プラグイン アーキテクチャをサポートする Flask アプリを作成しています。各プラグインは個別のフォルダーに存在し、クラスをサブクラス化する少なくとも 1 つのクラスを持つモジュールですPlugin
。セキュリティ上の理由から、flask アプリを最初に実行するときにすべてのプラグインをロードしたくありません。代わりに、ユーザーはフラスコ アプリ内からプラグインを有効にすることができます。彼がそれを行うと、アプリをロードするためのホワイトリストを作成するメモがデータベースに保存されます。ただし、無効になっているプラグインと、これらのプラグインの証明されたビューを覚えておく必要があります。カスタム コードを読み込まない、有効になっていないプラグイン用のダミー クラスを作成することで、これを行います。
各プラグインには独自のブループリントが付属しています。プラグインをロードするときにそれを登録します。ブループリントは、プラグインを有効にするためのルートも定義します。全体は次のようになります。
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
次のようになります。
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
問題は次のとおりです。プラグインを有効に変更すると、基本的に再実行したい
module = __import__(module_name)
for plugin in load_plugins_from_module(module):
app.register_blueprint(plugin.blueprint, url_prefix='/plugins')
そのプラグインのモジュールがアクティブになり、サブクラス化されたプラグインで定義されているすべてのルートも登録するようにします。AssertionError
実行時にブループリントを変更できないため、これによりエラーが発生します。そのための良い回避策は何ですか?アプリ内からアプリをリロードできますか? 実行時に既存のブループリントを変更できますか?
ご協力いただきありがとうございます!