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

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

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

一、前言

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

二、路径参数定义

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

py 复制代码
from fastapi import FastAPI
app = FastAPI()

@app.get("/hello/{name}")
def say_hello(name: str):
    return {"message": f"Hello {name}"}  

if __name__ == "__main__":
    import uvicorn
    uvicorn.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,将会看到如下响应:

json 复制代码
{"message":"Hello xiaoming"}

2.1 路径参数作用

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

2.2 路径参数的基本使用

2.2.1 无类型的路径参数

py 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
 def read_item(item_id):
    return {"item_id": item_id}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

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

json 复制代码
{"item_id": "xiaoming"}

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

json 复制代码
{"item_id":"11"}

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

2.2.2有类型的路径参数

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

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

py 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
 def read_item(item_id:int):
    return {"item_id": item_id}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

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

json 复制代码
{"item_id":11}

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

json 复制代码
{
  "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 为路径参数申明类型

py 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id:int}")
 def read_item(item_id):
    return {"item_id": item_id}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

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

json 复制代码
{"item_id":11}

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

json 复制代码
{"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}") 路径操作装饰器即可

py 复制代码
from fastapi import FastAPI

app = 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 uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

2.2.3 路径参数顺序

py 复制代码
from fastapi import FastAPI

app = 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 uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

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

json 复制代码
{"item_id":"11"}

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

json 复制代码
{"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 端:

py 复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    item_id: int
    item_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 uvicorn
    uvicorn.run("quickstart.demo:app", reload=True, port=8001)

Client端:

py 复制代码
import requests

data={"item_id":1,"item_name":"xiaoming"}

respone=requests.put("http://127.0.0.1:8001/items/1",json=data)
print(respone.json())

respone的结果:

json 复制代码
{'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 模块来进行参数的校验

py 复制代码
from fastapi import FastAPI

app = 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 uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

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

json 复制代码
{"item_id":"11"}

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

json 复制代码
{
  "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
      }
    }
  ]
}

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

perl 复制代码
数字:
gt:大于
ge:大于等于
lt:小于
le:小于等于

字符串:
min_length
max_length
pattern  正则表达式

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

py 复制代码
class Item(BaseModel):
    name: str
    price: float = Path(gt=0.1, le=100.2)

2.3.3 路径参数申明元数据

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

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

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

py 复制代码
from fastapi import FastAPI

app = 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 uvicorn
    uvicorn.run("quickstart.demo:app",reload=True,port=8001)

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

三、总结

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

相关推荐
万亿少女的梦1681 分钟前
基于Spring Boot的网络购物商城的设计与实现
java·spring boot·后端
Trouvaille ~5 分钟前
【机器学习】从流动到恒常,无穷中归一:积分的数学诗意
人工智能·python·机器学习·ai·数据分析·matplotlib·微积分
dundunmm13 分钟前
论文阅读:Deep Fusion Clustering Network With Reliable Structure Preservation
论文阅读·人工智能·数据挖掘·聚类·深度聚类·图聚类
szxinmai主板定制专家21 分钟前
【国产NI替代】基于FPGA的4通道电压 250M采样终端边缘计算采集板卡,主控支持龙芯/飞腾
人工智能·边缘计算
是十一月末21 分钟前
Opencv实现图像的腐蚀、膨胀及开、闭运算
人工智能·python·opencv·计算机视觉
云空29 分钟前
《探索PyTorch计算机视觉:原理、应用与实践》
人工智能·pytorch·python·深度学习·计算机视觉
杭杭爸爸30 分钟前
无人直播源码
人工智能·语音识别
dowhileprogramming40 分钟前
Python 中的迭代器
linux·数据库·python
开心工作室_kaic2 小时前
springboot485基于springboot的宠物健康顾问系统(论文+源码)_kaic
spring boot·后端·宠物
Ainnle2 小时前
微软 CEO 萨提亚・纳德拉:回顾过去十年,展望 AI 时代的战略布局
人工智能·microsoft