Shouldn’t any route that interacts with the file system (including anything that calls render_template) be a sync (non-async) route? Doesn’t blocking io completely destroy any performance gain from async? If so, why do the examples in the docs show this pattern?
IO is blocking within that request. There's no way around that. The difference between sync and async is that with the latter, the event loop from the blocking request is freed up to handle other requests, which is where the performance gain is. If there's only a single request, then sync and async are going to look largely the same from the outside. However if there's thousands of requests, async is going to do much better.
yup! I think of it like cooking. If you're only cooking one thing, sync & async look the same. But if you're cooking several things, you can switch between dishes as needed (asynchronous) instead of cooking each dish one at a time (synchronous)
render and serve HTML templates,
write (RESTful) JSON APIs,
serve WebSockets,
stream request and response data,
do pretty much anything over the HTTP or WebSocket protocols.
I had a project which was making API calls that could take 90 seconds to generate a response from external services. My flask API was obviously blocked and when I started letting other users on I fixed the bottleneck by updating (I think) 3-5 lines of code and adding an asyncio loop.
From my limited use it does seem like a drop in replacement for 'async flask'
twisted is pretty handy for WSGI apps. You don't need to use twisted's other features (async/event framework) to just setup a reactor and serve flask, so just add twisted to your requirements.txt and then make the entry point `python3 my_server_bootstrap.py` for the server. If you want features in front of it from nginx/haproxy I would use those as a second layer with a docker compose file or something.