FastAPI入门到实战:快速搭建高性能API接口,比Flask快好几倍
FastAPI是现在最火的Python Web框架,性能高、开发快、自动生成文档,比Flask、Django开发效率高很多,非常适合做API接口、后端服务。本文从基础到实战,带你快速掌握FastAPI。
一、为什么选FastAPI
1.1 核心优势
1.2 适合场景
很多大厂都在用FastAPI,比如Uber、Netflix、百度、字节跳动,现在招聘后端开发很多都要求会FastAPI。
二、快速开始
2.1 安装
pip install fastapi uvicorn
uvicorn是ASGI服务器,用来运行FastAPI应用。
2.2 第一个接口
创建`main.py`文件:
from fastapi import FastAPI
# 创建FastAPI实例
app = FastAPI()
# 定义接口
@app.get("/")
def read_root():
return {"message": "Hello FastAPI!"}
@app.get("/hello/{name}")
def say_hello(name: str, age: int = 0):
return {"message": f"Hello {name}, you are {age} years old"}
2.3 运行服务
uvicorn main:app --reload
`–reload`参数是开发模式,代码修改后自动重启服务。
启动后访问:
访问`http://127.0.0.1:8000/hello/张三?age=25`,会返回:
{"message": "Hello 张三, you are 25 years old"}
如果参数类型不对,比如age传字符串,FastAPI会自动返回错误提示,不用自己写参数校验。
三、核心功能
3.1 请求参数
FastAPI支持多种类型的参数:
路径参数
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
访问`/items/123`,item_id会自动转成int类型,传字符串会报错。
查询参数
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
访问`/items?skip=5&limit=20`,参数有默认值的话可以不传。
请求体
用Pydantic模型定义请求体,自动做参数校验:
from pydantic import BaseModel
from typing import Optional
class Item(BaseModel):
name: str
price: float
description: Optional[str] = None
in_stock: bool = True
@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "item_price": item.price}
发送POST请求,请求体是JSON格式:
{
"name": "手机",
"price": 5999,
"description": "最新款智能手机",
"in_stock": true
}
FastAPI会自动校验参数类型,字段缺失或者类型不对会返回详细的错误信息。
3.2 响应模型
可以定义响应模型,指定返回的字段,过滤敏感信息:
class User(BaseModel):
username: str
email: str
password: str # 敏感字段
avatar: Optional[str] = None
class UserResponse(BaseModel):
username: str
email: str
avatar: Optional[str] = None
@app.post("/users/", response_model=UserResponse)
def create_user(user: User):
# 保存用户到数据库
return user
返回的时候会自动过滤掉password字段,不会返回给前端,不用手动删。
3.3 路径操作配置
@app.post(
"/items/",
summary="创建商品",
description="创建新的商品接口,需要传入商品名称、价格等信息",
tags=["商品管理"],
status_code=201 # 指定返回的状态码
)
def create_item(item: Item):
return item
这些配置会自动显示在接口文档里,方便前端开发看。
3.4 表单数据
处理表单提交:
from fastapi import Form
@app.post("/login/")
def login(username: str = Form(...), password: str = Form(...)):
return {"username": username}
适合处理HTML表单提交,或者上传文件的场景。
3.5 文件上传
from fastapi import File, UploadFile
@app.post("/uploadfile/")
def create_upload_file(file: UploadFile = File(...)):
return {"filename": file.filename, "size": file.size}
大文件上传也支持,还可以限制文件大小、类型。
四、依赖注入
FastAPI的依赖注入系统非常强大,能减少很多重复代码:
from fastapi import Depends, HTTPException
# 定义依赖,模拟获取当前登录用户
def get_current_user(token: str = Depends(oauth2_scheme)):
if token != "valid_token":
raise HTTPException(status_code=401, detail="未授权")
return {"username": "test_user"}
# 接口使用依赖,需要登录才能访问
@app.get("/users/me")
def read_users_me(current_user: dict = Depends(get_current_user)):
return current_user
依赖可以多层嵌套,非常适合做权限验证、数据库连接、日志记录这些通用功能。
五、数据库操作
FastAPI可以搭配任何数据库,常用的是SQLAlchemy:
5.1 安装依赖
pip install sqlalchemy pymysql
5.2 数据库连接
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://user:password@localhost/dbname"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
# 依赖,获取数据库会话
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
5.3 定义模型
from sqlalchemy import Column, Integer, String, Float
class DBItem(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), index=True)
price = Column(Float)
description = Column(String(500))
5.4 数据库操作接口
# 创建商品
@app.post("/db/items/")
def create_db_item(item: Item, db: Session = Depends(get_db)):
db_item = DBItem(**item.dict())
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
# 查询商品列表
@app.get("/db/items/")
def read_db_items(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
items = db.query(DBItem).offset(skip).limit(limit).all()
return items
# 查询单个商品
@app.get("/db/items/{item_id}")
def read_db_item(item_id: int, db: Session = Depends(get_db)):
item = db.query(DBItem).filter(DBItem.id == item_id).first()
if item is None:
raise HTTPException(status_code=404, detail="商品不存在")
return item
六、异步支持
FastAPI原生支持异步,性能更高:
import asyncio
@app.get("/async/")
async def async_hello():
await asyncio.sleep(1)
return {"message": "Hello Async"}
数据库操作也可以用异步版本,比如SQLAlchemy 1.4+支持异步,或者用asyncpg操作PostgreSQL,并发性能更好。
七、身份认证
FastAPI自带OAuth2认证支持,很容易实现JWT认证:
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from datetime import datetime, timedelta
# JWT配置
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 创建token
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
# 登录接口
@app.post("/token")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
# 验证用户名密码
if form_data.username != "admin" or form_data.password != "123456":
raise HTTPException(status_code=401, detail="用户名或密码错误")
access_token = create_access_token(data={"sub": form_data.username})
return {"access_token": access_token, "token_type": "bearer"}
八、部署上线
8.1 生产环境运行
开发环境用uvicorn的–reload,生产环境不要用,用gunicorn+uvicorn:
pip install gunicorn
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
`-w 4`是启动4个 worker进程,根据CPU核心数设置,一般是CPU核心数*2+1。
8.2 Docker部署
创建Dockerfile:
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
构建运行:
docker build -t fastapi-app .
docker run -p 8000:8000 fastapi-app
8.3 反向代理
用Nginx做反向代理,配置静态文件、SSL证书:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
九、项目结构推荐
中小型项目可以按这个结构组织:
project/
├── main.py # 入口文件
├── requirements.txt # 依赖
├── .env # 环境变量配置
├── apis/ # 接口层
│ ├── __init__.py
│ ├── user.py
│ └── item.py
├── models/ # 数据库模型
│ ├── __init__.py
│ ├── user.py
│ └── item.py
├── schemas/ # Pydantic模型
│ ├── __init__.py
│ ├── user.py
│ └── item.py
├── crud/ # 数据库操作层
│ ├── __init__.py
│ ├── user.py
│ └── item.py
├── utils/ # 工具类
│ ├── __init__.py
│ ├── security.py
│ └── database.py
└── Dockerfile
分层清晰,方便维护。
FastAPI开发效率高,性能好,生态也越来越完善,是现在Python后端开发的首选框架,学完就能快速开发出高性能的API接口,赶紧试试吧!