FastAPI 教程

FastAPI 教程(中文版)

FastAPI 是一个现代、高性能的 Python Web 框架,用于构建 API。它基于 Python 类型提示(type hints),自动生成 OpenAPI 文档,支持异步,速度极快(与 Node.js 和 Go 相当)。


1. 安装 FastAPI 和 Uvicorn

pip install fastapi uvicorn
  • fastapi: 框架本体
  • uvicorn: ASGI 服务器,用于运行 FastAPI 应用

2. 第一个 FastAPI 应用

创建 main.py

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: str = None):
    return {"item_id": item_id, "q": q}

运行应用

uvicorn main:app --reload

--reload:开发模式,代码修改后自动重启

访问:

  • API: http://127.0.0.1:8000
  • 自动文档(Swagger UI): http://127.0.0.1:8000/docs
  • OpenAPI JSON: http://127.0.0.1:8000/openapi.json

3. 路径参数与查询参数

@app.get("/users/{user_id}")
def get_user(user_id: int, active: bool = True):
    return {"user_id": user_id, "active": active}
  • user_id: 路径参数(必填)
  • active: 查询参数(可选,默认 True

4. 请求体(POST)

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

@app.post("/items/")
def create_item(item: Item):
    return {"item_name": item.name, "item_price_with_tax": item.price + (item.tax or 0)}

Pydantic 自动验证数据类型和格式


5. 查询参数与字符串验证

from fastapi import Query

@app.get("/items/")
def read_items(
    skip: int = 0,
    limit: int = 10,
    q: str = Query(None, min_length=3, max_length=50)
):
    return {"skip": skip, "limit": limit, "q": q}

6. 路径参数验证

from fastapi import Path

@app.get("/items/{item_id}")
def read_item(item_id: int = Path(..., gt=0, le=100)):
    return {"item_id": item_id}
  • ... 表示必填
  • gt=0:大于 0
  • le=100:小于等于 100

7. 响应模型

from pydantic import BaseModel

class UserOut(BaseModel):
    id: int
    username: str
    email: str | None = None

@app.get("/users/{user_id}", response_model=UserOut)
def get_user(user_id: int):
    # 模拟数据库
    return {"id": user_id, "username": "john_doe", "email": "john@example.com"}

只返回 response_model 中定义的字段


8. 依赖注入(Dependency Injection)

from fastapi import Depends

async def get_current_user():
    return {"user_id": 1, "username": "alice"}

@app.get("/profile")
def get_profile(user=Depends(get_current_user)):
    return user

9. 异步支持

import asyncio

@app.get("/async")
async def async_endpoint():
    await asyncio.sleep(1)
    return {"message": "This is async!"}

10. 异常处理

from fastapi import HTTPException

@app.get("/items/{item_id}")
def read_item(item_id: int):
    if item_id not in [1, 2, 3]:
        raise HTTPException(status_code=404, detail="Item not found")
    return {"item_id": item_id}

11. 中间件(Middleware)

from fastapi import Request
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

12. 数据库集成(示例:SQLAlchemy + SQLite)

pip install sqlalchemy databases[sqlite]
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)

Base.metadata.create_all(bind=engine)

# 在路由中使用
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/users/")
def create_user(name: str, db=Depends(get_db)):
    user = User(name=name)
    db.add(user)
    db.commit()
    db.refresh(user)
    return user

13. 静态文件与模板

pip install jinja2
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import Request

app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")

@app.get("/html")
def get_html(request: Request):
    return templates.TemplateResponse("index.html", {"request": request, "title": "FastAPI"})

templates/index.html

<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
    <h1>Hello from FastAPI + Jinja2!</h1>
</body>
</html>

14. 安全(API Key 示例)

from fastapi import Security, Depends
from fastapi.security.api_key import APIKeyHeader

API_KEY = "secret123"
api_key_header = APIKeyHeader(name="X-API-Key")

def get_api_key(key: str = Depends(api_key_header)):
    if key != API_KEY:
        raise HTTPException(status_code=403, detail="Invalid API Key")
    return key

@app.get("/secure")
def secure_endpoint(api_key: str = Depends(get_api_key)):
    return {"message": "Secure data"}

15. 测试 FastAPI

from fastapi.testclient import TestClient

client = TestClient(app)

def test_read_root():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"Hello": "World"}

运行测试:

pip install pytest
pytest

16. 部署建议

方式推荐工具
本地开发uvicorn main:app --reload
生产部署uvicorn main:app --host 0.0.0.0 --port 80 --workers 4
容器化Docker + Gunicorn + Uvicorn

Dockerfile 示例

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

官方资源

  • 文档:https://fastapi.tiangolo.com/zh/
  • GitHub:https://github.com/tiangolo/fastapi
  • 中文教程:https://fastapi.tiangolo.com/zh/tutorial/

小结

特性说明
速度快基于 Starlette,异步支持
自动文档Swagger UI + ReDoc
类型安全Pydantic 验证
依赖注入简洁优雅
易测试内置 TestClient

现在开始你的第一个 FastAPI 项目吧!

fastapi dev main.py   # FastAPI CLI(0.104+)

推荐使用 fastapi-clipip install fastapi[all]


需要我为你生成一个完整的 FastAPI + SQLAlchemy + JWT 认证 + Docker 的项目模板吗?可以继续问我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注