And*_*rew 5 python jinja2 flask async-await
我正在用 Flask 编写一个 webapp。在我的一条路线中,我有一个函数可以侦听 API 并等待注册付款。该函数被调用confirm()。我将它传入render_templateasconfirm=confirm并使用 Jinja2 在页面上调用它:{{ confirm(cost) }}
我已经意识到需要异步调用该函数,否则页面在付款之前不会加载。但是,我收到了需要等待该函数的名义错误。阅读后,我尝试将路线更改为,async def qr()但 Flask 不会加载它,所以我不确定await在这种情况下应该如何使用。
async def confirm(cost):
json = { "action": "account_history", "account": app.config['NANO'], "count": 5, "raw": False, "reverse": False }
now = datetime.now()
delta = timedelta(seconds=60)
while datetime.now() < now+delta:
test = requests.post("https://nanoverse.io/api/node",json=json).json()
for item in test["history"]:
if item["amount"] == cost:
flash("Payment Received!")
break
else:
continue
break
Run Code Online (Sandbox Code Playgroud)
为了能够Awaitable在 jinja2 模板中使用对象,environment必须使用该选项创建enable_async。参考: https: //jinja.palletsprojects.com/en/2.11.x/api/#async-support
jinja_options要从 Flask 执行此操作,您需要在运行应用程序之前进行设置。像这样:
from flask import Flask
app = Flask(__name__)
app.jinja_options['enable_async'] = True
Run Code Online (Sandbox Code Playgroud)
现在只剩下一个问题了。基于AsyncSupportjinja2的文档:
asyncio.get_event_loop()必须返回一个事件循环。由于 Flask 为每个请求创建一个新线程,因此 jinja 不会有 evet_loop 。因此,必须执行类似的操作才能使其正常工作:
@app.route('/')
def example():
# ...
asyncio.set_event_loop(asyncio.new_event_loop())
return render_template('index.html', confirm=confirm)
Run Code Online (Sandbox Code Playgroud)
请谨慎对待如何提供事件循环。我不认为这是一种生产就绪的方法。这只是一个概念证明,用于演示它应该如何工作。我认为“为烧瓶线程提供 event_loop 的最佳实践”是另一个问题。