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

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 与校验规则包括gt、ge、lt、le四种数值约束并结合Annotated优雅地规避 Python 默认参数顺序问题。读完本文你将掌握如何为路径参数附加title、数值上下限约束理解参数声明顺序的三种解决手段以及这些声明最终如何映射到 Pydantic 校验与 OpenAPI 文档。前置准备导入Path与Annotated想为路径参数声明校验与 metadata第一步是像Query一样从fastapi导入Path并同时导入typing中的Annotatedfrom 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(titleThe ID of the item to get)], q: Annotated[str | None, Query(aliasitem-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(titleThe ID of the item to get)]该title会出现在自动生成的 OpenAPI schema 中。从本仓库的测试断言可以看到Path(titleThe 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 中Path的default与default_factory参数在文档字符串中明确写着“This doesnt 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(titleThe ID of the item to get), q: str, ):方案一调整顺序把无默认值的q放在前面对 FastAPI 来说参数声明顺序并不重要——它会依据参数名、类型以及Query、Path等 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(titleThe 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(titleThe 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(titleThe 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(titleThe 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。数值校验gegreater than or equal与Query一样Path以及后续教程中出现的其它参数声明类也支持数值约束。例如ge1表示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(titleThe ID of the item to get, ge1)], 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?qsomequery时路径参数0不满足ge1FastAPI 返回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。文档层ge1会渲染为 OpenAPI schema 中的minimum: 1见同文件 test_openapi_schema 的 snapshot 断言。数值校验gt与le同样的机制适用于另外两个约束gtgreaterthan严格大于leless than orequal小于等于。示例中gt0, le1000表示item_id必须大于 0 且小于等于 1000from typing import Annotated from fastapi import FastAPI, Path app FastAPI() app.get(/items/{item_id}) async def read_items( item_id: Annotated[int, Path(titleThe ID of the item to get, gt0, le1000)], 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。数值校验作用于浮点数gt与lt数值校验同样适用于float值。也正是此时能够声明严格大于gt而不仅是大于等于ge才显得重要例如我们可以要求某个值大于0即便它小于1也是合法的。看下面这个综合示例——路径参数item_id使用ge0, le1000query 参数size使用Query(gt0, lt10.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(titleThe ID of the item to get, ge0, le1000)], q: str, size: Annotated[float, Query(gt0, lt10.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.50.0或0非法因为不满足严格的gt0反过来lt同理10.5本身非法因为它要求严格小于 10.5。这些边界行为在仓库测试中都有精确断言见 tests/test_tutorial/test_path_params_numeric_validations/test_tutorial006.py请求校验结果错误类型/items/-1?qsomequerysize5item_id小于ge0greater_than_equal消息 Input should be greater than or equal to 0/items/1001?qsomequerysize5item_id大于le1000less_than_equal消息 Input should be less than or equal to 1000/items/1?qsomequerysize0.0size不满足gt0greater_than消息 Input should be greater than 0/items/1?qsomequerysize10.5size不满足lt10.5less_than消息 Input should be less than 10.5而在 OpenAPI 文档侧同样由该文件的test_openapi_schema快照断言ge0→minimum: 0le1000→maximum: 1000gt0→exclusiveMinimum: 0lt10.5→exclusiveMaximum: 10.5size对应的 schema 类型是number浮点数。参数声明的统一家族Query、Path与Param教程的 Recap 与“技术细节”两个小结串起了整套设计值得展开说明Query、Path以及后续章节出现的其它参数类都是同一个公共Param类的子类见 docs/hi/docs/tutorial/path-params-numeric-validations.md 的 note。因此它们共享同一套用于附加校验与 metadata 的参数。在本仓库中这一设计在源码中清晰可见fastapi/params.py 中的Param类统一接收并持有gt、ge、lt、le、min_length、max_length、pattern、title、examples等全部参数并通过 FieldInfo 下传给 Pydantic 用于校验与 schema 生成。也就是说你在Path上学到的全部约束能力都可以原样复用到Query、Header、Cookie等场景。Query、Path从fastapi导入时本质上不是类而是函数。当你调用它们时返回的是与函数同名的类的实例——例如导入的是名为Query的 function调用Query(...)后得到的是Queryclass 的 instance。之所以用函数而不是直接暴露类是为了避免编辑器/类型检查器因为Query等类需要类型参数泛型而在你的代码上标注类型错误让你无需添加额外的类型忽略配置就能在常规编辑器与工具链中顺畅工作。这一点在 fastapi/param_functions.py 中有直接体现def Path(...)第 13 行与def Query(...)第 357 行都是大写命名的函数定义其中gt、ge、lt、le均被声明为可选的float | None参数。小结四种数值约束速查参数含义OpenAPI 映射Pydantic 校验gtgreaterthan大于exclusiveMinimumgreater_thangegreater than orequal大于等于minimumgreater_than_equalltlessthan小于exclusiveMaximumless_thanleless than orequal小于等于maximumless_than_equal字符串类校验如min_length、max_length、pattern与 metadata如title、description的声明方式则与 Query 参数与字符串校验 完全一致可互为参照。进一步阅读全部本教程源码示例docs_src/path_params_numeric_validations/Param类的统一参数定义fastapi/params.pyPath、Query函数的完整签名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),仅供参考