vbl.使用 asyncawait

Changelog

在 2.0 版本加入.

路由、错误处理程序、请求前、请求后和拆卸功能都可以是协程函数(如果将FlaskTM与一起安装 async 额外的 (pip install flask[async] )。这允许使用定义视图 async def 和使用 await

@app.route("/get-data")
async def get_data():
    data = await async_db_query(...)
    return jsonify(data)

可插拔的基于类的视图还支持作为协程实现的处理程序。这适用于 dispatch_request() 方法继承的视图中的 flask.views.View 类以及从 flask.views.MethodView 班级。

vbl.使用 async 在Python3.8上的Windows上

Python3.8有一个与Windows上的asyncio相关的错误。如果你遇到类似的情况 ValueError: set_wakeup_fd only works in main thread ,请升级到Python3.9。

vbl.使用 async 带小绿灯

当使用GEVENT或Eventlet来服务应用程序或修补运行时时,需要greenlet>=1.0。使用PyPy时,需要使用>=7.3.7的PyPy。

性能

异步函数需要事件循环才能运行。作为一个WSGI应用程序,FASK使用一个工作进程来处理一个请求/响应周期。当一个请求进入一个异步视图时,Flask会在一个线程中启动一个事件循环,在那里运行view函数,然后返回结果。

每个请求仍然占用一个工作进程,即使是异步视图也是如此。优点是您可以在一个视图中运行异步代码,例如进行多个并发数据库查询、对外部API的HTTP请求等。但是,您的应用程序一次可以处理的请求数量将保持不变。

Async is not inherently faster than sync code. 异步在执行并发IO受限任务时很有用,但可能不会改善CPU受限任务。传统的Flask视图仍然适用于大多数用例,但FlaskAsync的支持使得编写和使用代码成为可能,这在以前是不可能的。

后台任务

异步函数将在事件循环中运行,直到它们完成,在此阶段事件循环将停止。这意味着在异步功能完成时尚未完成的任何其他衍生任务都将被取消。因此,您无法派生后台任务,例如通过 asyncio.create_task

如果您希望使用后台任务,最好使用任务队列来触发后台工作,而不是在视图函数中生成任务。考虑到这一点,您可以通过使用ASGI服务器为Flask提供服务并使用asgiref WsgiToAsgi适配器来生成异步任务,如中所述 ASGI 。这在适配器创建持续运行的事件循环时起作用。

何时改用夸特

由于FASK的实现方式,其对异步的支持不如异步优先框架的性能好。如果您有一个主要的异步代码库,那么考虑一下 Quart 。Quart是Flask的重新实现,基于 ASGI 标准而不是WSGI。这允许它处理许多并发请求、长时间运行的请求和WebSocket,而不需要多个工作进程或线程。

还可以通过运行带有GEvent或Eventlet的Flask来获得异步请求处理的许多好处。这些库修补低级的Python函数来实现这一点,而 async / await ASGI使用标准的、现代的Python功能。您是否应该使用FlaskTM、Quart或其他软件,最终取决于您对项目的具体需求的了解。

延拓

早于FlASK的异步支持的FASK扩展不会期望获得异步视图。如果它们提供装饰器来向视图添加功能,则这些功能可能不会与异步视图一起工作,因为它们不会等待该功能或无法等待。它们提供的其他函数也将无法等待,如果在异步视图中调用,则可能会被阻塞。

扩展编写者可以通过使用 flask.Flask.ensure_sync() 方法。例如,如果扩展提供了视图函数修饰符Add ensure_sync 在调用修饰函数之前,

def extension(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        ...  # Extension logic
        return current_app.ensure_sync(func)(*args, **kwargs)

    return wrapper

查看你想要使用的扩展的更改日志,看看他们是否实现了异步支持,或者向他们提出功能请求或公关。

其他事件循环

目前,烧瓶只支持 asyncio 。有可能覆盖 flask.Flask.ensure_sync() 若要更改包装异步函数以使用不同库的方式,请执行以下操作。