十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Quick Reference 速查:FastAPI 备忘清单实战指南——从参数校验、依赖注入到 Token 认证

Quick Reference 速查:FastAPI 备忘清单实战指南——从参数校验、依赖注入到 Token 认证 Quick Reference 速查FastAPI 备忘清单实战指南——从参数校验、依赖注入到 Token 认证【免费下载链接】reference面向开发者的技术速查清单Cheat Sheets集合整理常见技术、工具与开发流程帮助快速查阅关键信息提高开发效率。项目地址: https://gitcode.com/GitHub_Trending/referen/reference本文为 Quick Reference 技术速查仓库中 FastAPI 备忘清单 的深度扩写版本覆盖安装运行、路径/查询参数与校验、请求体、表单与文件上传、依赖项体系以及基于 Token 的认证与 HTTPS 配置等全部核心内容并补充了各参数取值、依赖缓存机制与运行前提的说明。读完后你可以直接复制其中的代码片段搭建一个带参数校验、依赖注入和 Token 认证的 FastAPI 应用。这份速查清单在仓库中的位置本仓库是一份面向中文开发者的技术速查清单Cheat Sheets集合各主题以docs/目录下的 Markdown 文件形式维护README.md首页通过卡片链接聚合所有速查表。FastAPI 属于 Python 技术栈条目同时出现在首页「正在建设中...」与「Python」两个分区中见 README.md 中指向docs/fastapi.md的链接。与 Python 生态相关的速查表还包括 Python 备忘清单、pip、uv 等FastAPI 的类型提示、切片操作等基础语法可以回溯到 Python 清单查阅。适用环境说明原文档标注的验证环境为 Python3.9.5与 FastAPI0.103.1因此文档中Union[str, None]的写法是面向 3.9 及更早版本保守书写的在 Python 3.10 中可等价使用str | None文档「声明元数据」一节即混用了str | None新式写法。入门安装、运行与最小程序安装 FastAPI完整开发环境一次装齐包含uvicorn、python-multipart等可选依赖$ pip install fastapi[all]生产部署时推荐分开安装避免带入开发期依赖$ pip install fastapi $ pip install uvicorn[standard]启动服务器FastAPI 本身不内置 HTTP 服务器通过 ASGI 服务器uvicorn运行$ uvicorn main:app --reloadmain:app的含义是「在main模块中找到名为app的应用对象」--reload表示代码变更后自动重载进程适合开发期使用。最小程序下面代码会直接启动 http 服务也可以使用uvicorn main:app --reloadfrom fastapi import FastAPI import uvicorn app FastAPI() # http://127.0.0.1:8000/ app.get(/) async def root(): return {message: Hello World} if __name__ __main__: uvicorn.run(appmain:app, reloadTrue)说明路由函数用async def声明FastAPI 会将其识别为异步处理函数适合 IO 密集型场景数据库、HTTP 下游调用函数返回的dict会被 FastAPI 序列化为 JSON 响应原文档中uvicorn.run(appmain:app, reloadTrue)的写法里app是uvicorn.run的第一个位置参数传字符串时会被当作「模块路径:对象名」解析。更规范的等价写法是uvicorn.run(main:app, reloadTrue)或者直接通过命令行uvicorn main:app --reload启动。路径参数URL 中的动态片段最基本的路径参数# http://127.0.0.1:8000/items/1 app.get(/items/{item_id}) async def read_item(item_id): return {item_id: item_id} # item_id自定义路径中{item_id}占位符的取值会按同名参数注入函数item_id这个名字可以自定义。多个路径参数# http://127.0.0.1:8000/items/1/2 app.get(/items/{item_id}/{user_id}) async def read_item(item_id, user_id): return {item_id: item_id, user_id: user_id}有类型的路径参数# http://127.0.0.1:8000/items/1 app.get(/items/{item_id}) async def read_item(item_id: int): return {item_id: item_id}声明item_id: int后FastAPI 基于标准 Python 类型提示做自动转换与校验访问/items/abc会得到 422 校验错误而不是把字符串带进业务逻辑。这是 FastAPI「类型提示即接口契约」的核心机制。文件路径参数路径片段默认不含斜杠/若参数本身是带/的文件路径需要在占位符上声明:path格式# http://127.0.0.1:8000/file//home/my/my.txt app.get(/file/{file_path:path}) async def read_item(file_path): return {file_path: file_path}查询参数URL 中的键值对带默认值的查询参数函数参数带默认值即被视为查询参数# http://127.0.0.1:8000/items/?skip0limit2 fake_items_db [{item_name: Foo}, {item_name: Bar}] app.get(/items/) async def read_item(skip: int 0, limit: int 10): return fake_items_db[skip: skip limit]可选查询参数# http://127.0.0.1:8000/items/1?qadmin from typing import Union app.get(/items/{item_id}) async def read_item(item_id: str, q: Union[str, None] None): if q: return {item_id: item_id, q: q} return {item_id: item_id}多路径多查询参数路径参数与查询参数可以在同一接口中混用# http://127.0.0.1:8000/users/1/items/2 # or # http://127.0.0.1:8000/users/1/items/2?qqueryshorttrue app.get(/users/{user_id}/items/{item_id}) async def read_user_item( user_id: int, item_id: str, q: Union[str, None] None, short: bool False ): item {item_id: item_id, owner_id: user_id} if q: item.update({q: q}) if not short: item.update( {description: 这是一个令人惊叹的项目有很长的描述} ) return item注意short: bool False查询参数shorttrue/shortfalse会被自动转换为 Python 布尔值。必需查询参数无默认值的参数即为必需参数请求中缺失时返回 422 错误# http://127.0.0.1:8000/items/123?needyyes app.get(/items/{item_id}) async def read_user_item(item_id: str, needy: str): item {item_id: item_id, needy: needy} return item请求体用 Pydantic 模型描述入参当接口接收 JSON 请求体时用 PydanticBaseModel定义结构字段默认值、可选性都由模型声明from pydantic import BaseModel from typing import Union class Item(BaseModel): name: str 小明 description: Union[str, None] None price: float tax: Union[float, None] None app.post(/items/) async def create_item(item: Item): print(item.name) return item字段语义name有默认值小明可省略description、tax为可选字段price无默认值是必填字段且必须是可解析为float的值。用curl调用该接口curl -X POST \ http://127.0.0.1:8000/items/ \ -H accept: application/json \ -H Content-Type: application/json \ -d { name: 小明, description: string, price: 0, tax: 0 }查询参数与字符串校验当参数需要额外约束长度、正则等时用Query显式声明元数据from fastapi import Query app.get(/items/) async def read_items( q: Union[str, None] Query(defaultNone, max_length50) ): results {items: [{item_id: Foo}, {item_id: Bar}]} if q: results.update({q: q}) return resultsQuery常用参数一览参数含义类型default默认值任意类型max_length最大长度intmin_length最小长度intpattern正则匹配stringalias别名参数URL 中实际使用的键名stringdeprecated标记为准备弃用的参数bool多个相同的查询参数URL 中出现多个同名的键值对如?qfooqbar声明列表类型即可收集为list# http://127.0.0.1:8000/items/?qfooqbar app.get(/items/) async def read_items( q: Union[List[str], None] Query(defaultNone) ): query_items {q: q} return query_items路径参数与数值校验Path的用法与Query基本相同可参考 FastAPI 官方文档中 path-params-numeric-validations 章节区别是约束作用于路径占位符而非查询键。使用新版写法时用Annotated把元数据与类型注解分离可读性更好from fastapi import FastAPI, Path, Query from typing_extensions import Annotated app.get(/items/{item_id}) async def read_items( item_id: Annotated[int, Path(title要获取的项目的 ID)], q: Annotated[str | None, Query(aliasitem-query)] None, ): results {item_id: item_id} if q: results.update({q: q}) return results这个例子同时演示了两件事路径参数item_id通过Path(title...)在自动生成的 API 文档中展示友好标题查询参数q通过Query(aliasitem-query)改变 URL 中的键名函数内仍用q接收。Path常用参数一览数值约束用于int/float类型参数参数含义类型...与Query相同的参数如default、title、alias、description等与Query具有一致的元数据能力...ge大于等于int/floatgt大于int/floatle小于等于int/floatlt小于int/floattitleAPI 文档中展示的标题string注原文档此处参数表中le出现两次、缺少「小于」一行上表已按ge/gt/le/lt四个完整的数值比较约束整理。其他参数Cookie 与 HeaderCookie与Header参数都具有Query的校验参数能力max_length、min_length等下面示例展示了如何用Annotated语法声明它们。Cookie 参数from fastapi import Cookie app.get(/items/) async def read_items( ads_id: Annotated[Union[str, None], Cookie()] None ): return {ads_id: ads_id}请求携带 Cookieads_idxxx时即可取值缺失时为None。Header 参数from fastapi import Header app.get(/items/) async def read_items( user_agent: Annotated[Union[str, None], Header()] None, items_id: Annotated[Union[int, None], Header(ge1)] None ): return {User-Agent: user_agent, items_id: items_id}两点说明Header()默认会将请求头名中的下划线映射为连字符即user_agent对应请求头User-AgentHeader(ge1)演示了 Header 参数同样支持数值校验约束这里保证items-id头取值不小于 1。表单数据Form 接收表单字段当接口接收的不是 JSON而是application/x-www-form-urlencoded表单字段时要使用Form。安装依赖$ pip install python-multipart前端 HTML 表单!DOCTYPE html html langen head meta charsetUTF-8 /head body form methodpost actionhttp://127.0.0.1:8000/login span账号/spaninput typetext nameusername br span密码/spaninput typepassword namepassword br input typesubmit value登录 /form /body /html表单字段名nameusername与后端Form参数名一一对应。后端 FastAPI 接收from fastapi import FastAPI, Form import uvicorn app FastAPI() app.post(/login/) async def login(username: str Form(), password: str Form()): return {username: username} if __name__ __main__: uvicorn.run(appmain:app, reloadTrue)username: str Form()中Form()作为默认值传入表示该参数从表单字段解析且为必填无业务默认值。文件上传UploadFile文件上传走multipart/form-data协议参数类型声明为UploadFile同样需要安装python-multipartfrom fastapi import FastAPI, UploadFile from fastapi.responses import HTMLResponse app.post(/uploadfile/) async def create_upload_file(file: UploadFile): print(file.file.read().decode()) return {filenames: file.filename, type: str(type(file.file))} app.get(/) async def main(): content body form action/uploadfile/ enctypemultipart/form-data methodpost input namefile typefile multiple input typesubmit /form /body return HTMLResponse(contentcontent)首页返回一个带enctypemultipart/form-data的上传表单提交后进入create_upload_file示例中直接读取文件字节内容并打印同时返回上传文件名与底层文件对象的类型。UploadFile 属性属性名含义返回filename文件名上传的文件名content_type内容类型MIME类型file文件SpooledTemporaryFile具有read、write方法UploadFile async 方法方法名含义write(data)把data写入文件read(size)按指定数量的字节读取文件内容seek(offset)移动至文件offsetint字节处的位置close()关闭文件SpooledTemporaryFile是内存/磁盘混合的临时文件实现小文件在内存中操作超过阈值后自动落盘因此大文件上传不会撑爆内存在async上下文中调用read等方法时FastAPI 会将其放到线程池执行避免阻塞事件循环。依赖项把重复逻辑抽成可注入单元依赖项使用场景共享业务逻辑复用相同的代码逻辑共享数据库连接实现安全、验证、角色权限等……创建依赖项from typing import Union from fastapi import Depends, FastAPI app FastAPI()read_items和read_users方法依赖common_parameters白话就是这两个接口都需要q、skip、limit三个查询参数async def common_parameters( q: Union[str, None] None, skip: int 0, limit: int 100 ): return {q: q, skip: skip, limit: limit} app.get(/items/) async def read_items( commons: dict Depends(common_parameters) ): return commons app.get(/users/) async def read_users( commons: dict Depends(common_parameters) ): return commons执行流程请求进入/items/或/users/时FastAPI 先解析q/skip/limit并调用common_parameters把其返回值注入路由函数的commons参数。后续给依赖加上鉴权、数据库会话等逻辑所有使用它的接口自动生效。类作为依赖项依赖不必是函数类也可以——FastAPI 会把路由函数的查询参数传给类的构造器from typing import Union from fastapi import Depends, FastAPI app FastAPI() fake_items_db [{item_name: Foo}, {item_name: Bar}] class CommonQueryParams: def __init__( self, q: Union[str, None] None, skip: int 0, limit: int 100 ): self.q q self.skip skip self.limit limitread_items接收一个commons参数类型是CommonQueryParamsCommonQueryParams接收的三个参数是调用 API 时从 URL 传入的app.get(/items/) async def read_items( commons: CommonQueryParams Depends(CommonQueryParams) ): response {} if commons.q: response.update({q: commons.q}) items fake_items_db[commons.skip : commons.skip commons.limit] response.update({items: items}) return response还可以简写当参数类型本身就是依赖类时Depends()不带参数也可以FastAPI 会自动使用该类型作为依赖app.get(/items/) async def read_items( # 这里的 Depends 没有传参FastAPI 会自动使用 CommonQueryParams commons: CommonQueryParams Depends() ): response {} if commons.q: response.update({q: commons.q}) items fake_items_db[commons.skip : commons.skip commons.limit] response.update({items: items}) return response类作为依赖的优势多参数聚合为对象、支持方法链式调用commons.xxx比一长串平铺参数更易维护。子依赖项依赖可以嵌套依赖项可以依赖其他依赖项只要不晕可以无数次套娃from typing import Union from fastapi import Cookie, Depends, FastAPI app FastAPI() def query_extractor(q: Union[str, None] None): return q def query_or_cookie_extractor( q: str Depends(query_extractor), last_query: Union[str, None] Cookie(defaultNone), ): if not q: return last_query return q # read_query函数依赖query_or_cookie_extractor函数 # query_or_cookie_extractor函数又依赖query_extractor函数 # 就是说依赖项可以依赖其他依赖项只要你不晕可以无数次套娃 app.get(/items/) async def read_query( query_or_default: str Depends(query_or_cookie_extractor) ): return {q_or_cookie: query_or_default}这段代码实现了一个典型的多来源取值策略优先取查询参数q查询参数缺失时回退到 Cookielast_query。调用链为read_query - query_or_cookie_extractor - query_extractor每一层都只关心自己的职责便于单独测试。不使用缓存use_cacheFalse同一请求中相同依赖默认只执行一次其余引用共享同一结果缓存。使用use_cache False参数可让每次Depends引用都重新执行——不用它的话value和value1是一样的def result_value(): value randint(1, 99) return value def get_value( value: int Depends(result_value, use_cacheFalse), value1: int Depends(result_value, use_cacheFalse) ): return value, value1 app.get(/value/) async def needy_dependency(value: tuple Depends(get_value)): return {value: value}从源码结构看这是 FastAPI 依赖求解机制中的一个开关请求处理时 FastAPI 构建依赖图并按节点求解默认以「节点」为单位缓存结果use_cacheFalse则强制每个引用点独立求解。典型用途是需要独立随机数、独立数据库会话如两个并行的读写会话等场景。全局依赖项在创建FastAPI实例时通过dependencies参数注册的依赖会作用于应用内所有路由from fastapi import Depends, FastAPI, Header, HTTPException async def verify_token(x_token: str Header()): if x_token ! fake-super-secret-token: raise HTTPException(status_code400, detailX-Token 标头无效) async def verify_key(x_key: str Header()): if x_key ! fake-super-secret-key: raise HTTPException(status_code400, detailX-Key 标头无效) return x_key全局依赖项很有用后面的安全性就可以使用全局依赖项app FastAPI( dependencies[Depends(verify_token), Depends(verify_key)] ) app.get(/items/) async def read_items(): return [{item: Portal Gun}, {item: Plumbus}] app.get(/users/) async def read_users(): return [{username: Rick}, {username: Morty}]以上配置意味着访问/items/、/users/或任何已注册路由前请求头必须同时携带X-Token: fake-super-secret-token与X-Key: fake-super-secret-key否则返回 400。适合做接口级开关、日志、限流、统一鉴权等横切逻辑依赖中抛出的HTTPException会被 FastAPI 统一转换为对应状态码的 JSON 错误响应。安全性基于 Token 的认证完整 Token 认证流程下面是一个可运行的最小 Bearer Token 认证示例。先导入所需组件from fastapi import FastAPI, Depends, HTTPException from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from pydantic import BaseModel app FastAPI()使用OAuth2PasswordBearer创建一个 token 依赖tokenUrl指明客户端应到哪个接口换取 tokenoauth2_scheme OAuth2PasswordBearer(tokenUrltoken)假设这是你的用户数据库实际项目中替换为数据库查询并务必使用真正的密码哈希fake_users_db { johndoe: { username: johndoe, full_name: John Doe, email: johndoeexample.com, hashed_password: fakehashedsecret, disabled: False, } }创建用户模型class User(BaseModel): username: str email: str full_name: str disabled: bool创建简单的认证辅助函数def fake_hash_password(password: str): return fakehashed password def get_user(db, username: str): if username in db: user_dict db[username] return User(**user_dict) def fake_decode_token(token: str): # 这个函数应该验证 token 并返回用户信息 # 这里我们只是简单地返回了用户名 return get_user(fake_users_db, token)创建依赖用于从请求中获取 token 并验证用户同时实现登录接口/token接收OAuth2PasswordRequestForm表单的username/password和受保护的/users/me接口async def get_current_user(token: str Depends(oauth2_scheme)): user fake_decode_token(token) if not user: raise HTTPException( status_code401, detailInvalid authentication credentials, headers{WWW-Authenticate: Bearer}, ) return user app.post(/token) async def login(form_data: OAuth2PasswordRequestForm Depends()): user get_user(fake_users_db, form_data.username) if not user or user.hashed_password ! fake_hash_password(form_data.password): raise HTTPException(status_code400, detailIncorrect username or password) return {access_token: user.username, token_type: bearer} app.get(/users/me) async def read_users_me(current_user: User Depends(get_current_user)): return current_user整个流程串起来是客户端向POST /token提交用户名密码表单OAuth2PasswordRequestForm负责解析username、password以及可选的scope校验通过后返回access_token示例中直接返回用户名生产环境应返回签名后的 JWT 或会话令牌客户端携带Authorization: Bearer token请求受保护接口oauth2_scheme从请求头中提取 token 并注入get_current_user验证失败时抛出 401 并附带WWW-Authenticate: Bearer响应头验证通过的用户对象注入read_users_me直接返回当前用户信息。这正是前文「全局依赖项」一节的进阶形态把Depends(get_current_user)挂到具体路由即可实现接口粒度的鉴权OAuth2PasswordBearer还会在自动生成的 API 文档中渲染出标准的「Authorize」授权按钮。HTTPS 和证书应用层代码不需要为 HTTPS 做任何特殊处理from fastapi import FastAPI app FastAPI() app.get(/https) async def read_https(): return {message: Hello, HTTPS!}TLS 终结由 ASGI 服务器承担。启动uvicorn时指定证书和私钥即可生产环境中应该使用真正的证书和私钥——可以从 Lets Encrypt 这类证书颁发机构获得免费证书或者使用 OpenSSL 生成自签名证书uvicorn main:app --host 0.0.0.0 --port 443 --ssl-keyfile /path/to/your/key.pem --ssl-certfile /path/to/your/cert.pem参数说明--host 0.0.0.0监听所有网卡--port 443使用 HTTPS 默认端口--ssl-keyfile指向私钥文件.pem--ssl-certfile指向证书文件。配置生效后FastAPI 应用即可通过https://访问从源码结构看FastAPI 本身未实现 TLS加密完全由 uvicorn 的ssl上下文处理因此也可以选择在 Nginx 等反向代理层终结 TLS 后再转发到 uvicorn。适用前提与延伸版本前提文中示例以 FastAPI0.103.1/ Python3.9.5为验证环境Union[str, None]写法兼容性最好Annotated新式元数据写法在 FastAPI 0.95 中已是主流推荐运行依赖所有代码都通过uvicorn启动Form与UploadFile功能额外依赖python-multipart自动文档文中每个接口的参数、默认值、校验约束都会被 FastAPI 自动收集生成 OpenAPI 文档与交互式调试页面这是「类型提示 元数据」写法的主要回报之一仓库内相关速查表Python 基础语法见 Python 备忘清单虚拟环境与包管理可查 pip、uv、conda完整清单原文本文全部代码与参数表均继承自 FastAPI 备忘清单如需在线排版样式可参考仓库的 Quick Reference 排版说明。【免费下载链接】reference面向开发者的技术速查清单Cheat Sheets集合整理常见技术、工具与开发流程帮助快速查阅关键信息提高开发效率。项目地址: https://gitcode.com/GitHub_Trending/referen/reference创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表