三周精通FastAPI:5 查询参数和字符串校验

FastAPI手册:https://fastapi.tiangolo.com/zh/tutorial/query-params-str-validations/

查询参数和字符串校验¶

FastAPI 允许你为参数声明额外的信息和校验。让我们以下面的应用程序为例:

from fastapi import FastAPIapp = FastAPI()@app.get("/items/")
async def read_items(q: str | None = None):results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}if q:results.update({"q": q})return results

查询参数 q 的类型为 str,默认值为 None,因此它是可选的。

使用python3.10或以上版本,存储文件为query.py,启动服务使用

uvicorn query:app --host 0.0.0.0 --reload

额外的校验¶

我们打算添加约束条件:即使 q 是可选的,但只要提供了该参数,则该参数值**不能超过50个字符的长度**。

导入 Query

为此,首先从 fastapi 导入 Query

from typing import Union
from fastapi import FastAPI, Query

使用 Query 作为默认值¶

现在,将 Query 用作查询参数的默认值,并将它的 max_length 参数设置为 50:

@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):

由于我们必须用 Query(default=None) 替换默认值 NoneQuery 的第一个参数同样也是用于定义默认值。所以:

q: Union[str, None] = Query(default=None)

...使得参数可选,等同于:

q: str = None

但是 Query 显式地将其声明为查询参数。然后,我们可以将更多的参数传递给 Query。在本例中,适用于字符串的 max_length 参数:

q: Union[str, None] = Query(default=None, max_length=50)

将会校验数据,在数据无效时展示清晰的错误信息,并在 OpenAPI 模式的*路径操作*中记录该参​​数。

添加更多校验¶

你还可以添加 min_length 参数:

    q: Union[str, None] = Query(default=None, min_length=3, max_length=50),

添加正则表达式¶

你可以定义一个参数值必须匹配的正则表达式:

        default=None, min_length=3, max_length=50, pattern="^fixedquery$"

这个指定的正则表达式通过以下规则检查接收到的参数值:

  • ^:以该符号之后的字符开头,符号之前没有字符。
  • fixedquery: 值精确地等于 fixedquery
  • $: 到此结束,在 fixedquery 之后没有更多字符。

如果你对所有的这些**「正则表达式」**概念感到迷茫,请不要担心。对于许多人来说这都是一个困难的主题。你仍然可以在无需正则表达式的情况下做很多事情。

但是,一旦你需要用到并去学习它们时,请了解你已经可以在 FastAPI 中直接使用它们。

默认值¶

你可以向 Query 的第一个参数传入 None 用作查询参数的默认值,以同样的方式你也可以传递其他默认值。假设你想要声明查询参数 q,使其 min_length 为 3,并且默认值为 fixedquery

async def read_items(q: str = Query(default="fixedquery", min_length=3)):

Note

具有默认值还会使该参数成为可选参数。

声明为必需参数¶

当我们不需要声明额外的校验或元数据时,只需不声明默认值就可以使 q 参数成为必需参数,例如:

q: str

代替:

q: Union[str, None] = None

但是现在我们正在用 Query 声明它,例如:

q: Union[str, None] = Query(default=None, min_length=3)

因此,当你在使用 Query 且需要声明一个值是必需的时,只需不声明默认参数:

async def read_items(q: str = Query(min_length=3)):

使用省略号(...)声明必需参数¶

有另一种方法可以显式的声明一个值是必需的,即将默认参数的默认值设为 ... :

async def read_items(q: str = Query(default=..., min_length=3)):

Info

如果你之前没见过 ... 这种用法:它是一个特殊的单独值,它是 Python 的一部分并且被称为「省略号」。 Pydantic 和 FastAPI 使用它来显式的声明需要一个值。

这将使 FastAPI 知道此查询参数是必需的。

使用None声明必需参数¶

你可以声明一个参数可以接收None值,但它仍然是必需的。这将强制客户端发送一个值,即使该值是None。为此,你可以声明None是一个有效的类型,并仍然使用default=...

async def read_items(q: Union[str, None] = Query(default=..., min_length=3)):

Tip

Pydantic 是 FastAPI 中所有数据验证和序列化的核心,当你在没有设默认值的情况下使用 Optional 或 Union[Something, None] 时,它具有特殊行为,你可以在 Pydantic 文档中阅读有关必需可选字段的更多信息。

查询参数列表 / 多个值¶

当你使用 Query 显式地定义查询参数时,你还可以声明它去接收一组值,或换句话来说,接收多个值。例如,要声明一个可在 URL 中出现多次的查询参数 q,你可以这样写:

async def read_items(q: Union[List[str], None] = Query(default=None)):

然后,输入如下网址:

http://localhost:8000/items/?q=foo&q=bar

你会在*路径操作函数*的*函数参数* q 中以一个 Python list 的形式接收到*查询参数* q 的多个值(foo 和 bar)。

因此,该 URL 的响应将会是:

{ "q": [ "foo", "bar" ] }

Tip

要声明类型为 list 的查询参数,如上例所示,你需要显式地使用 Query,否则该参数将被解释为请求体。

交互式 API 文档将会相应地进行更新,以允许使用多个值:

具有默认值的查询参数列表 / 多个值¶

你还可以定义在没有任何给定值时的默认 list 值:

async def read_items(q: List[str] = Query(default=["foo", "bar"])):

如果你访问:

http://localhost:8000/items/

q 的默认值将为:["foo", "bar"],你的响应会是:

{ "q": [ "foo", "bar" ] }

使用 list

你也可以直接使用 list 代替 List [str]

async def read_items(q: list = Query(default=[])):

Note

请记住,在这种情况下 FastAPI 将不会检查列表的内容。

例如,List[int] 将检查(并记录到文档)列表的内容必须是整数。但是单独的 list 不会。

声明更多元数据¶

你可以添加更多有关该参数的信息。

这些信息将包含在生成的 OpenAPI 模式中,并由文档用户界面和外部工具所使用。

Note

请记住,不同的工具对 OpenAPI 的支持程度可能不同。

其中一些可能不会展示所有已声明的额外信息,尽管在大多数情况下,缺少的这部分功能已经计划进行开发。

你可以添加 title

async def read_items(q: Union[str, None] = Query(default=None, title="Query string", min_length=3),
):

以及 description

async def read_items(q: Union[str, None] = Query(default=None,title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,),
):

别名参数¶

假设你想要查询参数为 item-query

像下面这样:

http://127.0.0.1:8000/items/?item-query=foobaritems 

但是 item-query 不是一个有效的 Python 变量名称。

最接近的有效名称是 item_query

但是你仍然要求它在 URL 中必须是 item-query...这时你可以用 alias 参数声明一个别名,该别名将用于在 URL 中查找查询参数值:

async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):

弃用参数¶

现在假设你不再喜欢此参数。

你不得不将其保留一段时间,因为有些客户端正在使用它,但你希望文档清楚地将其展示为已弃用。那么将参数 deprecated=True 传入 Query

@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None,alias="item-query",title="Query string",description="Query string for the items to search in the database that have a good match",min_length=3,max_length=50,pattern="^fixedquery$",deprecated=True,),
):

文档将会像下面这样展示它:

总结¶

你可以为查询参数声明额外的校验和元数据。

通用的校验和元数据:

  • alias
  • title
  • description
  • deprecated

特定于字符串的校验:

  • min_length
  • max_length
  • regex

在这些示例中,你了解了如何声明对 str 值的校验。

请参阅下一章节,以了解如何声明对其他类型例如数值的校验。

实践

写代码存盘为query.py

​
from fastapi import FastAPIapp = FastAPI()@app.get("/items/")
async def read_items(q: str | None = None):results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}if q:results.update({"q": q})return results​

启动服务器

uvicorn query:app --host 0.0.0.0 --reload

链接 :http://192.168.1.5:8000/items/?q=foo&q=qqq

输出:

{"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"qqq"}

 使用None声明必需参数

代码:

from typing import Unionfrom fastapi import FastAPI, Queryapp = FastAPI()@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=..., min_length=3)):results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}if q:results.update({"q": q})return results

链接:http://192.168.1.5:8000/items/?q=foo&q=bar

输出:

{"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"bar"}

 别名参数

代码:

from typing import Unionfrom fastapi import FastAPI, Queryapp = FastAPI()@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}if q:results.update({"q": q})return results

链接:http://192.168.1.5:8000/items/?item-query=foobaritems

输出:

{"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"foobaritems"}

 总结

到了这里,就感觉有那么一点吃力了。。。。继续努力!

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

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

相关文章

基于springboot+thymeleaf+springsecurity搭建一套web小案例

一、前言 本案例中的源代码已上传到资源库,可自行下载,传送阵 https://download.csdn.net/download/qq_36260963/89906196 Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的,使用它可以做到专注于Spring应用的开发&#x…

git clone 鉴权失败

git clone 鉴权失败问题 1. 问题描述2. 解决方法 1. 问题描述 使用git clone自己的代码报如下错误: 正克隆到 xxx... Username for https://github.com: Password for https://xxxgithub.com: remote: Support for password authentication was removed on Augu…

RAG流程的实现与改进

一、 RAG流程图 数据入库:读取本地数据并切成小块,并把这些小块经过编码embedding后,存储在一个向量数据库中(下图1——6步);相关性检索:用户提出问题,问题经过编码,再在…

Vue项目中实现拖拽上传附件:原生JS与Element UI组件方法对比

在现代化的Web应用中,文件上传是一个基本功能。随着技术的发展,拖拽上传已经成为提升用户体验的一个重要特性。在Vue项目中,我们可以通过原生JavaScript或使用Element UI组件来实现这一功能。下面我们将分别介绍这两种方法,并对比…

吴恩达深度学习笔记(6)

正交化 为了提高算法准确率,我们想到的方法 收集更多的训练数据增强样本多样性使用梯度下降将算法使算法训练时间更长换一种优化算法更复杂或者更简单的神经网络利用dropout 或者L2正则化改变网络框架更换激活函数改变隐藏单元个数 为了使有监督机制的学习系统良…

vue使用jquery的ajax,页面跳转

一、引入jquery依赖 打开终端更新npm npm install -g npm 更新完后引入输入npm install jquery 加载完后 在最外层的package.json文件中加入以下代码 配置好后导入jquery 设置变量用于接收服务器传输的数据 定义ajax申请数据 服务器的Controller层传输数据 (…

【VUE小型网站开发】初始环境搭建

1. 初始化VUE项目 1.1 创建vue项目 1.2 删除多余的界面 根据自己情况删除红框内的文件 清理app页面代码 1.3 引入vue-router 1.3.1 下载vue-router npm install vue-router1.3.2 配置vue-router 在 main.js 或 main.ts 中引入 vue-router import ./assets/main.css im…

Android 图片相识度比较(pHash)

概述 在 Android 中,要比对两张 Bitmap 图片的相似度,常见的方法有基于像素差异、直方图比较、或者使用一些更高级的算法如 SSIM(结构相似性)和感知哈希(pHash)。 1. 基于像素的差异比较 可以逐像素比较…

基于MATLAB车牌识别系统设计

MATLAB车牌识别系统设计 实践目的 车牌是一辆汽车独一无二的信息,因此,对车辆牌照的识别技术可以作为 辨识一辆车最为有效的方法。随着ITS(智能交通系统)的高速发展,对车牌识别技术的研究也随之发展。从根本上讲,牌照识别应用了…

中缀表达式转后缀表达式(逆波兰表达式)及如何计算后缀表达式

目录 中缀、后缀表达式简介 中缀转后缀的规则 模拟中缀转后缀 中缀转后缀代码 后缀表达式求值 后缀表达式求值代码 Leetcode相关题目 中缀、后缀表达式简介 首先说说什么是中缀表达式,中缀表达式中,操作符是以中缀形式处于操作数的中间。例如&…

Linux安装Anaconda和Pytorch

又到了一年一度换环境、换服务器不断折腾的时节了,一通折腾后,重新启动遂做记录。 1. Linux安装Anaconda 1.1 离线安装模式 进入官网https://www.anaconda.com/download/success,如图所示: 选择版本进行下载即可。 1.2 在线w…

[Linux网络编程]03-TCP协议

一.TCP协议数据通信的过程 TCP数据报如下,数据报中的标志位双端通信的关键。 三次握手: 1.客户端向服务端发送SYN标志位,请求建立连接,同时发送空包 2.服务端向客户端回发ACK标志位(即确认标志位,任何一端发送数据后都需要另一端…

【VUE】【IOS】【APP】IOS Music APP播放器开发

前言 周末闲来无事,学习了下移动端的一些知识。了解到移动端的一些实现方式,先从最简单的开始。本人没有IOS swift 和Android的开发经验。抱着学习态度从简单的入手,经过了解,本人之前自己用vue的写着玩了几个小项目。看到可以用…

《使用Gin框架构建分布式应用》阅读笔记:p101-p107

《用Gin框架构建分布式应用》学习第7天,p101-p107总结,总计7页。 一、技术总结 1.StatusBadRequest vs StatusInternalServerError 写代码的时候有一个问题,什么时候使用 StatusBadRequest(400错误),什么时候使用 StatusIntern…

1.2电子商务安全内涵

目录 1 电子商务安全的层次 2 计算机网络安全 3电子商务安全的特点 只有在你生命美丽的时候,世界才是美丽的。 —— 顾城 《顾城哲思录》 1 电子商务安全的层次 安全:主体没有危险的客观状态 电子商务安全是一个广泛的概念,它涉及到电子商务的各个方…

现今 CSS3 最强二维布局系统 Grid 网格布局

深入学习 CSS3 目前最强大的布局系统 Grid 网格布局 Grid 网格布局的基本认识 Grid 网格布局: Grid 布局是一个基于网格的二位布局系统,是目前 CSS 最强的布局系统,它可以同时对列和行进行处理(它将网页划分成一个个网格,可以任…

PHP函数$_FILES详解

PHP函数$_FILES详解 在PHP中上传一个文件建一个表单要比ASP中灵活得多。具体的看代码。 <form enctype"multipart/form-data" action"upload.php" method"post"> <input type"hidden" name"MAX_FILE_SIZE" value…

嵌入式入门学习——8基于Protues仿真Arduino+SSD1306液晶显示数字时钟

0 系列文章入口 嵌入式入门学习——0快速入门&#xff0c;Let‘s Do It&#xff01; SSD1306 1 Protues查找SSD1306器件并放置在画布&#xff0c;画好电气连接&#xff08;这里VCC和GND画反了&#xff0c;后面仿真出错我才看见&#xff0c;要是现实硬件估计就烧毁了&#xf…

【时时三省】(C语言基础)函数介绍strncat

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 strncat 打印结果是hello wor 跟strcat不同的是他后面可以加一个参数 这个参数就是它可以根据后面的数字 来追加多少个字符 这个如果后面的参数改成10的话 就是打印hello world 不会跟strn…

Appium环境搭建、Appium连接真机

文章目录 一、安装Android SDK二、安装Appium-desktop三、安装Appium Inspector 一、安装Android SDK 首先需要安装jdk&#xff0c;这里就不演示安装jdk的过程了 SDK下载地址&#xff1a;Android SDK 下载 1、点击 Android SDK 下载 -> SKD Tools 2、选择对应的版本进行下…