I'm writing a webapp in Flask. Within one of my routes, I have a function that listens to an API and waits for a payment to be registered. The function is called confirm()
. I pass it in the render_template
as confirm=confirm
and I call it on the page using Jinja2: {{ confirm(cost) }}
I've realised that the function needs to be called asynchronously because otherwise the page doesn't load until the payment is made. However, I'm getting the titular error that the function needs to be awaited. Having read around, I've tried changing the route to async def qr()
but Flask won't load it so I'm not sure how await
should be used in this case.
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
To be able to use Awaitable
objects within jinja2 templates, the environment
must be created with the enable_async
option.
Ref: https://jinja.palletsprojects.com/en/2.11.x/api/#async-support
To do this from flask you need to set it via jinja_options
before running the app. Like this:
from flask import Flask
app = Flask(__name__)
app.jinja_options['enable_async'] = True
Now there's only one issue remaining. Based on the AsyncSupport
documentation of jinja2:
asyncio.get_event_loop()
must return an event loop. Since flask creates a new Thread for each request there will be no evet_loop for jinja. So something like this must be done to get it working:
@app.route('/')
def example():
# ...
asyncio.set_event_loop(asyncio.new_event_loop())
return render_template('index.html', confirm=confirm)
Be cautious with how you'd provide the event loop. I don't think this a production-ready approach. This is just a proof of concept to demonstrate how it should work. I think the "best practices to provide event_loop for flask threads" is a whole another question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With