关于 FastAPI 路径参数,你知道多少?

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我!

文章目录

  • 一、前言
  • 二、路径参数定义
    • 2.1 路径参数作用
    • 2.2 路径参数的基本使用
      • 2.2.1 无类型的路径参数
      • 2.2.2有类型的路径参数
        • 2.2.2.1 为函数中的与路径参数同名的参数声明类型
        • 2.2.2.2 为路径参数申明类型
      • 2.2.3 路径参数顺序
    • 2.3路径参数高级用法
      • 2.3.1 Pydantic 模型(请求体)作为路径参数
      • 2.3.2 路径参数校验
      • 2.3.3 路径参数申明元数据
  • 三、总结


一、前言

FastAPI 最核心的之一就是路径参数,今天我们一篇彻底搞 FaST 懂路径参数

二、路径参数定义

路径操作装饰器中对应的值就是路径参数,比如:

from fastapi import FastAPI
app = FastAPI()@app.get("/hello/{name}")
def say_hello(name: str):return {"message": f"Hello {name}"}  if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

路径操作装饰器 @app.get("/hello/{name}") 中 name 就是路径参数,这里我们也把路径参数 name 的值作为参数 name 传递给了路径操作函数 say_hello,如果我们运行示例并访问 http://127.0.0.1:8001/hello/xiaoming,将会看到如下响应:

{"message":"Hello xiaoming"}

2.1 路径参数作用

路径参数在 FastAPI 中的主要作用是从 URL 路径中提取变量值,并将其传递给请求处理函数。并且提供了灵活的路由匹配和处理,还支持类型转换和验证,使你能够
构建强大和可靠的 API

2.2 路径参数的基本使用

2.2.1 无类型的路径参数

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}")def read_item(item_id):return {"item_id": item_id}if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

如果我们运行示例并访问 http://127.0.0.1:8001/items/xiaoming,将会看到如下响应:

{"item_id": "xiaoming"}

如果我们运行示例并访问 http://127.0.0.1:8001/items/11,将会看到如下响应:

{"item_id":"11"}

所以当路径参数是无类型时,FastAPI 会将其认为为 str 类型

2.2.2有类型的路径参数

2.2.2.1 为函数中的与路径参数同名的参数声明类型

比如申明函数中 item_id 为 int 类型

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}")def read_item(item_id:int):return {"item_id": item_id}if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

如果我们运行示例并访问 http://127.0.0.1:8001/items/11,将会看到如下响应:

{"item_id":11}

注意函数接收(并返回)的值为 11,是一个 Python int 值,而不是字符串 "11"
所以,FastAPI 通过上面的类型可以对参数进行类型转换。
如果我们运行示例并访问 http://127.0.0.1:8001/items/xiaoming,将会看到如下响应:

{"detail":[{"loc":["path","item_id"],"msg":"value is not a valid integer","type":"type_error.integer"}]
}

因为路径参数 item_id 传入的值为 "xiaoming",它不是一个 int
如果你提供的是 float 而非整数也会出现同样的错误,比如:http://127.0.0.1:8001/items/11.1
所以,通过同样的 Python 类型声明,FastAPI 提供了数据校验功能。并且清楚地指出了校验未通过的具体原因。在开发和调试 API 时,这非常有用。

2.2.2.2 为路径参数申明类型
from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id:int}")def read_item(item_id):return {"item_id": item_id}if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

如果我们运行示例并访问 http://127.0.0.1:8001/items/11,将会看到如下响应:

{"item_id":11}

如果我们运行示例并访问 http://127.0.0.1:8001/items/xiaoming,将会看到如下响应:

{"detail":"Not Found"}

上一篇文章中,我们讲过 @app.get("/items/{item_id:int}") 为 **路径操作装饰器,它的作用就是匹配 URL ,**而传给 FastAPI 的 URL 为 /items/xiaoming,它应该匹配 @app.get("/items/{item_id:str}") 或者 @app.get("/items/{item_id}"),但代码中并没有这两个地址,所以浏览器会返回 Not Found,而服务端也就是我们的 Code 打印出来的日志为
127.0.0.1:64512 - "GET /items/xiaoming HTTP/1.1" 404 Not Found
想要修复这个错误其实也很容易,我们再加一个 @app.get("/items/{item_id:str}") 路径操作装饰器即可

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id:int}")def read_item(item_id):return {"item_id": item_id}@app.get("/items/{item_id:str}")def read_item(item_id):return {"item_id": item_id}    if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

2.2.3 路径参数顺序

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}")def read_item(item_id):return {"item_id": item_id}@app.get("/items/{item_id:int}")def read_item(item_id):return {"item_id_int": item_id}    if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

如果我们运行示例并访问 http://127.0.0.1:8001/items/11,将会看到如下响应:

{"item_id":"11"}

如果我们运行示例并访问 http://127.0.0.1:8001/items/xiaoming,将会看到如下响应:

{"item_id":"xiaoming"}

会发现,不管怎么样都没有办法访问 @app.get("/items/{item_id:int}") 这个路径操作装饰器,除非将这两个装饰器调换一下位置。

2.3路径参数高级用法

2.3.1 Pydantic 模型(请求体)作为路径参数

在 FastAPI 中,使用 Pydantic 模型作为路径参数的优势主要体现在以下几个方面:

  1. 类型转换和验证:通过使用 Pydantic 模型作为路径参数,你可以指定参数的类型,并利用 Pydantic 的验证规则来确保传入的参数值符合预期的格式和约束。这可以防止无效的参数值传递到请求处理函数中,提高了数据的有效性和安全性。

  2. 自动生成文档和 OpenAPI 规范:FastAPI 使用 Pydantic 模型作为路径参数时,能够自动根据模型的定义生成路径参数的文档和 OpenAPI 规范。这样,你不仅可以确保文档与实际代码保持同步,还可以获得更详细和准确的文档信息,包括参数类型、验证规则和示例值等。

  3. 代码重用和可维护性:使用 Pydantic 模型作为路径参数可以提高代码的重用性和可维护性。你可以在多个路由中使用相同的模型作为路径参数,避免了重复定义和验证参数的过程。这样,如果需要更改参数的类型或验证规则,你只需要修改模型的定义,而不必在多个地方修改代码。

  4. 更清晰的代码结构:通过使用 Pydantic 模型作为路径参数,可以使代码结构更清晰和可读。模型的定义提供了一种统一的方式来描述和组织参数,使得代码更易于理解和维护。

以下是一个示例:

Server 端:

from fastapi import FastAPI
from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):item_id: intitem_name: str@app.put("/items/{item_id}")
def put_item(item_id:int,item_name:str):return {"item_id": item_id, "item_name":item_name}if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app", reload=True, port=8001)

Client端:

import requestsdata={"item_id":1,"item_name":"xiaoming"}respone=requests.put("http://127.0.0.1:8001/items/1",json=data)
print(respone.json())

respone的结果:

{'item_id': 1, 'item_name': 'xiaoming'}

在上述示例中,我们定义了一个 Item 模型作为路径参数,并且还定义了另一个 user_id 的普通路径参数。FastAPI 会自动将路径参数中的 user_id 值转换为整数,并将其传递给 put_item 函数的 user_id 参数。同时,它还会根据 Item 模型的定义,验证并转换路径参数中的 JSON 对象,并将其传递给 put_item 函数的 item 参数。

2.3.2 路径参数校验

因为是路径参数,所以需要使用 FastPAI 的 Path 模块来进行参数的校验

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}")
def read_item(item_id:int=Path(gt=0, le=100)):return {"item_id": item_id}if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

这个例子当中,我们限制了 item_id 取值范围为 [0,100]
如果我们运行示例并访问 http://127.0.0.1:8001/items/11,将会看到如下响应:

{"item_id":"11"}

访问 http://127.0.0.1:8001/items/101 ,将会看到如下响应:

{"detail":[{"loc":["path","item_id"],"msg":"ensure this value is less than or equal to 100","type":"value_error.number.not_le","ctx":{"limit_value":100}}]
}

类似操作还有很多,比如:

数字:
gt:大于
ge:大于等于
lt:小于
le:小于等于字符串:
min_length
max_length
pattern  正则表达式

如果使用 Pydantic 模型作为路径参数,也可以进行类似的校验,如:

class Item(BaseModel):name: strprice: float = Path(gt=0.1, le=100.2)

2.3.3 路径参数申明元数据

在 FastAPI 中,路径参数的元数据用于提供关于该参数的额外信息,例如描述、示例值、别名等。这些元数据可以通过在路径参数声明中使用参数关键字参数的方式进行设置。使用元数据可以提高代码的可读性和维护性。

FastAPI 使用元数据来生成自动化的文档,包括 API 文档和交互式 API 文档(Swagger UI 或 ReDoc)。元数据提供了关于路径参数的描述、示例值和其他信息,使生成的文档更加详细和准确。这样,用户可以在文档中了解到如何正确使用路径参数。

下面是一个示例,展示了在 FastAPI 中使用路径参数元数据的方式:

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}")
def read_item(item_id:int=Path(description="item的ID,规定其值大于0,小于等于100",gt=0, le=100)):return {"item_id": item_id}if __name__ == "__main__":import uvicornuvicorn.run("quickstart.demo:app",reload=True,port=8001)

这样的话,在跟上下游对接的过程中,如果还有人问你 item_id 是啥意思,直接甩一个链接 http://127.0.0.1:8001/docs 到他脸上,因为文档中有详细的信息,如:

三、总结

至此我们将跟路径参数相关的,包括路径参数的定义、作用、基本用法和高级用法,就介绍完了。抓紧应用到自己的工作中去吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769827.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React Developer Tools安装

问题描述 在react开发中,需要插件来帮助我们开发,例如: 方法 (可能需要魔法 进去后搜索: 点击下载即可

【Nebula笔记】基础操作

目录 一、预备~ 二、基础操作 (一) 图空间 1. 创建图空间 2. 清空图空间 3. 其他 4. FAQ 执行DROP SPACE语句删除图空间后,为什么磁盘的大小没变化? (二) 点类型 1. 创建Tag 2. 删除Tag 3. 更新Tag 4. 其他 (三) 边类型 1. 创建Edge type…

git如何在某个commitId的状态提交到一个分支

有些时候,我们在使用子仓库,或者其他情况,会有一个状态是当前的git仓库是在一个commitId上,而没有在一个分支上: 这时如果想要把基于这个commitId创建一个分支,可以使用下面这个命令: git push…

HCIA实验

实验目的: 1、R6为ISP,接口IP地址均为公有地址,该设备只能配置IP地址,之后不能再对其进行任何配置; 2、R1-R5为局域网,私有IP地址192.168.1.0/24,请合理分配; 3、R1、R2、R4&#x…

JUC-多线程

目录 进程 线程 线程的串行 区别 多线程 进程 是指计算机中已执行的程序,曾经是分时系统的基本运作单位在面向进程设计的系统(如早期的UNIX,Linux 2.4及更早的版本)中,是程序的基本执行实体在面向线程设计的系统…

【网络建设与运维】2024年河北省职业院校技能大赛中职组“网络建设与运维”赛项规程

培训、环境、资料、考证 公众号:Geek极安云科 网络安全群:775454947 网络系统管理群:223627079 网络建设与运维群:870959784 极安云科专注于技能提升,赋能 2024年广东省高校的技能提升,在培训中我们的应急…

OSCP靶场--Crane

OSCP靶场–Crane 考点(CVE-2022-23940sudo service提权) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.229.146 -sC -sV --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-25 08:07 EDT Nmap scan report for 192.16…

Java 算法和数据结构 答案整理,最新面试题

Java中如何使用动态规划求解背包问题? 1、定义子问题: 首先确定动态规划状态,通常以物品数量和背包容量为变量定义子问题,例如dp[i][j]表示前i件物品放入容量为j的背包所能获得的最大价值。 2、确定状态转移方程: 基…

手撕算法-盛最多水的容器

描述 分析 两个板之间能盛下的水的量,取决于短板。想让两个板之间能盛下更多的水,需要改变短板的长度。就像水桶效应:那么用两个指针指向容器的两个板,然后每次移动较短的板即可。移动较短的板,可能会增大容积&#x…

计算机网络常见题(持续更新中~)

1 描述一下HTTP和HTTPS的区别 2 Cookie和Session有什么区别 3 如果没有Cookie,Session还能进行身份验证吗? 4 BOI,NIO,AIO分别是什么 5 Netty的线程模型是怎么样的 6 Netty是什么?和Tomcat有什么区别,特点是什么? 7 TCP的三次…

解决 cv2.imread读取带中文路径图片问题

http://t.csdnimg.cn/i8CXn 1.问题: # 中草药数据集样本可视化展示 import cv2 import matplotlib.pyplot as plt %matplotlib inline plt.title("heshouwu") plt.imshow(cv2.imread(r"D:\home\aistudio\data1\archive\train\何首乌\heshouwu_0001.…

[C语言]结构体、位段、枚举常量、联合体

目录 结构体 结构体的使用方法 结构体所占用的大小 位段 位段的使用方法 位段所占用的大小 枚举常量 枚举常量的使用方法 枚举常量的优势 联合体 联合体的使用方法 结构体 结构体的使用方法 结构体是一些值的集合,我们可以定义一个结构体,里…

数据结构入门框架

博主b站入口:Uncertanity的个人空间 参考资料: 《大话数据结构》程杰 《数据结构C语言(第二版)》严蔚敏

为什么静态成员函数不能是虚函数

在面向对象编程中,静态成员函数和虚函数都是常见的概念,但它们之间存在着本质上的差异。由于其特性上的差异,静态成员函数不能声明为虚函数。下面我们来探讨一下为什么静态成员函数不能是虚函数。 我在网上查到最多的说法是静态函数没有this指…

【OpenModelica】1 OpenModelica项目架构

1 OpenModelica项目架构 文章目录 1 OpenModelica项目架构一、 架构总览图二、OpenModelica各部分作用 一、 架构总览图 OpenModelica 环境由几个相互连接的子系统组成,如图 1.1 所示。 其中包括: MDT Eclipse 插件图形模型编辑器/浏览器文本模型编辑器…

开始喜欢上了runnergo,JMeter out了?

RunnerGo是一款基于Go语言、国产自研的测试平台。它支持高并发、分布式性能测试。和JMeter不一样的是,它采用了B/S架构,更灵活、更方便。而且,除了API测试和性能测试,RunnerGo还加上了UI测试和项目管理等实用功能,让测…

代码随想录day30(2)回溯:组合(leetcode77)

题目要求:给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 思路:首先定义两个变量,一个存放符合条件的单一结果,另一个存放符合条件结果的集合,for循环用来横向遍历,递归用来纵…

C语言例4-6:格式字符d的使用例子

代码如下&#xff1a; //格式字符d的使用例子 #include<stdio.h> int main(void) {int num1123;long num2123456;printf("num1%d,num1%5d,num1%-5d,num1%2d\n",num1,num1,num1,num1);//以四种不同格式&#xff0c;输出int型数据num1的值printf("num2%ld,…

基于Spring Boot网络相册设计与实现

摘 要 网络相册设计与实现的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&am…

用BI来做金蝶的数据分析,真能随时自助分析?

BI数据分析快的事&#xff0c;大家都知道&#xff0c;那用BI来分析金蝶ERP上的数据也很快&#xff0c;也能随时想怎么分析就怎么分析&#xff0c;想分析哪些数据就分析哪些数据吗&#xff1f; 用BI分析金蝶数据&#xff0c;不仅可随时自助分析&#xff0c;还可极大提高分析效率…