Modify drawings or update flash applications at run time

I am writing a Flask application that supports plugin architecture. Each plugin lives in a separate folder and is a module that has at least one class that subclasses the Plugin class. For security reasons, I do not want to download all plugins when the flash drive application is initially launched. Instead, the user can enable plugins from the flash application. As soon as he does this, we save the note in the database, which adds a whitelist to the application for download. However, we should still remember which plugins are disabled and the proven views for these plugins. I do this by creating a dummy class for plugins that are not included that do not load any custom code.

Each plugin has its own Blueprint. We register this when loading plugins. Blueprint defines the route to enable the plugin. It all looks like this:

 for plugin_name in os.listdir(plugin_dir): plugin_path = os.path.join(plugin_paths, plugin_name) module_name = "plugins.{}.__init__".format(plugin_name) plugin_enabled = ask_db_whether_plugin_is_enabled(plugin_name) if os.path.isdir(plugin_path) and plugin_enabled: module = __import__(module_name) for plugin in load_plugins_from_module(module): app.register_blueprint(plugin.blueprint, url_prefix='/plugins') else: PluginCls = type(identifier, (Plugin, ), {}) disabled_plugin = PluginCls() app.register_blueprint(disabled_plugin.blueprint, url_prefix='/plugins') 

load_plugins_from_module as follows:

 def load_plugins_from_module(module): def is_plugin(c): return inspect.isclass(c) and \ issubclass(c, Plugin) and \ c != Plugin for name, objects in inspect.getmembers(module, lambda c: inspect.ismodule(c)): for name, PluginCls in inspect.getmembers(objects, is_plugin): plugin = PluginCls() yield plugin 

Now the question is: when I change the plugin to on, I basically want to restart

 module = __import__(module_name) for plugin in load_plugins_from_module(module): app.register_blueprint(plugin.blueprint, url_prefix='/plugins') 

for this plug-in module so that it becomes active and registers all routes that were defined in the subclass plug-in. This will increase the AssertionError because I cannot change the drawings at runtime. What would be good for this? Can I reload the application from the application? Can I modify an existing project at runtime?

Thank you for your help!

+4
source share
3 answers

I'm not sure you will need to complicate this.

You can simply set configuration options for the plugins you want to enable. And you can register your drawings based on this configuration in your "Start_app ()" method.

You can also dynamically configure configuration options that inherit from specific folders / files, for example, to make them more dynamic.

Plugins are usually developers, so the configuration option is not burdensome unless you are trying to create something where every casual user can modify your website - which can pose huge security issues.

For security reasons, I don’t want to load all plugins when the flash application is initially launched.

I am not sure about that. Preventing the user from manually launching the plugins can be more dangerous for security (therefore, if the user can secretly download the code, and then can now enable them).

You can create a CMS with the plugin turned on, for example WordPress, simply without routing the plugin URL until the user clicks on the “activate plugin” button

+1
source

I'm not sure how to change the application object at runtime, but there is an alternative way in which you can try what you need.

  • Create a table called "Plugins" and it will have two columns:

     Field 1: Blueprint name Field 2: isActive 
  • Provide an interface to users where they can “activate” the desired plugin. You can control access to it as needed. So you can write a view, for example:

     @login_required def activate_plugin(name): #whatever code is needed to activate the flag in Plugins table. 
  • Drawings may have a before_request () method that you can use to check if a plugin / plan is enabled. if not included, return 404 or any other code.

     @blueprintname.before_request def check_if_active(blueprintname): is_active = some_function_that_checks_plugin_active_flag() if is_active: #Normal processing else: abort(404) 
  • Thus, each drawing request first checks to see if it is active before returning a response.

+1
source

You can recreate the Flask application object at runtime using the Application Dispatching pattern.

Here's the gist of the question of how to restart the Flask application when invoking a special endpoint, you can, of course, adapt it for reading from the database:

https://gist.github.com/nguyenkims/ff0c0c52b6a15ddd16832c562f2cae1d

0
source

All Articles