我正在用Flask编写一个Web应用程序。在我的一条路线中,我有一个侦听API并等待付款被注册的函数。该函数称为confirm()
。我以render_template
的形式在confirm=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
答案 0 :(得分:2)
要在jinja2模板中使用Awaitable
对象,必须使用environment
选项创建enable_async
。
参考:https://jinja.palletsprojects.com/en/2.11.x/api/#async-support
要从烧瓶中执行此操作,您需要在运行应用之前通过jinja_options
进行设置。像这样:
from flask import Flask
app = Flask(__name__)
app.jinja_options['enable_async'] = True
现在只剩下一个问题了。基于jinja2的AsyncSupport
文档:
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)
请谨慎提供事件循环。我认为这不是生产就绪的方法。这只是概念证明,以证明其应如何工作。我认为“为烧瓶线程提供event_loop的最佳实践”完全是另一个问题。