RuntimeWarning:从未等待协程'qr。<locals> .confirm'

时间:2020-08-14 17:16:46

标签: python flask async-await jinja2

我正在用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

1 个答案:

答案 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的最佳实践”完全是另一个问题。