对比 Flask FastAPI - 一款新型的 Python Web 框架

近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能 , 基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI。然而不断的 google 过程中偶然间发现了 FastAPI 这么一款集成了 Swagger UI 的更新的 Python Web 框架 。起初想要在标题中表达的意思大概是 Flask + Swagger = FastAPI, 后来发现 FastAPI 的闪亮点不仅如此 , 顺便找了些 Flask 与 FastAPI 对比的文章来 , 在文后附有链接 。
本文不对 Flask 与 FastAPI 的各个方面对进行对比 , 本人兴趣依然还在 FastAPI 的 Swagger UI 功能 , 以及与 Flask 的 Blueprint 类似的特性 。如果要拿 Flask 与 FastAPI 比较的话 , 应该用 Flask 2.x, 因为它开始支持类似 @App.get 的装饰器 , 并引入了 async 路由函数 。
Flask 是在 2010 年发布的 , 它构建于 WSGI(Python Web Server Gateway Interface) 之上的 , 产品环境中运行需与 uWSGI, Gunicorn 搭配 , 或用 mod_wsgi 模块与 Apache 集成 。因发布较早 , 所以目前应该有较多的使用者 。Flask 2.0 需要 Python 3.6+ 的支持 , 如果支持 async , 需 Python 3.7+
FastAPI 发布于 2018 年 , 构建于 ASGI(Asynchronous Server Gateway Interface) 之上 , 在 IO 密集型的应用中有更优越的性能 。生成环境中配合 ASGI 服务器 , 如 Uvicorn 或 Hypercorn . FastAPI 最为亮丽的特性是集成了 Swagger UI -- 外加一个福利 ReDoc。FastAPI 需 Python 3.6+ 版本 。
毕竟是在开始学一个新的框架 , 还是从它的基本用法开始 , 途中会穿插与 Flask 的对比 。
FastAPI 的基本用法安装:
$ pip install fastapi$ pip install "uvicorn[standard]" 当前安装的 fastapi 版本为 0.70.1, uvicorn 版本为 0.16.0 。开始第一个例子 , 摘自官方
创建一个 main.py 文件 , 内容为
from typing import Optionalfrom fastapi import FastAPIapp = FastAPI()@app.get("/")def read_root():return {"Hello": "World"}@app.get("/items/{item_id}")def read_item(item_id: int, q: Optional[str] = None):return {"item_id": item_id, "q": q} from typing import Optional
from fastapi import FastAPI
app = FastAPI ( )
@ app . get ( "/" )
def read_root ( ) :
return { "Hello" : "World" }
@ app . get ( "/items/{item_id}" )
def read_item ( item_id : int , q : Optional [ str ] = None ) :
return { "item_id" : item_id , "q" : q }
注:以上两个函数前面可以加上 async 关键字
启动服务 , 用命令
$uvicorn main:app --reloadINFO: Will watch for changes in these directories: ['/Users/yanbin/demo/first-fastapi']INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)INFO: Started reloader process [81730] using watchgodINFO: Started server process [81732]INFO: Waiting for application startup.INFO: Application startup complete.注: uvicorn --help 列出详细帮助 , 如启动多少个 worker, 绑定网络接口和端口号, 配置 SSL 证书等 。
访问服务
$ curl -i http://localhost:8000/HTTP/1.1 200 OKdate: Mon, 20 Dec 2021 06:51:24 GMTserver: uvicorncontent-length: 17content-type: application/json{"Hello":"World"} 另一个服务就是
http://localhost:8000/items/100?q=somequery
与 Flask 的对比

  1. Flask 对返回的 dict 类型会自动应用 jsonify(), 并且响应的 Content-Type 为 application/json; 如果返回的是字符串 , 响应 Content-Type 为 text/html, 除非显式的调用 jsonify() 函数 。FastAPI 都会生成 application/json 的响应 , Flask 对返回的 tuple 类型还有更多的约定, 见 Flask About Response
  2. Flask 对路径中的参数可选择中 @app.xxx 装饰器中声明类型 , 如 app.get("/items/<int:item_id>"
  3. Flask 访问查询参数用 request.args.get('key') 的方式
  4. 启动服务的方式不同 , 下面单独列出
回顾一个 Flask 启动服务的方式有
$ export FLASK_APP=hello$ flask run 如果程序文件名为 app.py 或 wsgi.py 的话 , 可以省略 FLASK_APP 环境变量 , 直接执行 flask run 就行 。另一种方式就是在代码中加上 main 入口
if __name__ == "__main__":app.run() if __name__ == "__main__" :


推荐阅读