FastAPI vs Flask: Why FastAPI Outperforms Flask for Modern APIs

This article compares FastAPI and Flask, highlighting FastAPI's speed, developer experience, and standards support, while providing practical migration guidance, code examples, configuration tips, async handling, dependency injection, testing, deployment, and documentation differences for Python web developers.

21CTO
21CTO
21CTO
FastAPI vs Flask: Why FastAPI Outperforms Flask for Modern APIs
笔者这几天上手体验 FastAPI,感受到这个框架易用和方便。之前也使用过 Python 中的 Django 和 Flask 作为项目的框架。Django 说实话上手也方便,但是学习起来有点重量级框架的感觉,FastAPI 带给我的直观体验还是很轻便的,本文翻译的这篇文章就会着重介绍 FastAPI 和 Flask 的区别。

Python 是最流行的编程语言之一。从脚本到 API 开发再到机器学习,Python 都有着它自己的足迹。因为 Python 注重开发者的体验和其所能提供的大量工具而大受欢迎。网络框架 Flask 就是这样一个工具,它在机器学习社区中很受欢迎。它也被广泛用于 API开发。但是有一个新的框架正在崛起:FastAPI。与 Flask 不同,FastAPI 是一个 ASGI(Asynchronous Server Gateway Interface 异步服务器网关接口)框架。与 Go 和 NodeJS 一样,FastAPI 是最快的基于 Python 的 Web 框架之一。

本文针对那些有兴趣从 Flask 转移到 FastAPI 的人,比较和对比了 Flask 和 FastAPI 的常见模式。

FastAPI vs Flask

FastAPI 的构建考虑了以下三个主要问题:

速度

开发者经验

开放标准

你可以把 FastAPI 看作是把 Starlette、Pydantic、OpenAPI 和 JSON Schema 粘合在一起的胶水。

本质上说,FastAPI 使用 Pydantic 进行数据验证,并使用 Starlette 作为工具,使其与 Flask 相比快得惊人,具有与 Node 或 Go 中的高速 Web APIs 相同的性能。

Starlette + Uvicorn 提供异步请求能力,这是 Flask 所缺乏的。

有了 Pydantic 以及类型提示,你就可以得到一个具有自动完成功能的良好的编辑体验。你还可以得到数据验证、序列化和反序列化(用于构建一个 API),以及自动化文档(通过 JSON Schema 和 OpenAPI )。

也就是说,Flask 的使用更为广泛,所以它经过了实战检验,并且有更大的社区支持它。由于这两个框架都是用来扩展的,Flask 显然是赢家,因为它有庞大的插件生态系统。

建议:

如果你对上述三个问题有共鸣,厌倦了 Flask 扩展时的大量选择,希望利用异步请求,或者只是想建立一个 RESTful API,请使用 FastAPI。

如果你对 FastAPI 的成熟度不满意,需要用服务器端模板构建一个全栈应用,或者离不开一些社区维护的 Flask 扩展,就可以使用 Flask。

开始

安装

与任何其他 Python 包一样,安装非常简单。

Flask

pip install flask # or poetry add flask
pipenv install flask
conda install flask

FastAPI

pip install fastapi uvicorn # or poetry add fastapi uvicorn
pipenv install fastapi uvicorn
conda install fastapi uvicorn -c conda-forge

与 Flask 不同,FastAPI 没有内置的开发服务器,需要使用 Uvicorn 或 Daphne 等 ASGI 服务器。

"Hello World" 应用

Flask

# flask_code.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
    return {"Hello": "World"}
if __name__ == "__main__":
    app.run()

FastAPI

# fastapi_code.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
    return {"Hello": "World"}
if __name__ == "__main__":
    uvicorn.run("fastapi_code:app")

参数 reload=True 可以传递给 uvicorn.run() 实现热重载。

配置

Flask 和 FastAPI 都提供了多种配置方式:

环境变量

配置文件

实例文件夹

类和继承

有关详细信息,请参阅各自的文档:

Flask: https://flask.palletsprojects.com/en/2.0.x/config/

FastAPI: https://fastapi.tiangolo.com/advanced/settings/

Flask

import os
from flask import Flask
class Config(object):
    MESSAGE = os.environ.get("MESSAGE")
app = Flask(__name__)
app.config.from_object(Config)
@app.route("/settings")
def get_settings():
    return {"message": app.config["MESSAGE"]}
if __name__ == "__main__":
    app.run()

运行前设置环境变量: export MESSAGE="hello, world" FastAPI

import uvicorn
from fastapi import FastAPI
from pydantic import BaseSettings
class Settings(BaseSettings):
    message: str
settings = Settings()
app = FastAPI()
@app.get("/settings")
def get_settings():
    return {"message": settings.message}
if __name__ == "__main__":
    uvicorn.run("fastapi_code:app")

同样在运行前设置环境变量。

路由、模板和视图

HTTP 方法

Flask

from flask import request
@app.route("/", methods=["GET", "POST"])
def home():
    if request.method == "POST":
        return {"Hello": "POST"}
    return {"Hello": "GET"}

FastAPI

@app.get("/")
def home():
    return {"Hello": "GET"}
@app.post("/")
def home_post():
    return {"Hello": "POST"}

URL 参数

Flask

@app.route("/employee/<int:id>")
def home(id):
    return {"id": id}

FastAPI

@app.get("/employee/{id}")
def home(id: int):
    return {"id": id}

查询参数

Flask

from flask import request
@app.route("/employee")
def home():
    department = request.args.get("department")
    return {"department": department}

FastAPI

@app.get("/employee")
def home(department: str):
    return {"department": department}

模板

Flask 使用 Jinja2,默认在 templates 文件夹中查找。

FastAPI 需要手动安装 Jinja2 并使用 Jinja2Templates

from fastapi import Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
def home(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

静态文件

Flask 默认从 static 文件夹提供。

FastAPI 需要挂载:

from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")

异步任务

Flask (自 2.0 起)支持 async/await ,但通常需要外部工具如 Celery。

FastAPI 原生支持 asyncio,只需在函数前加 async ,并可使用 BackgroundTasks

from fastapi import BackgroundTasks
def process_file(filename: str):
    pass
@app.post("/upload/{filename}")
async def upload_and_process(filename: str, background_tasks: BackgroundTasks):
    background_tasks.add_task(process_file, filename)
    return {"message": "processing file"}

依赖注入

Flask 没有内置 DI,需要第三方库。

FastAPI 使用 Depends 实现强大的依赖注入:

from databases import Database
from fastapi import Depends
from starlette.requests import Request
def get_db(request: Request):
    return request.app.state._db
@app.get("/data")
def get_data(db: Database = Depends(get_db)):
    return get_all_data(db)

数据校验

Flask 需要外部库(如 Flask‑Pydantic)进行验证。

FastAPI 内置 Pydantic 支持:

from pydantic import BaseModel
app = FastAPI()
class Request(BaseModel):
    username: str
    password: str
@app.post("/login")
async def login(req: Request):
    if req.username == "testdriven.io" and req.password == "testdriven.io":
        return {"message": "success"}
    return {"message": "Authentication Failed"}

中间件

Flask 使用 WSGI 中间件:

class middleware:
    def __init__(self, app):
        self.app = app
    def __call__(self, environ, start_response):
        start = time.time()
        response = self.app(environ, start_response)
        end = time.time() - start
        print(f"request processed in {end} s")
        return response
app.wsgi_app = middleware(app.wsgi_app)

FastAPI 使用装饰器:

from fastapi import Request
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    print(f"request processed in {process_time} s")
    return response

模块化

Flask 使用蓝图(Blueprint)实现模块化。

FastAPI 使用 APIRouter

from fastapi import APIRouter
product = APIRouter()
@product.get("/product1")
def get_product():
    ...
app.include_router(product)

自动文档

Flask 本身不生成 API 文档,需要扩展如 flask‑swagger。

FastAPI 默认提供 OpenAPI、Swagger UI 和 ReDoc。

All registered endpoints
All registered endpoints

身份认证

Flask 需要第三方扩展实现安全功能。

FastAPI 原生支持 HTTP 基本认证、OAuth2、OpenID Connect 等:

import secrets
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
    correct_user = secrets.compare_digest(credentials.username, "stanleyjobson")
    correct_pass = secrets.compare_digest(credentials.password, "swordfish")
    if not (correct_user and correct_pass):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
    return credentials.username
@app.get("/whoami")
def who_ami_i(username: str = Depends(get_current_username)):
    return {"username": username}

CORS

Flask 通过 Flask‑CORS 实现。

from flask_cors import CORS
app = Flask(__name__)
CORS(app)

FastAPI 原生支持:

from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = ["*"]
app.add_middleware(CORSMiddleware, allow_origins=origins)

测试

Flask 使用内置测试客户端:

import pytest
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
    return {"message": "OK"}
def test_hello():
    res = app.test_client().get("/")
    assert res.status_code == 200
    assert res.data == b'{"message":"OK"}
'

FastAPI 使用 TestClient

from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/")
async def home():
    return {"message": "OK"}
client = TestClient(app)
def test_home():
    res = client.get("/")
    assert res.status_code == 200
    assert res.json() == {"message": "OK"}

部署

生产服务器

Flask 推荐使用 Gunicorn、uWSGI 等 WSGI 服务器。

pip install gunicorn
gunicorn main:app

FastAPI 使用 Uvicorn,或通过 Gunicorn + UvicornWorker 组合:

pip install uvicorn
uvicorn main:app
# or with gunicorn
gunicorn -w 3 -k uvicorn.workers.UvicornWorker main:app

Docker

Flask Dockerfile 示例

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "main:app"]

FastAPI Dockerfile 示例

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

总结

Flask 与 Django 是最流行的 Python Web 框架,FastAPI 则是第三大。Flask 作为微框架提供灵活性,但需要自行添加功能;FastAPI 内置许多现代特性(异步、自动文档、依赖注入),使得构建高性能 API 更加简洁。随着社区的成长,越来越多开发者倾向于使用 FastAPI 来构建机器学习模型服务或 RESTful API,迁移到 FastAPI 是一个值得考虑的选择。

官方文档

FastAPI:https://fastapi.tiangolo.com/

Flask:https://flask.palletsprojects.com/en/2.0.x/

本文翻译自 Moving from Flask to FastAPI,作者:Amal Shaji

相关阅读:

Python 正考虑更改版本号

Python Web框架的三强之争:Flask、Django和FastAPI

RStudio 推出新的 R 和 Python IDE

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Pythondependency-injectionFlaskFastAPIWeb APIPydanticASGI
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.