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

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

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 集成 DeepSeek 示例_python 集成开发工具

DeepSeek 简介DeepSeek 由知名量化资管巨头幻言方量化创立于2023年7月17日,全称杭州深度求索人工智能基础技术研究有限公司。长久以来专注于开发先进的大语言模型(LLM)和相关技术。D...

(完结篇)简析一个比Flask和Tornado更高性能的API 框架FastAPI

0前言 前几天给大家分别分享了(入门篇)简析Python web框架FastAPI——一个比Flask和Tornada更高性能的API 框架和(进阶篇)Python web框架FastAPI——一个比...

python之requests介绍和案例_python怎么安装requests库

requests功能: 用于发送 HTTP 请求,适合与 REST API 交互。实际案例:调用 API 获取数据: 从监控系统 API 获取服务器状态。import requestsdef get_...

用Python调用OpenAI API做有趣的事

GPT模型GPT模型:生成式预训练模型(Generative Pre-Training)总体结构:无监督的预训练有监督的下游任务精调核心结构:中间部分主要由12个Transformer Decoder...

Python调用ChatGPT最新GPT-3.5-turbo模型详细方法

一、ChatGPT官方文档介绍:messages中的centent就是我们要提问的问题,可以看到chatgpt已经支持基于上一个问题进行提问了ChatGPT API---0.002美元,1000个to...