news 2026/9/8 19:14:34

FastAPI 路径参数与数值校验(Path Parameters Numeric Validations)完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FastAPI 路径参数与数值校验(Path Parameters Numeric Validations)完整指南

FastAPI 路径参数与数值校验(Path Parameters & Numeric Validations)完整指南

【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi

本文基于 FastAPI 官方教程(本仓库 docs/hi/docs/tutorial/path-params-numeric-validations.md)整理而成。与 Query 参数类似,FastAPI 允许开发者通过Path路径参数声明同样的 metadata 与校验规则(包括gtgeltle四种数值约束),并结合Annotated优雅地规避 Python 默认参数顺序问题。读完本文,你将掌握如何为路径参数附加title、数值上下限约束,理解参数声明顺序的三种解决手段,以及这些声明最终如何映射到 Pydantic 校验与 OpenAPI 文档。

前置准备:导入PathAnnotated

想为路径参数声明校验与 metadata,第一步是像Query一样从fastapi导入Path,并同时导入typing中的Annotated

from typing import Annotated from fastapi import FastAPI, Path, Query app = FastAPI() @app.get("/items/{item_id}") async def read_items( item_id: Annotated[int, Path(title="The ID of the item to get")], q: Annotated[str | None, Query(alias="item-query")] = None, ): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial001_an_py310.py。

版本注意:FastAPI 自 0.95.0 起加入对Annotated的支持(并开始推荐使用)。若你的版本较旧,使用Annotated会遇到错误。请先参考 docs/hi/docs/deployment/versions.md 中 “Upgrading the FastAPI versions” 一节,将 FastAPI 至少升级到 0.95.1。

为路径参数声明 Metadata

与 Query 参数完全一样,你可以在Path()中传递title等 metadata 参数,为路径参数item_id声明人类可读的标题:

item_id: Annotated[int, Path(title="The ID of the item to get")]

title会出现在自动生成的 OpenAPI schema 中。从本仓库的测试断言可以看到,Path(title="The ID of the item to get")/openapi.json中对应参数 schema 的"title": "The ID of the item to get"(见 tests/test_tutorial/test_path_params_numeric_validations/test_tutorial004.py)。

注意:路径参数永远是必填的。路径参数本身就是 URL 路径的一部分,因此无论你将其声明为None,还是给它一个默认值,都不会改变其“必须出现在请求路径中”这一事实。教程 docs/hi/docs/tutorial/path-params-numeric-validations.md 中也明确强调:给路径参数设默认值是无效的,它始终是 required。这一点同样可以从源码中得到印证——fastapi/param_functions.py 中Pathdefaultdefault_factory参数在文档字符串中明确写着“This doesn't affectPathparameters as the value is always required”,它们仅为兼容性而保留。

按需调整参数的声明顺序

教程给出了一个值得注意的 Python 语法场景。假设你想把 query 参数q声明为必填的str——由于没有任何额外声明,你并不需要Query();但路径参数item_id又必须使用Path()才能附加校验与 metadata。

不推荐:默认值参数排在无默认值参数之前

如果坚持不使用Annotated,而写成下面的形式,Python 解释器会直接报错,因为 Python 不允许“有默认值的参数”位于“无默认值的参数”之前:

# 这会在函数定义阶段触发 Python 语法错误:non-default argument follows default argument async def read_items( item_id: int = Path(title="The ID of the item to get"), q: str, ):

方案一:调整顺序,把无默认值的q放在前面

对 FastAPI 来说,参数声明顺序并不重要——它会依据参数名、类型以及QueryPath等 default 声明来识别每个参数。因此你可以把没有默认值的q放在前面,把带有= Path(...)item_id放在后面:

from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items(q: str, item_id: int = Path(title="The ID of the item to get")): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial002_py310.py。

方案二(推荐):使用Annotated

一旦改用Annotated,校验信息不再占用函数参数的 default value 槽位,因此不存在“default 参数排在前面的问题”,顺序也就变得随意、自由:

from typing import Annotated from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items( q: str, item_id: Annotated[int, Path(title="The ID of the item to get")] ): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial002_an_py310.py。注意这里q在前、item_id在后,顺序刻意与上一个示例相反,但语义完全一致。

参数顺序小技巧:*关键字参数分隔符

教程还介绍了一个“小技巧”(通常不常用):当你想同时满足以下四个条件时——

  • q不加Query()也没有默认值;
  • item_id必须通过Path()声明;
  • 参数顺序需要任意摆放;
  • 不想用Annotated

——可以借 Python 的特殊语法:把*作为函数第一个参数传入。Python 不会对*本身做任何处理,但它宣告:其后所有参数都只能以关键字参数(keyword arguments,即 kwargs)方式传入,即使它们本身没有默认值:

from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items(*, item_id: int = Path(title="The ID of the item to get"), q: str): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial003_py310.py。

使用Annotated时则更简单

若使用Annotated,由于不占用函数参数默认值,你连*都不需要:

from typing import Annotated from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items( item_id: Annotated[int, Path(title="The ID of the item to get")], q: str ): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial003_an_py310.py。

数值校验:ge(greater than or equal)

Query一样,Path(以及后续教程中出现的其它参数声明类)也支持数值约束。例如ge=1表示item_id必须是“greater than orequal to 1”(大于或等于 1)的整数:

from typing import Annotated from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items( item_id: Annotated[int, Path(title="The ID of the item to get", ge=1)], q: str ): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial004_an_py310.py。

这一约束同时作用于校验层文档层

  • 校验层:请求/items/0?q=somequery时,路径参数0不满足ge=1,FastAPI 返回422,错误详情为"Input should be greater than or equal to 1",错误类型为greater_than_equalctx中携带{"ge": 1}(见 tests/test_tutorial/test_path_params_numeric_validations/test_tutorial004.py)。
  • 文档层:ge=1会渲染为 OpenAPI schema 中的"minimum": 1(见同文件 test_openapi_schema 的 snapshot 断言)。

数值校验:gtle

同样的机制适用于另外两个约束:

  • gtgreaterthan,严格大于;
  • leless than orequal,小于等于。

示例中gt=0, le=1000表示item_id必须大于 0 且小于等于 1000:

from typing import Annotated from fastapi import FastAPI, Path app = FastAPI() @app.get("/items/{item_id}") async def read_items( item_id: Annotated[int, Path(title="The ID of the item to get", gt=0, le=1000)], q: str, ): results = {"item_id": item_id} if q: results.update({"q": q}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial005_an_py310.py。

数值校验作用于浮点数:gtlt

数值校验同样适用于float值。也正是此时,能够声明严格大于gt(而不仅是大于等于ge)才显得重要:例如我们可以要求某个值大于0,即便它小于1也是合法的。

看下面这个综合示例——路径参数item_id使用ge=0, le=1000,query 参数size使用Query(gt=0, lt=10.5)

from typing import Annotated from fastapi import FastAPI, Path, Query app = FastAPI() @app.get("/items/{item_id}") async def read_items( *, item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)], q: str, size: Annotated[float, Query(gt=0, lt=10.5)], ): results = {"item_id": item_id} if q: results.update({"q": q}) if size: results.update({"size": size}) return results

完整源码见 docs_src/path_params_numeric_validations/tutorial006_an_py310.py。

对浮点数而言:

  • 0.5是合法值(大于 0 且小于 10.5);
  • 0.00非法,因为不满足严格的gt=0
  • 反过来lt同理:10.5本身非法,因为它要求严格小于 10.5。

这些边界行为在仓库测试中都有精确断言(见 tests/test_tutorial/test_path_params_numeric_validations/test_tutorial006.py):

请求校验结果错误类型
/items/-1?q=somequery&size=5item_id小于ge=0greater_than_equal,消息 "Input should be greater than or equal to 0"
/items/1001?q=somequery&size=5item_id大于le=1000less_than_equal,消息 "Input should be less than or equal to 1000"
/items/1?q=somequery&size=0.0size不满足gt=0greater_than,消息 "Input should be greater than 0"
/items/1?q=somequery&size=10.5size不满足lt=10.5less_than,消息 "Input should be less than 10.5"

而在 OpenAPI 文档侧(同样由该文件的test_openapi_schema快照断言):

  • ge=0"minimum": 0le=1000"maximum": 1000
  • gt=0"exclusiveMinimum": 0lt=10.5"exclusiveMaximum": 10.5
  • size对应的 schema 类型是"number"(浮点数)。

参数声明的统一家族:QueryPathParam

教程的 Recap 与“技术细节”两个小结串起了整套设计,值得展开说明:

QueryPath以及后续章节出现的其它参数类,都是同一个公共Param类的子类(见 docs/hi/docs/tutorial/path-params-numeric-validations.md 的 note)。因此它们共享同一套用于附加校验与 metadata 的参数。在本仓库中,这一设计在源码中清晰可见:fastapi/params.py 中的Param类统一接收并持有gtgeltlemin_lengthmax_lengthpatterntitleexamples等全部参数,并通过 FieldInfo 下传给 Pydantic 用于校验与 schema 生成。也就是说,你在Path上学到的全部约束能力,都可以原样复用到QueryHeaderCookie等场景。

QueryPathfastapi导入时,本质上不是类而是函数。当你调用它们时,返回的是与函数同名的类的实例——例如导入的是名为Query的 function,调用Query(...)后得到的是Queryclass 的 instance。之所以用函数而不是直接暴露类,是为了避免编辑器/类型检查器因为Query等类需要类型参数(泛型)而在你的代码上标注类型错误,让你无需添加额外的类型忽略配置,就能在常规编辑器与工具链中顺畅工作。这一点在 fastapi/param_functions.py 中有直接体现:def Path(...)(第 13 行)与def Query(...)(第 357 行)都是大写命名的函数定义,其中gtgeltle均被声明为可选的float | None参数。

小结:四种数值约束速查

参数含义OpenAPI 映射Pydantic 校验
gtgreaterthan(大于)exclusiveMinimumgreater_than
gegreater than orequal(大于等于)minimumgreater_than_equal
ltlessthan(小于)exclusiveMaximumless_than
leless than orequal(小于等于)maximumless_than_equal

字符串类校验(如min_lengthmax_lengthpattern)与 metadata(如titledescription)的声明方式,则与 Query 参数与字符串校验 完全一致,可互为参照。

进一步阅读

  • 全部本教程源码示例:docs_src/path_params_numeric_validations/
  • Param类的统一参数定义:fastapi/params.py
  • PathQuery函数的完整签名:fastapi/param_functions.py
  • 仓库回归测试(含边界值与 OpenAPI schema 断言):tests/test_tutorial/test_path_params_numeric_validations/

【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 19:13:43

乐学平台数据结构考题精讲:约瑟夫问题、验证表、循环小数与BFS

简介:北理工大二数据结构课程乐学在线评测平台编程题的完整C实现合集,共29个cpp源码文件,压缩包大小仅25KB,覆盖线性表、栈与队列、树与二叉树、图、查找与排序等数据结构核心内容,适合正在修读该课程或准备期末机考的…

作者头像 李华
网站建设 2026/9/8 19:12:48

AI Infra实战11:模型部署Pipeline——CI/CD自动化

AI Infra实战11:模型部署Pipeline,CI/CD自动化 本篇目标 设计完整的模型发布Pipeline:从模型训练完成到线上服务更新的全自动化流程。 学完本篇你将掌握: 模型CI/CD vs 代码CI/CD的核心差异完整的模型发布Pipeline设计模型质量门禁灰度发布…

作者头像 李华
网站建设 2026/9/8 19:07:59

thinkphp6搭配elementui搭建可商用二开商城系统的工程实践

简介:SparkShop(星火商城)是一套基于 ThinkPHP6 和 ElementUI 构建的开源免费可商用商城系统,适合有 PHP 开发基础、需要快速搭建多端商城或进行二次开发的团队与个人。资源包含 2000 个文件,核心为 899 个 PHP 业务代…

作者头像 李华
网站建设 2026/9/8 19:07:10

IRWOZ 2.0:LLM驱动的工业机器人对话数据集全解析

1. 为什么需要IRWOZ 2.0这样的工业对话数据集1.1 工业机器人交互的现状与痛点干过工业机器人项目的人应该都有同感:现场调试机器人,最耗时间的往往不是运动轨迹规划,也不是传感器标定,而是跟示教器较劲。市面主流品牌的示教器&…

作者头像 李华