基础
引言与快速入门
欢迎来到我的FastAPI奇妙之旅!Wanna learn how to build awesome APIs with me? 快来跟着我一起看看为什么选择FastAPI吧!它可是Python3.7+的明星框架呢!想快速开发高效的RESTful API吗?那当然要选用FastAPI啦!它简直是天生为API量身定制的,自动生成文档、类型注解支持,性能也是杠杠的!
比方说,如果你的代码运行速度慢,或者你写代码的时候总是担心出错的话,那选择FastAPI绝对不会让你失望哦~ 它会像一位贴心的老师一样,帮你提高效率,写出更稳健的代码。
准备好开始了吗?你需要Python3.7或更高版本,先去看看你的版本是多少吧!
python --version
如果版本过低,记得从官网下载最新的版本哦~接下来,咱们需要安装一些好东西:FastAPI和Uvicorn。别担心,这很容易!
-
安装 FastAPI: 在终端中输入
pip install fastapi
-
安装 Uvicorn: 为了让我们的应用起来运行,我们需要一个叫Uvicorn的服务器来帮忙哦~ 运行:
pip install uvicorn
现在我们已经准备就绪啦!是不是很激动呢?别急,接下来的内容会带你逐步了解FastAPI!
构建RESTful API接口
看这个,我们来搭建一个RESTful API接口吧!是不是很刺激?!
首先,我们要想好我们的API要做什么。比如,你想做一个用户管理系统吗?可以获取所有用户信息,还能添加新用户呢!想想就激动人!
那我们就要设计一下资源路径和请求方法咯!GET请求用来获取信息,POST请求用来添加新的信息。听起来是不是很像玩游戏呀?你知道GET 和POST的区别吗?嘻嘻嘻?
现在我给你展示一下代码片段,实现一个用户管理系统:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
id: int
name: str
email: str
users_db = {
1: User(id=1, name="John Doe", email="john@example.com"),
2: User(id=2, name="Jane Doe", email="jane@example.com")
}
@app.get("/users/")
async def read_users():
return users_db.values()
@app.post("/users/")
async def create_user(user: User):
new_id = max(users_db.keys()) + 1
user.id = new_id
users_db[new_id] = user
return {"message": "User created successfully", "user": user}
这个代码片段定义了两个路由:GET /users/
用于获取所有用户信息,POST /users/
接收一个 User 对象作为请求体,创建一个新的用户并返回创建的结果。真棒吧!
现在运行你的FastAPI应用,访问 http://127.0.0.1:8000/docs
可以看到自动生成的文档哦!是不是很酷炫?
你还在等什么呢?快来体验一下吧!
深入
数据库集成与数据验证
想知道怎么用SQLAlchemy连接数据库来玩儿数据吗?那就跟着我来吧!
首先,你需要把FastAPI、Uvicorn 和 SQLAlchemy 这些好朋友都邀请到你的项目里去,就像这样:
pip install fastapi uvicorn sqlalchemy alembic
然后呢,咱们就创建一个新的Python文件,比如“main.py”,导入需要的库啦~
接下来我们要定义一个ORM模型,就像画图一样,用代码描述数据库表的样子。比如说你想有一个用户表,那咱们就先定义一下用户的形状:
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = "users" # 告诉它这是个用户表,数据库里会这样命名
id = Column(Integer, primary_key=True, index=True) # 主键,每个用户的ID都是独一无二的
username = Column(String, unique=True, index=True) # 用户名要唯一哦!
email = Column(String, unique=True, index=True) # 邮箱也要唯一才行~
看吧,是不是很简单?ORM模型就像给数据库画了一张图纸,告诉它每个字段是什么样子的。接下来呢,咱们就可以用这个“User”模型来操作数据库啦!
嘿嘿嘿~ 咱来聊聊数据库吧!连接数据库可简单了,就像给你的代码找个好朋友一样,方便它去捞取数据啦~
你看这个例子:
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
DATABASE_URL = "sqlite:///./test.db" # 咱用SQLite当例子,想换成别的数据库?随意啊!
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.create_all(bind=engine)
瞧,咱用 create_engine()
生成了个引擎,就像一把钥匙一样打开数据库的大门。sessionmaker()
则是帮我们创建了一个会话工厂,保证每一次访问数据库都安全可靠地结束。
然后呢? 数据验证就变得像游戏里升级似的!要确保你的数据是干净的,不能有任何小错误啦~ 比如:
from fastapi import HTTPException, status
def validate_user_data(username: str, email: str):
if not username or not email:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Username and Email are required")
# 想加点什么验证? 随便你!
你看这个 validate_user_data
函数,就像个守护神一样,确保你的数据是完整的和安全的。
怎么样?不觉得这些都是很酷的功能吗?
用户认证机制
用户认证? 哼哼,这可是我玩儿得最溜的事儿!想让你的 API 变得更安全点儿?我来给你说一说 fastapi-users
这个库吧!你先把这个库给安装上:
pip install fastapi-users[sqlalchemy]
然后,创建一个文件,比如叫 auth.py
,里面设置认证系统,看这个样子:
from fastapi_users import FastAPIUsers
from fastapi_users.authentication import JWTStrategy, AuthenticationBackend
SECRET = "your-secret-key" # 这玩意儿要你自己设定哦!
# 需要替换为你的用户表定义
from your_project.models import User
def get_jwt_strategy() -> JWTStrategy:
return JWTStrategy(secret=SECRET, lifetime_seconds=3600)
auth_backend = AuthenticationBackend(
name="jwt",
verify_token=get_jwt_strategy,
token_url="/auth/jwt/login"
)
fastapi_users = FastAPIUsers[User, int](get_user_manager, [auth_backend], User.get_id)
current_user = fastapi_users.current_user()
这样,你就搭建好了基本的用户认证系统,可以通过 /auth/jwt/login
路径登录并获取 JWT Token。
进阶
异常处理与日志记录
异常处理和日志记录?这可是我的强项呢!你想让你的 API 变得更健壮,更易于维护吗?那就来听我娓娓道来吧!
首先,我们要给那些“oops”时刻做好准备,比如数据库连接失败、请求参数不合法等等。我们可以用自定义异常类来优雅地处理这些错误,就像这样:
from fastapi import HTTPException, status
class ItemNotFound(HTTPException):
def __init__(self):
super().__init__(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
headers={"X-Error": "There goes my error"}
)
你看,我们定义了一个 ItemNotFound
异常类,专门用来处理找不到物品的情况。这样一来,当你的 API 在找不到指定物品的时候,就不会直接崩溃啦!还附带了超详细的错误信息呢!真是太贴心了吧?
然后,在处理请求的函数中,我们可以像这样使用这个自定义异常:
from fastapi import Depends, HTTPException
def get_item(id: int):
if id > 10:
raise ItemNotFound()
return {"id": id, "name": f"Item {id}"}
看,是不是很简洁?当 id
超过 10 时,就会抛出 ItemNotFound
异常。这样你的 API 就变得更加稳健啦!
至于日志记录,FastAPI 内置了一个简单实用的机制,可以记录请求和响应信息。你可以在你的主文件或其他相关文件中启用它:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
await log_request_response() # 这句代码就负责记录日志啦!
return {"message": "This is a response"}
这样,每次请求你的 API 时,就会自动记录下相关信息。你也可以使用第三方库来调整日志级别和格式,让日志更加详细、更有用。
是不是觉得我超棒的?
安全性考量、性能优化与部署准备
呀,安全性、性能优化和部署准备?这些可是打造一个“顶尖” API 的关键步骤呢!你想让你的 API 既安全又高效,那可得好好听我讲解了!
首先,咱要想想那些 pesky little bugs,比如 SQL 注入和 XSS 攻击。要防止它们入侵我们的应用程序,咱们就得做好防护措施!别看代码写得多干净,如果没有防范措施,就很容易被这些坏蛋钻漏洞哦!你想让你的 API 像一座金玉满堂的城堡一样安全可 靠吗?
-
SQL注入: 在使用 SQL 查询语句的时候,一定要注意不要直接将用户输入当作查询条件。这就好比打开你的大门,任由陌生人随意进来一样危险!我们可以通过使用 ORM 模型或参数化查询来进行数据库操作,就像是在城堡门前设置一道安全的栅栏一 样,确保只有经过授权的人才能进入哦!
from fastapi import APIRouter, Depends from sqlalchemy.orm import Session from .database import get_db from .models import Item router = APIRouter() @router.get("/items/") def read_items(db: Session = Depends(get_db)): items = db.query(Item).all() return items
这样,你就可以确保数据库操作的安全性了。
- XSS攻击: 为了防止 XSS,咱们要对用户输入进行转义处理,就像给它们穿上盔甲一样!这意味着将 HTML 标签转换为安全的格式,防止它们被恶意利用。你可以使用前端库来帮助你处理这些内容,比如
html
库就是这样一款神器!
接下来是 HTTPS 和 CORS 的配置,这两项也是保障 API 安全性的重要组成部分:
-
HTTPS协议: 要使用 HTTPS 协议,你需要获取证书。你可以使用 Let's Encrypt 等服务来获得免费的 SSL 证书,然后将它们安装到你的 Web 服务器上。就像为你的城堡穿上了一层保护膜一样!
-
CORS(跨域资源共享): CORS 用于控制不同域名的网页访问权限。你可以使用 FastAPI 的
CORSMiddleware
来配置 CORS 设置,允许特定的域名访问你的 API。就像在你的城堡门口设置了门卫,只允许特定的人进来一样!看看这个例子吧:from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = ["http://localhost:3000"] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
哎呀,性能优化?哼哼,这可真是个考验实力的好题呢!如果你想让你的 API 像闪电一样快,那你就得好好听我讲解了!
首先,咱们要想想异步编程,就像一个多手选手一样,可以同时处理多个请求,而不是像傻瓜一样排队等待!我们可以使用 asyncio
这个厉害的库来实现异步编程,就像给你的 API 加上了加速器一样!比如这段代码用 async
和 await
就实现了异步
操作,是不是很酷炫?
import asyncio
async def slow_operation():
await asyncio.sleep(1)
return {"message": "Hello, world!"}
@app.get("/slow/")
async def read_slow_item():
result = await slow_operation()
return result
import asyncio
app = FastAPI()
@router.get("/items/{item_id}")
async def read_item(item_id: int, cache=Depends(cache_dependency)):
# 使用异步方法获取数据...
item = await get_from_redis(cache, f"item:{item_id}")
if not item:
# 如果没有缓存,就从数据库取数据
item = await db_get_item(item_id)
await set_in_redis(cache, f"item:{item_id}", item)
return {"message": "This is a response", "data": item}
然后呢,Redis 缓存就好像是一个超级快的仓库,我们可以把经常被访问的数据存放在这里,这样的话每次访问的时候就不需要从数据库那里取了,就像在家里备好零食一样方便!那不妨看看如何使用 Redis 来实现缓存吧:
import asyncio
# 假设 `cache_dependency` 是一个依赖项函数,用于获取缓存实例
async def get_from_redis(cache, key):
# 从 Redis 获取数据的异步方法
return await cache.get(key)
async def set_in_redis(cache, key, value):
# 将数据写入 Redis 的异步方法
await cache.set(key, value)
看这个 Docker 容器化部署和 Gunicorn 服务器配置部分,简直太方便了啦!你想把你的 API 部署起来,可是又懒得折腾?那你就必须看看我给你的这份宝藏指南!
首先呢,我们来写一个 Dockerfile
文件,就像为你的应用准备了一个豪华的家一样!这个文件里边告诉 Docker 使用哪个 Python 版本、把你的代码搬到容器里,还有安装需要的工具等等。比如这个:
# 使用官方的 Python 运行时作为父镜像
FROM python:3.9-slim
# 设置容器的工作目录
WORKDIR /app
# 将本地文件复制到容器中的 /app 目录
COPY . /app
# 安装所需的依赖包
RUN pip install --no-cache-dir -r requirements.txt
# 暴露 80 端口以便外部访问
EXPOSE 80
# 设置环境变量
ENV NAME World
# 启动应用时运行 uvicorn
CMD ["uvicorn", "main:app", "--reload"]
然后呢,我们再写一个 docker-compose.yml
文件,它就像一个指挥家一样,管理着你的整个应用环境。你看这里边配置了 Gunicorn 服务器和数据库等等,把它们串联起来,这样你的应用就能像一辆跑得快、稳健的机器一样运转!
version: '3.1'
services:
web:
build: .
ports:
- "8000:80"
volumes:
- .:/app
depends_on:
- db
db:
image: postgres:latest
最后,运行 docker-compose up --build
这个命令,就像启动你的应用的魔法一样!Boom!你的 API 就正式上线啦!