在进行相关搜索时,我发现还有很多人在推荐Flask作为Python的web框架。然而,我觉得“Flask已经有点过时了,而FastAPI才是真正的未来”。所以我写了这篇文章。欢迎大家来讨论并提出不同的看法。
Flask 在许多 Python 开发者心中占有重要位置。我敢打赌你很可能用过 Flask,但你可能还没试过 FastAPI。
下面是给你看两个例子:这里有两例子,
我们现在来看看官方的Python 开发者调查报告 中 web 框架的比例变化:
很明显,在2019年,FastAPI甚至还没有被列入选择范围,而到了2023年,其市场份额已达25%。(注:目前我们只掌握了2023年的数据。)
需要注意的是,这些数据包括了现有的系统,因此Django和Flask的比例不会突然下降得太快。然而,趋势已经很明显了。
我们知道 Web 框架领域非常繁荣,每年都会冒出新的框架。其中大部分框架都很快消亡,但有些却能经久不衰。FastAPI 诞生于 2018 年末,到了 2019 年末才开始崭露头角。那么,它又是如何在短短五年内就赶超了 2010 年末诞生的 Flask 的,成为广受欢迎的框架呢?接下来,我们将沿着时间线回顾 Python Web 框架及相关解决方案的发展历程,以便更好地理解这些变化。
FastAPI 的作者是一位极其关注 Python 生态系统发展的开发者。第二个扩展阅读链接是作者撰写的文章“替代方案、灵感和比较”(https://fastapi.tiangolo.com/alternatives/),详细介绍了 FastAPI 从各种库中获得的灵感和参考。该文章的历史部分也提到了这篇文章。建议阅读原文,因为它详细解释了 FastAPI 出现的原因以及作者的一些设计思路。
Flask 是一个“轻量级框架”,与 Django 完全不同。它只保留了核心功能,并将其他功能拆分到多个库(例如 Jinja2、Werkzeug 等)。这给开发者提供了很大的自由度,使他们能够轻松地为相关功能编写第三方插件。如蓝图、上下文和用于表示路由、信号等的装饰器,这些内部设计在当时非常先进。再加上详尽的文档,它对新手非常友好。
得益于其简洁性,Flask非常适合构建API。然而,由于Flask本身并没有提供任何内置功能,我们需要专门的REST框架。因此,这些框架如flask-restful、Flask-RESTPlus和flask-api相继出现。此外,在REST服务中,还有数据验证、解析和规范的需求,这催生了Marshmallow、Webargs和APISpec,直到Flask-apispec的出现。在发展的过程中,然而,一直没有出现一个类似DRF的Flask REST框架。
在这个阶段,Flask的不足逐渐暴露了。
Flask 的原有优势在于其灵活性和简约性,但这同时也意味着需要开发大量的内部插件。要么需要一家大公司投入资源来开发和维护,要么需要一个非常有能力的个人开发者。否则,插件难以达到生产标准,从而导致 Flask 的第三方插件质量参差不齐,很难保证长期维护。正如前面提到的,许多这样的库已经不再维护。
所以,即使在今天,如果你想用 Flask 构建一个 API 服务,你仍然需要拼凑各种不同的组件。对于一些没有及时更新的组件,你可能需要自己解决相关问题。老手或许能够应付,但对于初学者来说,这可能显得相当棘手,尤其是当他们想要应用最新的实践和技术时。
从 Python 3.5 开始,asyncio 成为了未来的发展方向。因此,一些原生支持 aiohttp、Starlette 和 sanic 这样的框架也随之出现。
这时,Flask不太愿意适应变化。社区在支持asyncio方面进展缓慢,而Flask的原作者已经转而使用Rust,项目现在由两位维护者负责(现在只剩下一位了)。
这些构建 API 服务的项目,比如 apistar 和 molten,都给 FastAPI 的诞生提供了设计灵感。
然后,FastAPI 应运而生了。作者原本是在寻找一个理想的解决方案,但这些情况都有各自的问题和局限性。因此,作者就创建了这个新框架 FastAPI。
这是文章的核心部分。以下就是FastAPI能够取代Flask的几个重要原因。
在开发 API 的过程中,数据格式的验证、解析和序列化是常见的任务。多年来,各种解决方案层出不穷,目前,Pydantic 已成为首选工具。
从 fastapi 导入 FastAPI 作为 FastAPI 从 pydantic 导入 BaseModel 作为 BaseModel
class Item(BaseModel): # 定义一个模型类 name: str # 名称 description: str | None = None # 描述 price: float # 价格 tax: float | None = None # 税 app = FastAPI() # 创建一个FastAPI应用 @app.post("/items/") # 定义一个创建项目的POST请求处理器 async def create_item(item: Item): # 创建项目的异步函数 return item # 返回项目
乍一看,这段代码可能看起来像是 ORM 或数据类的写法,但实际上它使用了 Python 本机的类型提示语法来注解字段类型。如前所述,在前面提到的例子中,/items/
请求中的 Item
的定义已经清晰地定义了,并且每个字段的值类型都明确标注。与使用模式描述或甚至硬编码的老方法相比,这种方法更加简洁,更符合 Python 的编程习惯,并且具有更好的集成开发环境支持。
目前,Pydantic 在用户数据验证领域占据主导地位。由于 FastAPI 内置了 Pydantic,验证过程变得更加简单,错误也减少了。这就是为什么 FastAPI 官网提到,这种方案可以减少开发者多达 40% 的错误。尤其是对于像 Python 这样的动态语言,如果你不使用 mypy 进行类型检查,使用 Pydantic 就变得非常必要了。
此外,得益于Pydantic的集成,将ORM(如SQLAlchemy)添加进项目变得非常简单。由于数据验证已经完成,从请求中获取的对象可以直接传递给数据库。反过来,从数据库中检索出的对象可以直接返回。
相比之下,Flask 略显不足。
使用 Flask 时,代码执行是单线程且同步的。这意味着请求必须一个接一个地处理,而其他请求则会浪费时间等待 I/O 操作在前一个请求完成之前。相比之下,Asyncio 是更优的选择。它可以将 I/O 操作异步化,让你可以在任务未完成时就能获取结果,然后继续处理其他任务。
FastAPI 原生支持并发和异步编程。只要代码正确编写,即可实现高效运行。因此,它在目前的 Python 框架中最快。其效率可媲美 NodeJS 或 Go。当速度和性能是关键时,FastAPI 无疑是最佳之选。
让我们先提到 WSGI。它的全称是“Python Web 服务器网关接口”(WSGI),可以在“PEP 3333”中找到详细信息 (https://peps.python.org/pep-3333/)。它是一个专门用于网络应用与服务器交互的 Python 标准。如果你之前接触过 PHP 或 Ruby,理解起来会更容易。Flask 依赖于 Werkzeug,一个 WSGI 工具包,因此,Flask 支持旧的 WSGI 标准,而不支持 ASGI。
WSGI 的问题是它不能利用异步性来提升性能和效率。因此,Django Channels 推出了 ASGI。它的全称是“异步服务器网关接口”,这是一个几乎完全重新设计的迭代标准。它提供异步服务器和应用程序接口,并支持 HTTP、HTTP/2 和 WebSocket。与 WSGI 不同,ASGI 允许每个应用程序拥有多个异步事件,支持更灵活的应用程序处理方式。此外,ASGI 不仅支持同步应用程序,也支持异步应用程序。您可以将旧的同步 WSGI 网络应用程序迁移到 ASGI,或者使用 ASGI 构建新的异步网络应用程序,轻松享受异步带来的性能提升。
在得出结论前,我们再解释五个术语。
在过去,WSGI的生产环境解决方案通常是Nginx + Gunicorn + Flask(或Django),而如今,这一解决方案变成了Nginx + Uvicorn + FastAPI,用于ASGI。
还有一件事。从FastAPI的名字和介绍来看,很明显它是为构建API服务而设计的。事实上,它的核心代码确实也是如此。可以说,它不是一个传统的、完全自实现的框架,而更像是一个结合了多种框架优势的框架。从一个空壳开始,它组装了必要的和合适的组件,使其更加灵活。例如,它没有内置模板引擎。如果你真的需要用它来构建需要模板渲染的web应用,你可以选择和组合你需要的模板引擎。当然,你也可以使用Starlette自带的Jinja2(Flask中也有内置)。
(注:此处调整为“为什么大家说Flask不行了?”更符合口语化表达,同时考虑到技术讨论中保持“Flask”原文的准确性,最终选择更通用的表达方式。)
为什么大家说Flask不行了?
前面提到的 FastAPI 的优势还不足以断定 Flask 已经过时。那么,我为何持有这种观点呢?主要归因于开发者和用户的受欢迎程度。
我可以想到的几个指标如下:这里的受欢迎程度相当主观。
依我看来,所有这些情况都表明 Flask 的鼎盛时期已经过去,而 FastAPI 正在兴起,正在成为新星。
最后但并非最不重要的是,我推荐一个部署 Flask/FastAPI 的理想平台:Leapcell。
Leapcell(访问 https://leapcell.io/)是专为现代分布式应用设计的云计算平台。其按需计费模式确保用户无需支付闲置资源费用,用户只需按实际使用付费。
Leapcell在WSGI/ASGI应用中的独特优点有:
更多详情请查看文档!
Leapcell 的推特:https://x.com/LeapcellHQ