FastAPI 核心
FastAPI 官方中文文档https://fastapi.tiangolo.com/zh/角色Java 生态Python 生态后端开发框架SpringBootFastAPI用途写接口、做管理系统、业务后端写接口、做 AI 服务、模型部署一、路由、GET/POST1.创建并激活一个虚拟环境2.安装 FastAPIpip install fastapi[standard]3.在合适的文件夹里新建一个文件叫GPtest.py。用你的文本编辑器打开它输入以下代码from fastapi import FastAPI appFastAPI() #Get app.get(/) def home(): return {message:Hi ai infra} app.get(/user/{user_id}) def get_user(user_id:int): return {user_id:user_id,name:ai infra student} #Post app.post(/login) def login(username:str,password:str): return {username:username,status:success}4.需要用uvicorn来运行uvicorn GPtest:app --reload5.可以http://127.0.0.1:8000/docs查看自动生成的交互式 API 文档。6.在交互式 API 文档中测试接口二、请求体、参数校验、响应模型代码演示Pydantic是一个 Python 数据验证库它的核心功能是定义数据模型数据结构自动类型转换比如把字符串123转成整数123数据校验检查字段是否缺失、类型是否正确、值是否在范围内与 JSON 无缝互转在 FastAPI 中Pydantic 被深度集成用于定义请求体Request Body的结构定义响应体Response Body的结构自动生成 API 文档Swagger UIfrom fastapi import FastAPI from pydantic import BaseModel appFastAPI() #请求体 class UserRequest(BaseModel): username:str password:str age:int #响应 class UserResponse(BaseModel): username:str age:int status:str #请求 app.post(/user,response_modelUserResponse) def create_user(user:UserRequest): return { username:user.username, age:user.age, status:created }通过装饰器app.post(/user)把create_user“挂载”到路径/user上告诉 FastAPI当收到 POST 请求到/user时执行这个函数。BaseModel说明1.定义数据结构class UserRequest(BaseModel): username: str password: str age: int声明了一个“数据蓝图”任何符合这个模型的数据必须包含username字符串、password字符串、age整数。2.自动类型转换如果客户端传来的age是字符串25Pydantic 会自动尝试转成整数25因为模型中标注为int。如果转换失败比如abc会抛出清晰的验证错误。3.自动数据验证必填字段username,password,age都没有默认值所以它们是必填的。如果请求体中缺少某个字段FastAPI 会自动返回 422 错误并指出哪个字段缺失。类型校验如果age传了字符串abc会返回错误value is not a valid integer。4.为 FastAPI 提供请求体解析依据当你写user: UserRequest时FastAPI 知道要从请求的JSON Body中读取数据并使用UserRequest模型来解析它。5. 自动生成 API 文档FastAPI 会读取UserRequest的结构在 Swagger UI/docs中自动生成请求体的 JSON 示例和字段说明让调用方一目了然。6.提供 IDE 智能提示因为user参数的类型是UserRequest你在函数内部写user.时IDE 会自动弹出username、password、age的选项极大减少拼写错误。三、文件上传、中间件3.1文件上传1.简单的文件上传接口的实现from fastapi import FastAPI,UploadFile,File import shutil appFastAPI() app.post(/upload) def upload(file:UploadFileFile(...)): with open(file.filename,wb) as f: shutil.copyfileobj(file.file,f) return {filename:file.filename,status:ok}shutilPython 标准库提供高级文件操作UploadFileFastAPI 提供的特殊类型用于处理上传的文件包含文件名、内容等元数据。File(...)指示 FastAPI 从请求的表单字段中读取文件数据...表示该字段为必填copyfileobj会分块读取并写入内存效率高。2.访问http://localhost:8000/docs使用 Swagger UI 手动上传测试接口:3.2中间件概念中间件是位于 Web 服务器和应用程序之间的一个“钩子”层。每个请求在到达路径函数之前以及响应离开路径函数之后都会经过中间件。可以利用中间件来添加通用的响应头记录日志处理跨域CORS压缩响应身份验证等CORSMiddleware是 FastAPI 提供的一个内置中间件专门用于处理CORS跨域资源共享问题。from fastapi.middleware.cors import CORSMiddlewareCORS是一种浏览器安全机制叫做“同源策略”。它限制网页只能请求相同源协议 域名 端口的 API。例如前端页面运行在http://localhost:3000后端 API 运行在http://localhost:8000这两个源的端口不同3000 vs 8000浏览器会认为它们是不同源。当前端 JavaScript 尝试用fetch或XMLHttpRequest调用后端 API 时浏览器会拦截该请求并在控制台报错CORS 机制允许服务器告诉浏览器“这个来源http://localhost:3000是被允许的请放行。” 服务器通过在响应头中添加特定字段如Access-Control-Allow-Origin来实现。CORSMiddleware的作用就是自动为所有响应添加这些 CORS 响应头从而让浏览器允许跨域请求。from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, # 允许 任意来源任何域名、IP、端口访问你的 API。 #allow_origins[*] 与 allow_credentialsTrue 一起使用时浏览器会拒绝携带凭证的请求规范禁止。如果要允许凭证必须指定具体的源 allow_origins[*], #允许前端请求携带 凭证如 Cookies、HTTP 认证、客户端证书。 allow_credentialsTrue, #允许 所有 HTTP 方法GET、POST、PUT、DELETE 等。 allow_methods[*], #允许 所有请求头例如 Content-Type, Authorization 等 allow_headers[*], )简化版的实际工作流程1.前端http://localhost:3000向你的后端http://localhost:8000发送一个 POST 请求。2.浏览器检测到跨源会先发送一个预检请求OPTIONS询问服务器是否允许实际请求。3.你的 FastAPI 应用收到 OPTIONS 请求CORSMiddleware捕获它并返回带有以下响应头的空响应Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: * Access-Control-Allow-Credentials: true4.浏览器看到这些头确认允许然后发送真正的 POST 请求。5.你的路径函数正常处理请求返回数据。CORSMiddleware也会在响应中添加Access-Control-Allow-Origin: *等头。6.浏览器收到响应后因为 CORS 头符合要求会把数据交给前端 JavaScript。四、统一返回格式def resp(code0, msgsuccess, dataNone): return {code: code, msg: msg, data: data}对比#不使用统一接口函数会让代码变得臃肿、混乱、难维护 # 接口 A return {user: Alice, age: 20} # 接口 B return {status: ok, data: {id: 1}} # 接口 C return {code: 200, message: success, result: [...]}五、全局异常处理from fastapi import HTTPException app.get(/error) def testErro(): raise HTTPException(status_code400,detail参数错误)