我想用燒瓶來運行一些功能。假設你有一個myapp.py用函式呼叫的檔案run
def run():
return 'special routed hello world'
和這個主燒瓶檔案,像這樣
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'hello world'
@app.route('/<myapp>')
def open_app(myapp):
from myapp import run
return run()
很明顯這不起作用,但是當flask已經在運行時,我如何動態呼叫這些運行函式。這甚至可能嗎?換句話說:當有人打開例如.../foobar 時,開始呼叫open_app帶有引數的函式foobar。在該函式中,從檔案foobar.py(假設檔案存在)匯入函式run,運行它并回傳該函式的結果。
uj5u.com熱心網友回復:
實際上,可以使用importlib,尤其是import_module與 結合使用getattr來動態呼叫模塊的功能。我也有安全問題。
以下兩個示例展示了一種簡單的 RPC 實作。
第一個示例使用模塊字典。如果具有該名稱的模塊可用,則呼叫 run 函式。它允許強限制??。優化當然是可能的,而且可能是必要的。
第二個例子展示了在不同模塊中使用引數呼叫不同函式的可能性。盡管如此,與之前的版本一樣,所有模塊都在一個名為“actions”的包中,以確保可以限制呼叫。我還認為帶有 POST 的變體比使用變數規則更適合此目的。
請記住,這些是強烈的簡化。JSON-RPC 等協議肯定會在實作程序中起到指導作用。
from flask import Flask
from flask import jsonify, request, jsonify
from importlib import import_module
from actions import *
app = Flask(__name__)
app.secret_key = 'your secret here'
@app.route('/exec/<string:action>', methods=['POST'])
def exec(action):
result = cmddict[action].run()
return jsonify(result=result)
@app.route('/call', methods=['POST'])
def call():
data = request.get_json()
module = data.get('module')
method = data.get('method')
params = data.get('params')
try:
# import module by name
m = import_module(f'actions.{module}', __name__)
# get function by name
f = getattr(m, method)
# call function with params
result = f(**params) if isinstance(params, dict) else f(*params)
return jsonify(result=result, error=None)
except Exception as err:
return jsonify(result=None, error=f'{err}')
# ./actions/__init__py
__all__ = ['demo']
from importlib import import_module
cmddict = {}
for _ in __all__:
cmddict[_] = import_module(f'actions.{_}', __name__)
__all__.append('cmddict')
# ./actions/demo.py
def run():
return f'hello world'
def func(*args, **kwargs):
print('func', args, kwargs)
``
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/334869.html
下一篇:werkzeug.routing.BuildError:無法為值為['next']的端點“login”構建url。您的意思是“core.login”嗎?
