FastAPI作为Python生态中新兴的Web框架,凭借其出色的性能表现和开发者友好特性,正在快速成为构建API服务的首选工具。这个教程将从零开始,带你完整掌握FastAPI的核心用法,最终实现生产级部署的全套技能。
我最初接触FastAPI是在2019年,当时正在为一个物联网平台选型后端框架。经过对比Flask、Django等传统选项后,FastAPI的异步支持、自动文档生成等特性最终打动了我。几年实战下来,这个框架确实没有让人失望 - 我们的API响应时间平均降低了40%,开发效率提升了近一倍。
本教程特别适合以下人群:
推荐使用Python 3.8+版本以获得最佳兼容性。我个人习惯使用pyenv管理多版本Python环境:
bash复制# 安装pyenv(MacOS)
brew install pyenv
# 安装指定Python版本
pyenv install 3.10.6
# 创建虚拟环境
python -m venv fastapi-env
source fastapi-env/bin/activate
注意:Windows用户可以使用WSL2获得接近Linux的开发体验,这对后续部署环节尤为重要
除了fastapi本体,还需要安装uvicorn作为ASGI服务器:
bash复制pip install fastapi uvicorn
生产环境建议固定版本:
bash复制pip install fastapi==0.95.2 uvicorn==0.22.0
典型的生产级依赖栈还包括:
创建main.py文件:
python复制from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
启动开发服务器:
bash复制uvicorn main:app --reload
访问http://localhost:8000即可看到返回的JSON响应。--reload参数启用热重载,这在开发阶段非常实用。
FastAPI支持多种参数声明方式:
python复制from fastapi import Path, Query
@app.get("/items/{item_id}")
async def read_item(
item_id: int = Path(..., title="商品ID"),
q: str = Query(None, alias="query"),
size: float = Query(1.0, gt=0)
):
return {"item_id": item_id, "q": q, "size": size}
参数验证特性包括:
定义数据模型是生产级API的关键:
python复制from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
username: str
email: EmailStr
password: str
age: int = Field(gt=18, description="必须年满18岁")
@app.post("/users/")
async def create_user(user: UserCreate):
# 数据自动验证
return {"username": user.username}
Pydantic提供的验证能力:
推荐使用SQLAlchemy 2.0+的异步API:
python复制from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
DATABASE_URL = "sqlite+aiosqlite:///./test.db"
engine = create_async_engine(DATABASE_URL)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession)
@app.get("/users/{user_id}")
async def get_user(user_id: int):
async with AsyncSessionLocal() as session:
result = await session.execute(select(User).where(User.id == user_id))
user = result.scalars().first()
return user
经验:异步数据库操作需要特别注意连接管理,建议使用依赖注入系统
JWT认证实现示例:
python复制from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=401,
detail="无效凭证"
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
except JWTError:
raise credentials_exception
user = await get_user(username)
if user is None:
raise credentials_exception
return user
安全最佳实践:
uvicorn启动参数建议:
bash复制uvicorn main:app \
--host 0.0.0.0 \
--port 8000 \
--workers 4 \
--limit-concurrency 1000 \
--timeout-keep-alive 30
关键参数说明:
Dockerfile示例:
dockerfile复制FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--workers", "4"]
构建与运行:
bash复制docker build -t fastapi-app .
docker run -d -p 8000:8000 --name myapp fastapi-app
推荐使用Prometheus + Grafana监控方案:
python复制from fastapi import Request
from prometheus_client import Counter, generate_latest
REQUEST_COUNT = Counter(
"app_requests_total",
"Total request count",
["method", "endpoint"]
)
@app.middleware("http")
async def monitor_requests(request: Request, call_next):
REQUEST_COUNT.labels(
method=request.method,
endpoint=request.url.path
).inc()
return await call_next(request)
@app.get("/metrics")
async def metrics():
return Response(generate_latest())
日志配置建议:
典型性能问题及解决方案:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 高并发时响应变慢 | 数据库连接池不足 | 增加连接池大小 |
| CPU利用率高 | 同步阻塞操作 | 检查是否有未异步化的IO操作 |
| 内存持续增长 | 内存泄漏 | 使用memory_profiler分析 |
正确配置CORS中间件:
python复制from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://example.com"],
allow_methods=["*"],
allow_headers=["*"],
)
连接池最佳实践:
python复制async def get_db():
async with AsyncSessionLocal() as session:
try:
yield session
finally:
await session.close()
生产级项目推荐结构:
code复制project/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── api/
│ │ ├── v1/
│ │ │ ├── endpoints/
│ │ │ ├── models/
│ │ │ └── routers.py
│ ├── core/
│ │ ├── config.py
│ │ └── security.py
│ └── db/
│ ├── models.py
│ └── session.py
├── tests/
├── requirements/
│ ├── base.txt
│ ├── dev.txt
│ └── prod.txt
└── Dockerfile
关键设计原则:
使用pytest编写测试:
python复制from fastapi.testclient import TestClient
def test_read_item():
with TestClient(app) as client:
response = client.get("/items/42")
assert response.status_code == 200
assert response.json() == {"item_id": 42}
测试数据库配置技巧:
python复制@pytest.fixture
async def test_db():
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield engine
await engine.dispose()
使用locust进行压力测试:
python复制from locust import HttpUser, task
class ApiUser(HttpUser):
@task
def read_item(self):
self.client.get("/items/42")
测试指标关注点:
GitHub Actions配置示例:
yaml复制name: CI/CD Pipeline
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements/dev.txt
- name: Run tests
run: |
pytest -v --cov=app --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v3
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t fastapi-app .
- name: Log in to Registry
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Push Docker image
run: |
docker tag fastapi-app username/fastapi-app:${{ github.sha }}
docker push username/fastapi-app:${{ github.sha }}
使用redis实现API缓存:
python复制from fastapi_cache import FastAPICache
from fastapi_cache.backends.redis import RedisBackend
from redis import asyncio as aioredis
@app.on_event("startup")
async def startup():
redis = aioredis.from_url("redis://localhost")
FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")
@app.get("/items/{item_id}")
@cache(expire=60)
async def get_item(item_id: int):
return {"item_id": item_id}
使用Celery实现异步任务:
python复制from celery import Celery
celery = Celery(__name__, broker="redis://localhost:6379/0")
@celery.task
def process_data(data: dict):
# 耗时操作
return result
@app.post("/process")
async def start_processing(data: dict):
task = process_data.delay(data)
return {"task_id": task.id}
自定义Swagger UI配置:
python复制app = FastAPI(
title="My API",
description="API文档说明",
version="0.1.0",
docs_url="/api/docs",
redoc_url="/api/redoc",
openapi_url="/api/openapi.json"
)
可以进一步:
与Consul集成的示例:
python复制import consul
c = consul.Consul()
def register_service():
c.agent.service.register(
"fastapi-service",
service_id="fastapi-1",
address="127.0.0.1",
port=8000,
check={
"HTTP": "http://127.0.0.1:8000/health",
"Interval": "10s"
}
)
集成OpenTelemetry:
python复制from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
provider = TracerProvider()
processor = BatchSpanProcessor(JaegerExporter(
agent_host_name="localhost",
agent_port=6831,
))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
使用Kafka处理事件:
python复制from aiokafka import AIOKafkaProducer
producer = AIOKafkaProducer(bootstrap_servers='localhost:9092')
@app.on_event("startup")
async def startup_event():
await producer.start()
@app.on_event("shutdown")
async def shutdown_event():
await producer.stop()
@app.post("/events")
async def create_event(event: dict):
await producer.send("events-topic", json.dumps(event).encode())
return {"status": "queued"}
防范注入攻击:
python复制from pydantic import constr
class UserInput(BaseModel):
username: constr(strict=True, min_length=4, max_length=20, regex="^[a-zA-Z0-9_]+$")
content: str = Field(..., max_length=1000)
@app.post("/comments")
async def add_comment(comment: UserInput):
# 自动验证通过的内容可以安全处理
return {"status": "ok"}
防止暴力破解:
python复制from fastapi import Request
from fastapi.middleware import Middleware
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
@app.get("/protected")
@limiter.limit("5/minute")
async def protected_route(request: Request):
return {"message": "敏感操作"}
环境变量管理建议:
python复制from pydantic_settings import BaseSettings
class Settings(BaseSettings):
secret_key: str
database_url: str
class Config:
env_file = ".env"
settings = Settings()
使用pytest-benchmark进行性能测试:
python复制def test_api_performance(benchmark):
with TestClient(app) as client:
benchmark(client.get, "/items/42")
SQLAlchemy性能建议:
高效静态资源处理:
python复制from fastapi.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static")
优化建议:
统一错误响应格式:
python复制from fastapi import HTTPException, Request
from fastapi.responses import JSONResponse
class UnicornException(Exception):
def __init__(self, name: str):
self.name = name
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name} did something wrong."},
)
结构化日志配置:
python复制import logging
from pythonjsonlogger import jsonlogger
logger = logging.getLogger("uvicorn.error")
handler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
"%(asctime)s %(levelname)s %(message)s"
)
handler.setFormatter(formatter)
logger.addHandler(handler)
Kubernetes就绪检查:
python复制@app.get("/health")
async def health_check():
return {"status": "healthy"}
进阶检查可以包括:
在实际项目中,有几个关键点特别值得注意:
依赖管理:使用poetry代替pip可以更好地管理项目依赖,特别是处理传递依赖冲突时。我们的项目通过迁移到poetry,解决了85%的"works on my machine"问题。
配置分离:根据环境(开发/测试/生产)使用不同的配置文件。我推荐使用pydantic的BaseSettings配合.env文件管理配置,这样既安全又灵活。
API版本控制:从一开始就规划好API版本策略。我们采用路径版本控制(/v1/endpoint),配合适当的弃用通知机制,使版本迁移更加平滑。
文档维护:除了自动生成的OpenAPI文档,我们还维护了一份Markdown格式的API参考。使用mkdocs-material构建文档站点,既美观又实用。
监控告警:在生产环境,我们配置了Prometheus监控关键指标,当API错误率超过1%或P99延迟超过500ms时触发告警。这套系统多次帮助我们提前发现了潜在问题。
测试覆盖率:坚持要求核心业务逻辑达到90%以上的测试覆盖率。我们使用pytest-cov配合GitHub Actions的强制检查,确保没有未经测试的代码进入生产环境。
部署策略:采用蓝绿部署减少停机时间。结合Docker和Kubernetes,我们的部署过程可以在30秒内完成,且支持秒级回滚。
性能预算:为关键API设置性能预算(如首页API必须<200ms)。在CI流水线中加入性能测试,超过预算的代码变更会被自动拒绝。
团队协作:使用Git规范(如Conventional Commits)和代码审查确保代码质量。我们要求每个PR至少有一个审核者,且必须通过所有检查才能合并。
技术债务管理:定期(如每季度)进行技术债务评估,分配专门的时间进行处理。我们使用SonarQube跟踪技术债务,保持代码健康度在A级以上。