2025-04-11 03:04:22 +00:00
< ! DOCTYPE html >
< html lang = "en" data-content_root = "./" >
< head >
< meta charset = "utf-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title > Using async and await & # 8212 ; Flask Documentation ( 3 . 2 . x ) < / title >
< link rel = "stylesheet" type = "text/css" href = "_static/pygments.css?v=6625fa76" / >
< link rel = "stylesheet" type = "text/css" href = "_static/flask.css?v=b87c8d14" / >
< script src = "_static/documentation_options.js?v=56528222" > < / script >
< script src = "_static/doctools.js?v=9bcbadda" > < / script >
< script src = "_static/sphinx_highlight.js?v=dc90522c" > < / script >
< script data-project = "flask" data-version = "3.2.x" src = "_static/describe_version.js?v=fa7f30d0" > < / script >
< link rel = "icon" href = "_static/shortcut-icon.png" / >
< link rel = "index" title = "Index" href = "genindex.html" / >
< link rel = "search" title = "Search" href = "search.html" / >
< link rel = "next" title = "API" href = "api.html" / >
< link rel = "prev" title = "Apache httpd" href = "deploying/apache-httpd.html" / >
< / head > < body >
< div class = "related" role = "navigation" aria-label = "Related" >
< h3 > Navigation < / h3 >
< ul >
< li class = "right" style = "margin-right: 10px" >
< a href = "genindex.html" title = "General Index"
accesskey = "I" > index < / a > < / li >
< li class = "right" >
< a href = "py-modindex.html" title = "Python Module Index"
> modules < / a > | < / li >
< li class = "right" >
< a href = "api.html" title = "API"
accesskey = "N" > next < / a > | < / li >
< li class = "right" >
< a href = "deploying/apache-httpd.html" title = "Apache httpd"
accesskey = "P" > previous < / a > | < / li >
< li class = "nav-item nav-item-0" > < a href = "index.html" > Flask Documentation ( 3 . 2 . x ) < / a > & # 187 ; < / li >
< li class = "nav-item nav-item-this" > < a href = "" > Using < code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < / code > and < code class = "docutils literal notranslate" > < span class = "pre" > await < / span > < / code > < / a > < / li >
< / ul >
< / div >
< div class = "document" >
< div class = "documentwrapper" >
< div class = "bodywrapper" >
< div class = "body" role = "main" >
< section id = "using-async-and-await" >
< span id = "async-await" > < / span > < h1 > Using < code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < / code > and < code class = "docutils literal notranslate" > < span class = "pre" > await < / span > < / code > < a class = "headerlink" href = "#using-async-and-await" title = "Link to this heading" > ¶ < / a > < / h1 >
< details class = "changelog" >
< summary > Changelog < / summary > < div class = "versionadded" >
< p > < span class = "versionmodified added" > Added in version 2 . 0 . < / span > < / p >
< / div >
< / details > < p > Routes , error handlers , before request , after request , and teardown
functions can all be coroutine functions if Flask is installed with the
< code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < / code > extra ( < code class = "docutils literal notranslate" > < span class = "pre" > pip < / span > < span class = "pre" > install < / span > < span class = "pre" > flask [ async ] < / span > < / code > ) . This allows views to be
defined with < code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < span class = "pre" > def < / span > < / code > and use < code class = "docutils literal notranslate" > < span class = "pre" > await < / span > < / code > . < / p >
< div class = "highlight-python notranslate" > < div class = "highlight" > < pre > < span > < / span > < span class = "nd" > @ app < / span > < span class = "o" > . < / span > < span class = "n" > route < / span > < span class = "p" > ( < / span > < span class = "s2" > & quot ; / get-data & quot ; < / span > < span class = "p" > ) < / span >
< span class = "k" > async < / span > < span class = "k" > def < / span > < span class = "w" > < / span > < span class = "nf" > get_data < / span > < span class = "p" > ( ) : < / span >
< span class = "n" > data < / span > < span class = "o" > = < / span > < span class = "k" > await < / span > < span class = "n" > async_db_query < / span > < span class = "p" > ( < / span > < span class = "o" > . . . < / span > < span class = "p" > ) < / span >
< span class = "k" > return < / span > < span class = "n" > jsonify < / span > < span class = "p" > ( < / span > < span class = "n" > data < / span > < span class = "p" > ) < / span >
< / pre > < / div >
< / div >
< p > Pluggable class-based views also support handlers that are implemented as
coroutines . This applies to the < a class = "reference internal" href = "api.html#flask.views.View.dispatch_request" title = "flask.views.View.dispatch_request" > < code class = "xref py py-meth docutils literal notranslate" > < span class = "pre" > dispatch_request ( ) < / span > < / code > < / a >
method in views that inherit from the < a class = "reference internal" href = "api.html#flask.views.View" title = "flask.views.View" > < code class = "xref py py-class docutils literal notranslate" > < span class = "pre" > flask . views . View < / span > < / code > < / a > class , as
well as all the HTTP method handlers in views that inherit from the
< a class = "reference internal" href = "api.html#flask.views.MethodView" title = "flask.views.MethodView" > < code class = "xref py py-class docutils literal notranslate" > < span class = "pre" > flask . views . MethodView < / span > < / code > < / a > class . < / p >
< div class = "admonition-using-async-with-greenlet admonition" >
< p class = "admonition-title" > Using < code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < / code > with greenlet < / p >
< p > When using gevent or eventlet to serve an application or patch the
runtime , greenlet & gt ; = 1 . 0 is required . When using PyPy , PyPy & gt ; = 7 . 3 . 7 is
required . < / p >
< / div >
< section id = "performance" >
< h2 > Performance < a class = "headerlink" href = "#performance" title = "Link to this heading" > ¶ < / a > < / h2 >
< p > Async functions require an event loop to run . Flask , as a WSGI
application , uses one worker to handle one request / response cycle .
When a request comes in to an async view , Flask will start an event loop
in a thread , run the view function there , then return the result . < / p >
< p > Each request still ties up one worker , even for async views . The upside
is that you can run async code within a view , for example to make
multiple concurrent database queries , HTTP requests to an external API ,
etc . However , the number of requests your application can handle at one
time will remain the same . < / p >
< p > < strong > Async is not inherently faster than sync code . < / strong > Async is beneficial
when performing concurrent IO-bound tasks , but will probably not improve
CPU-bound tasks . Traditional Flask views will still be appropriate for
most use cases , but Flask ’ s async support enables writing and using
code that wasn ’ t possible natively before . < / p >
< / section >
< section id = "background-tasks" >
< h2 > Background tasks < a class = "headerlink" href = "#background-tasks" title = "Link to this heading" > ¶ < / a > < / h2 >
< p > Async functions will run in an event loop until they complete , at
which stage the event loop will stop . This means any additional
spawned tasks that haven ’ t completed when the async function completes
will be cancelled . Therefore you cannot spawn background tasks , for
example via < code class = "docutils literal notranslate" > < span class = "pre" > asyncio . create_task < / span > < / code > . < / p >
< p > If you wish to use background tasks it is best to use a task queue to
trigger background work , rather than spawn tasks in a view
function . With that in mind you can spawn asyncio tasks by serving
Flask with an ASGI server and utilising the asgiref WsgiToAsgi adapter
as described in < a class = "reference internal" href = "deploying/asgi.html" > < span class = "doc" > ASGI < / span > < / a > . This works as the adapter creates
an event loop that runs continually . < / p >
< / section >
< section id = "when-to-use-quart-instead" >
< h2 > When to use Quart instead < a class = "headerlink" href = "#when-to-use-quart-instead" title = "Link to this heading" > ¶ < / a > < / h2 >
< p > Flask ’ s async support is less performant than async-first frameworks due
to the way it is implemented . If you have a mainly async codebase it
would make sense to consider < a class = "reference external" href = "https://github.com/pallets/quart" > Quart < / a > . Quart is a reimplementation of
Flask based on the < a class = "reference external" href = "https://asgi.readthedocs.io/en/latest/" > ASGI < / a > standard instead of WSGI . This allows it to
handle many concurrent requests , long running requests , and websockets
without requiring multiple worker processes or threads . < / p >
< p > It has also already been possible to run Flask with Gevent or Eventlet
to get many of the benefits of async request handling . These libraries
patch low-level Python functions to accomplish this , whereas < code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < / code > /
< code class = "docutils literal notranslate" > < span class = "pre" > await < / span > < / code > and ASGI use standard , modern Python capabilities . Deciding
whether you should use Flask , Quart , or something else is ultimately up
to understanding the specific needs of your project . < / p >
< / section >
< section id = "extensions" >
< h2 > Extensions < a class = "headerlink" href = "#extensions" title = "Link to this heading" > ¶ < / a > < / h2 >
< p > Flask extensions predating Flask ’ s async support do not expect async views .
If they provide decorators to add functionality to views , those will probably
not work with async views because they will not await the function or be
awaitable . Other functions they provide will not be awaitable either and
will probably be blocking if called within an async view . < / p >
< p > Extension authors can support async functions by utilising the
< a class = "reference internal" href = "api.html#flask.Flask.ensure_sync" title = "flask.Flask.ensure_sync" > < code class = "xref py py-meth docutils literal notranslate" > < span class = "pre" > flask . Flask . ensure_sync ( ) < / span > < / code > < / a > method . For example , if the extension
provides a view function decorator add < code class = "docutils literal notranslate" > < span class = "pre" > ensure_sync < / span > < / code > before calling
the decorated function , < / p >
< div class = "highlight-python notranslate" > < div class = "highlight" > < pre > < span > < / span > < span class = "k" > def < / span > < span class = "w" > < / span > < span class = "nf" > extension < / span > < span class = "p" > ( < / span > < span class = "n" > func < / span > < span class = "p" > ) : < / span >
< span class = "nd" > @ wraps < / span > < span class = "p" > ( < / span > < span class = "n" > func < / span > < span class = "p" > ) < / span >
< span class = "k" > def < / span > < span class = "w" > < / span > < span class = "nf" > wrapper < / span > < span class = "p" > ( < / span > < span class = "o" > * < / span > < span class = "n" > args < / span > < span class = "p" > , < / span > < span class = "o" > * * < / span > < span class = "n" > kwargs < / span > < span class = "p" > ) : < / span >
< span class = "o" > . . . < / span > < span class = "c1" > # Extension logic < / span >
< span class = "k" > return < / span > < span class = "n" > current_app < / span > < span class = "o" > . < / span > < span class = "n" > ensure_sync < / span > < span class = "p" > ( < / span > < span class = "n" > func < / span > < span class = "p" > ) ( < / span > < span class = "o" > * < / span > < span class = "n" > args < / span > < span class = "p" > , < / span > < span class = "o" > * * < / span > < span class = "n" > kwargs < / span > < span class = "p" > ) < / span >
< span class = "k" > return < / span > < span class = "n" > wrapper < / span >
< / pre > < / div >
< / div >
< p > Check the changelog of the extension you want to use to see if they ’ ve
implemented async support , or make a feature request or PR to them . < / p >
< / section >
< section id = "other-event-loops" >
< h2 > Other event loops < a class = "headerlink" href = "#other-event-loops" title = "Link to this heading" > ¶ < / a > < / h2 >
< p > At the moment Flask only supports < a class = "reference external" href = "https://docs.python.org/3/library/asyncio.html#module-asyncio" title = "(in Python v3.13)" > < code class = "xref py py-mod docutils literal notranslate" > < span class = "pre" > asyncio < / span > < / code > < / a > . It ’ s possible to
override < a class = "reference internal" href = "api.html#flask.Flask.ensure_sync" title = "flask.Flask.ensure_sync" > < code class = "xref py py-meth docutils literal notranslate" > < span class = "pre" > flask . Flask . ensure_sync ( ) < / span > < / code > < / a > to change how async functions
are wrapped to use a different library . < / p >
< / section >
< / section >
< div class = "clearer" > < / div >
< / div >
< / div >
< / div >
< span id = "sidebar-top" > < / span >
< div class = "sphinxsidebar" role = "navigation" aria-label = "Main" >
< div class = "sphinxsidebarwrapper" >
< p class = "logo" > < a href = "index.html" >
< img class = "logo" src = "_static/flask-vertical.png" alt = "Logo of Flask" / >
< / a > < / p >
< h3 > Contents < / h3 >
< ul >
< li > < a class = "reference internal" href = "#" > Using < code class = "docutils literal notranslate" > < span class = "pre" > async < / span > < / code > and < code class = "docutils literal notranslate" > < span class = "pre" > await < / span > < / code > < / a > < ul >
< li > < a class = "reference internal" href = "#performance" > Performance < / a > < / li >
< li > < a class = "reference internal" href = "#background-tasks" > Background tasks < / a > < / li >
< li > < a class = "reference internal" href = "#when-to-use-quart-instead" > When to use Quart instead < / a > < / li >
< li > < a class = "reference internal" href = "#extensions" > Extensions < / a > < / li >
< li > < a class = "reference internal" href = "#other-event-loops" > Other event loops < / a > < / li >
< / ul >
< / li >
< / ul >
< h3 > Navigation < / h3 >
< ul >
< li > < a href = "index.html" > Overview < / a >
< ul >
< li > Previous : < a href = "deploying/apache-httpd.html" title = "previous chapter" > Apache httpd < / a >
< li > Next : < a href = "api.html" title = "next chapter" > API < / a >
< / ul >
< / li >
< / ul >
< search id = "searchbox" style = "display: none" role = "search" >
< h3 id = "searchlabel" > Quick search < / h3 >
< div class = "searchformwrapper" >
< form class = "search" action = "search.html" method = "get" >
< input type = "text" name = "q" aria-labelledby = "searchlabel" autocomplete = "off" autocorrect = "off" autocapitalize = "off" spellcheck = "false" / >
< input type = "submit" value = "Go" / >
< / form >
< / div >
< / search >
< script > document . getElementById ( 'searchbox' ) . style . display = "block" < / script > < div id = "ethical-ad-placement" > < / div >
< / div >
< / div >
< div class = "clearer" > < / div >
< / div >
< div class = "footer" role = "contentinfo" >
& # 169 ; Copyright 2010 Pallets .
Created using < a href = "https://www.sphinx-doc.org/" > Sphinx < / a > 8 . 1 . 3 .
< / div >
< / body >
< / html >