跳到主要内容

FastApi

简介

FastApi 是一个基于 Python 的高性能 Web 框架,专门用于快速构建 API 接口服务。

  • 原生支持异步
  • Pydantic 类型提示与验证,减少手动校验代码
  • 自动生成可交互式文档,浏览器中直接调用和测试 API

第一个 FastApi 程序

  1. 创建项目
    隔离项目运行环境,避免依赖冲突,保持全局环境的干净和稳定

  2. 创建文件

  3. 运行项目

    通过 IDEA 运行项目

    通过命令行运行项目

    uvicorn main:app --reload
    • uvicorn 是一个 ASGI 服务器,用于运行 FastApi 应用
    • main:app 表示运行 main.py 文件中的 app 对象` 指定 FastApi 应用
    • --reload 表示开启自动 reload 功能,代码修改后自动重启服务器
  4. 运行项目,访问 http://127.0.0.1:8000/docs

路由

路由是 URL 地址和处理函数之间的映射关系,它决定了当用户访问某个特定网址时,服务器应该执行那段代码来返回结果。

参数简介和路径参数

同一段接口逻辑,根据参数不同返回不同的数据

参数就是客户端发送请求时附带的额外信息和指令

参数的作用是让同一个接口能根据不同的输入,返回不同的输出,实现动态交互。

路径参数

  • 位置:URL 路径的一部分 /book/{id}
  • 作用:指向唯一的、特定的资源
  • 方法:GET
@app.get("/hello/{name}")
async def say_hello(name: str):
return {"message": f"Hello {name}"}

FastApi 允许为参数声明额外的信息和校验(使用 Path 函数)

Path 参数说明
...必填
gt/ge大于/大于等于
lt/le小于/小于等于
description描述
min_length长度限制
max_length
@app.get('/book/{id}')
async def get_book(id: int = Path(...,gt=0,lt=101,description='书籍的ID')):
return {"id":id , "title": f"这是第{id}本书"}

查询参数

声明的参数不是路径参数时,路径操作函数会把该参数自动解释为查询参数

  • 位置:URL ? 之后,k1 = v1&k2 = v2
  • 作用:对资源集合进行过滤、排序、分页等操作
  • 方法:GET
@app.get('/news/news_list')
async def get_news_list(skip:int, limit:int = 10):
return {"skip":skip,"limit":limit}

使用 Query 类型注解可以为查询参数添加额外信息和校验(使用 Query 函数)

@app.get('/news/news_list')
async def get_news_list(skip:int = Query(0,description='跳过多少条数据'), limit:int = Query(10,description='每页多少条数据')):
return {"skip":skip,"limit":limit}

请求体参数

  • 位置:HTTP 请求的消息体 {body}

  • 作用:创建、更新资源、携带大量数据,如 JSON

  • 方法:POST、PUT 等

  1. 定义类型

from pydantic import BaseModel

class User(BaseModel):

username: str

password: str

  1. 类型注解

@app.post('/register')

async def register(user: User):

return user

from pydantic import BaseModel,File
class User(BaseModel):
username: str = Field(...,min_length=3,max_length=50,description='用户名')
password: str = Field(...,min_length=3,max_length=50,description='密码')
avatar: File

响应类型

默认情况下,FastAPI 会自动将路径操作函数返回的 Python 对象(字典、列表、Pydantic 模型等),经由 jsonable_encoder 转换为 JSON 兼容格式,并包装为 JSONResponse 返回,这省去了手动序列化的步骤,让开发者能更专注于业务逻辑。

如果要返回非 JSON 数据(如HTML、文件流),FastAPI 提供了丰富的响应类型来返回不同数据。

响应类型用途示例
JSONResponse默认响应,返回JSON数据return {"key": "value"}
HTMLResponse返回HTML内容return HTMLResponse(html_content)
PlainTextResponse返回纯文本return PlainTextResponse("text")
FileResponse返回文件下载return FileResponse(path)
StreamingResponse流式响应生成器函数返回数据
RedirectResponse重定向return RedirectResponse(url)

设置方式

  1. 在装饰器中指定响应类,适合固定返回类型(HTML、纯文本)


    @app.get('/html',response_class=HTMLResponse)

    async def html():

    return '<h1>Hello World666</h1>'

  2. 返回响应对象(文件下载、图片、流式响应)


    # FileResponse 是 FastAPI 提供的专门用于高效返回文件内容(如图片、PDF、Excel、音视频等)的相应类。它能够智能处理文件路径、媒体类型推断、范围请求和缓存头部,是服务静态文件的推荐方式。

    @app.get('/file')

    async def file():

    file_path = '16479213397724544.png'

    return FileResponse(file_path)

自定义响应数据格式

response_model 是路径操作装饰器(如 @app.get 或 @app.post) 的关键参数,它通过第一个 Pydantic 模型来严格定义和约束 API 端点的输出格式。这一机制在提供自动数据验证和序列化的同时,更是保障数据安全性的第一道防线。


class News(BaseModel):
id: int
title: str
content: str

@app.get("/news/{id}",response_model=News)
async def get_news(id:int):
return {
"id":id,
"title": f"这是第{id}本书",
"content": "这是一本好书"
}

异常处理

对于客户端引发的错误 (4xx,如资源未找到、认证失败),应使用 fastapi.HTTPException 来中断正常处理流程,并返回标准错误响应。

@app.get('/news1/{id}')
async def get_news(id:int):
id_list = [1,2,3,4,5,6]
if id not in id_list:
raise HTTPException(status_code=404,detail='当前id不存在')
return {"id":id}

中间件

使用中间件为每个请求前后添加统一的处理逻辑

  • 多个接口都需要验证用户身份
  • 多个接口都需要记录日志、性能数据
  • 跨域处理
  • 响应头处理

中间件(Middleware)是一个在 每次请求进入 FastAPI 应用时都会被执行的函数。 它在请求到达实际的路径操作(路由处理函数)之前运行,并且在响应返回给客户端之前再运行一次。

中间件的函数顶部使用装饰器 @app.middleware('http')

# request 是请求, call_next 是传递请求的

@app.middleware('http')
async def middleware1(request,call_next):
print('中间件1 start')
response = await call_next(request) # 传递请求,返回响应
print('中间件1 end')
return response


@app.middleware('http')
async def middleware2(request,call_next):
print('中间件2 start')
response = await call_next(request) # 传递请求,返回响应
print('中间件2 end')
return response

依赖注入

通过依赖注入系统来共享通用逻辑,减少代码重复。比如分页逻辑

提示

中间件控制所有请求,包括静态文件请求。

  • 依赖项: 可重用的组件(函数/类),负责提供某种功能或数据
  • 注入: FastAPI 自动帮忙调用依赖项,并将结果注入到路径操作函数中。
# 分页参数逻辑公用:新闻列表和用户列表
# 1. 依赖项
async def common_parameters(
skip: int = Query(0,ge= 0),
limit: int = Query(10,le=60),
):
return {'skip':skip,'limit':limit}
# 3. 声明依赖项 - 注入依赖
@app.get('/news/news_list')
async def get_news_list(commons = Depends(common_parameters)):
return commons

@app.get('/user/user_list')
async def get_user_list(commons = Depends(common_parameters)):
return commons

应用场景

  • 处理请求参数: 从请求中提取和验证参数
  • 共享业务逻辑:抽取封装多个路由公用的逻辑代码
  • 共享数据库连接: 管理数据库会话的创建、使用、关闭
  • 安全和认证:验证用户身份、检查权限和角色要求等。