[Python] FastAPI基础:Query查询参数用法全面解析与实例

liftword3个月前 (02-09)技术文章26

1. HTTP 请求格式

在开始写 Restful API 前,先简单的了解一下常规 HTTP 请求的格式,以便后续遇到问题知道从哪里排查,各部分的含义。下面是一个常规的 POST 请求的例子,各部分含义也都做了说明:

POST /api/data HTTP/1.1 # Request Line 请求行:包括请求方法 Method,请求 URI 和协议版本
Host: example.com       # 请求头 - 请求的主机名
Content-Type: application/json     # 请求头 - 请求体的数据类型
Authorization: Bearer abc123abc456 # 请求头 - 认证信息
Content-Length: 38      # 请求头 - 请求体的字节长度,帮助服务器正确解析主体内容
                              # 空行,分隔请求头和请求体
{"username": "John Doe", "gender": "male"} # 请求体


2. FastAPI 常见的路由函数请求参数类型

FastAPI 路由函数请求参数类型多种多样,常见的参数类型有:

  • query 查询参数
  • path 路径参数
  • 请求头 header 参数
  • 请求体 body 参数

对于这些不同的参数,FastAPI 框架整合了 pydantic 库进行统一的参数绑定和自动解析,下图是对应的源代码和类关系示意图。

FastAPI fastapi/param_functions 中对 pydantic 库提供的 PathQueryBodyCookie 等类进行进一步的封装,可以很方便的使用它们完成请求参数的获取和解析,下面是 FastAPI 框架对 Query 类封装的源代码截图。


3. Query 查询参数

接下来开始本节的主体内容,介绍 Query 查询参数的使用。查询参数,直观的例子为:

http://127.0.0.1:8000/queryUserInfo?user_id=111&user_name=zhangsan&token=test_token

其中“?”后面跟着的这一串就是 HTTP 请求的 Query 参数。对应到 FastAPI,则是相应的路由函数的参数,并且这些查询参数无需其它修饰,直接在路由函数参数列表中添加即可,如下面的 user_id 就是一个查询参数。

async def query_user_info(user_id: int):
  • 可选查询参数:查询参数可以是必填的或是可选的,可选通过 Optional 设置
  • bool 查询参数:FastAPI 框架会对 bool 型参数自动转换
  • list 查询参数:实现参数的多值查询
  • 查询参数条件校验


3.1. 可选查询参数

查询参数可以是必填的或是可选的,可以通过 Optional 来设置参数是否可选,默认是必填的。举例如下:

from typing import Optional
from fastapi import FastAPI

# 实例化 FastAPI,代表当前服务进程
app = FastAPI()

# 通过 @app.get 装饰器创建一个 API 端点路由
# 查询参数:查询参数可以是必填的,也可以是可选的,可选通过 Optional 设置
# user_id 必填,如果没有,则会抛出请求参数校验异常错误
# user_name 可选,没有也不会抛参数校验异常,Optional[str] = None 表示参数要么是 str 类型的值,要么是 None
# token 带默认值,没有给值时,默认是 test_token
@app.get("/queryUserInfo", summary='获取用户信息')
async def query_user_info(user_id: int,
                          user_name: Optional[str] = None,
                          token: str = 'test_token'):
    return {
        "user_id": user_id,
        "user_name": user_name,
        "token": token
    }

Swagger-UI 交互式接口文档效果如下:

接口调用效果如下:可以看到,没有提供 user_id 是会报错。

下面截图可以更加明显的看清这种错误:


3.2. bool 类型的查询参数

FastAPI 框架会对 bool 型的参数进行自动转换,把它们转化成 true/false。对于布尔类型的查询参数的值,可以是:true/false, 1/0, on/off,这些值都会被转换成 true/false,而其它值则会导致抛出参数校验异常。示例如下:

@app.get("/queryUser", summary='按性别查询用户')
async def query_user(is_man: bool):
    return {
        "is_man": is_man
    }

运行效果如下:


3.3. list 查询参数

有时需要查询多个不同的值(多值查询,即对同一个变量同时传递多个不同的值),请求类似这样:

GET /queryGroup?group_name=group1&group_name=group6&group_name=group8 

对于这样的查询请求,只需使用 list 类型的参数就可以实现。举例如下:

# List[str] = Query(["dev-team", "test-team"]) 指定参数为 list 类型,并设置了默认参数
@app.get("/queryGroup", summary='查询指定的组')
async def query_group(group_name: List[str] = Query(["dev-team", "test-team"])):
    return {
        "groups": group_name
    }

运行效果如下:


3.4. 查询参数的条件校验

从源代码上可以看出 FastAPI 提供的 Query 封装,支持多种校验方式,如下图:

下面是一个简单的例子:

@app.get("/queryLimit", summary='参数条件限制')
async def query_limit(user_id: int = Query(..., gt=100, lt=200, title='用户ID', description='用户的唯一编码'),
                      user_name: str = Query(None, min_length=3, max_length=50, regex="^e"),
                      group_name: str = Query('dev-team', max_length=10)):
    return {
        'user_id': user_id,
        'user_name': user_name,
        'group_name': group_name
    }
  • gt, lt 和其它编程语言类似,都表示 大于、小于
  • min_length, max_length 英文字面意思,校验文本长度
  • regex="^e" 正则表达式,表示以 e 开头

Swagger-UI 交互式接口文档效果如下:

接口调用效果如下:

实际项目中一般很少使用 Query 查询参数,容易被枚举数据。

相关文章

通过Python调用deepseek的API进行对话

import requests import json # DeepSeek 模型的 API 端点 API_URL = "https://api.deepseek.com/v1/chat/compl...

Python调用免费翻译API实现Excel文件批量翻译

工作中用到翻译软件是再正常不过的事情了,一般浏览外文网站翻译直接用谷歌插件还好解决。如果有一个Excel文件,里面有上万条需要翻译的内容,不能使用百度或Google免费的文档功能,需要怎么解决呢?总不...

使用python调用文心一言API,实现批量提问

在使用文心一言网页版时,一般都是输入一个提问,文心给出该提问的结果。但是,有时候我们需要批量向文心进行提问,而且这些提问的性质都是一样的,那么如何实现这个需求呢?一、提出问题例如:有一个表格,1000...

Python调用Docker API的使用方式_python控制docker

Docker是目前最流行的容器化技术之一,它提供了一种轻量级和快速的方式来构建、打包和部署应用程序。Python是一种非常流行的编程语言,可以与Docker API一起使用,以便更好地管理和定制Doc...

使用Python调用ChatGPT API_python调用api函数

当前ChatGPT使用gpt-3.5和gpt-4等语言大模型,提供了强大的文本交互功能。用户也可以使用gpt-3.5或gpt-4提供的API接口构建自己的应用。本文简单的介绍一下使用Python调用C...

PySpark和SparkSQL基础:如何利用Python编程执行Spark(附代码)

作者:Pinar Ersoy翻译:孙韬淳校对:陈振东本文约2500字,建议阅读10分钟本文通过介绍Apache Spark在Python中的应用来讲解如何利用PySpark包执行常用函数来进行数据处理...