【5.0】Fastapi路径参数和数据的解析验证

发布时间 2023-10-01 15:35:31作者: Chimengmeng

【一】小项目构建

【1】文档结构树

projects                                              
    ├─coronavirus                                                 ├─__init__.py
    	├─....py
    ├─turtorial  
    	├─__init__.py
    	├─chapter03.py
    	├─chapter04.py
    	├─chapter05.py
    	├─chapter06.py
    	├─chapter07.py
    	├─chapter08.py
    ├─run.py

【2】同一项目下的多路由实现

  • projects\turtorial\chapter03.py
from fastapi import APIRouter

app03 = APIRouter()
  • 其他同理

  • projects\turtorial\__init__.py

from .chapter03 import app03
from .chapter04 import app04
from .chapter05 import app05
from .chapter06 import app06
from .chapter07 import app07
from .chapter08 import app08

【2】自定义启动入口

  • projects\run.py
from fastapi import FastAPI
import uvicorn
from turtorial import app03, app04, app05, app06, app07, app08

app = FastAPI()

# 将其他app添加到主路由下
# app03 : app名字
# prefix :自定义路由地址
# tags :自定义路由标题 (默认是default)

app.include_router(app03, prefix='/chapter03', tags=['第三章 请求参数和验证'])
app.include_router(app04, prefix='/chapter04', tags=['第四章 响应处理和FastAPI配置'])
app.include_router(app05, prefix='/chapter05', tags=['第五章 FastAPI的依赖注入系统'])
app.include_router(app06, prefix='/chapter06', tags=['第六章 安全、认证和授权'])
app.include_router(app07, prefix='/chapter07', tags=['第七章 FastAPI的数据库操作和多应用的目录结构设计'])
app.include_router(app08, prefix='/chapter08', tags=['第八章 中间件、CORS、后台任务、测试用例'])


def main():
    # run:app : 启动文件:app名字
    # host :IP
    # port : 端口
    # reload : 自动重启
    # debug :debug 模式
    # workers : 开启的进程数
    uvicorn.run('run:app', host='127.0.0.1', port=8000, reload=True, debug=True, workers=1)


if __name__ == '__main__':
    main()

【3】启动项目

  • 直接运行 run.py 即可启动项目
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28332] using statreload
INFO:     Started server process [7868]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

image-20230929154949515

【二】路径参数和数据的验证

【1】无参

from fastapi import APIRouter

app03 = APIRouter()


# 不带参数的验证
@app03.get('/path/parameters')
def path_params01():
    return {"message": 'This is a message!'}

【2】有参

from fastapi import APIRouter

app03 = APIRouter()


# 路径参数和数字验证

# 函数的顺序就是路由访问的顺序
@app03.get('/path/parameters')
def path_params01(parameters: str):
    return {"message": parameters}

【3】小提示

from fastapi import APIRouter

app03 = APIRouter()


# 路径参数和数字验证

# 不带参数的验证
@app03.get('/path/parameters')
def path_params01():
    return {"message": 'This is a message!'}


# 函数的顺序就是路由访问的顺序
@app03.get('/path/parameters')
def path_params01(parameters: str):
    return {"message": parameters}
  • 当我们的视图定义如上时
    • 我们访问第二个路由恰巧参数是 parameters 就会被第一个路由截获到
    • 因此 函数的顺序就是路由访问的顺序
    • 为了避免冲突,我们尽量提前定义好每一个路由相关的信息或者将我们想要的执行的视图尽量往上放

【三】枚举类型

【1】定义视图

from fastapi import APIRouter
from enum import Enum


app03 = APIRouter()

class CityName(str, Enum):
    Beijing = 'Beijing China'
    Shanghai = 'Shanghai China'


# 枚举类型参数
@app03.get('/enum/{city}')
async def lastest(city: CityName):
    if city == CityName.Beijing:
        return {'city_name': city, "confirmed": 1500, "death": 60}
    elif city == CityName.Shanghai:
        return {'city_name': city, "confirmed": 600, 'death': 88}
    else:
        return {'city_name': city, "confirmed": 'unknown'}

【2】发起请求

image-20230929160553344

【四】文件类型

【1】定义视图

from fastapi import APIRouter

app03 = APIRouter()


# 文件类型
# file_path:path : 当路径中 有 类似于 路由中的 / 时 ,会被解析成字符串类型
@app03.get('/files/{file_path:path}')
async def file_path(file_path: str):
    return f'The file path is {file_path}'

【2】发起请求

  • 如果不加 file_path:path

image-20230929161212669

  • 加了 file_path:path

image-20230929161152256

【五】路径参数(数字类型)验证

【1】定义视图

from fastapi import APIRouter, Path

app03 = APIRouter()

# 路径参数
# from fastapi import Path
# Path 类就是用来校验路径参数用的
@app03.get('/path_num/{num}')
async def path_params_validate(
        # num 必须是 int 类型 ,且 使用 Path 校验 ,必须大于等于1 小于等于10
        # title 给参数 添加标题
        # description : 给参数 添加描述
    	# None :可以使用 ...代替
        num: int = Path(None, title="Your number", description="校验的数字类型", ge=1, le=10)
):
    return num

【2】发起请求

image-20230929162000164

  • 携带不符合规则的参数
    • 爆红且无法请求

image-20230929162056820

  • 携带符合规则的参数
    • 请求正确

image-20230929162046517

【六】查询参数和数据的解析与验证

【1】定义视图

from typing import Optional
from fastapi import APIRouter, Path

app03 = APIRouter()

#####  查询参数和数据的解析与验证

# 模拟分页功能
@app03.get('/query')
# Optional 选填参数,默认 指定 为 None
async def page_limit(page: int = 1, limit: Optional[int] = None):
    if limit:
        return {"page": page, 'limit': limit}
    else:
        return {"page": page}


# 验证布尔类型自动转换
@app03.get('/query/bool/conversion')
async def type_conversion(param: bool = False):
    return param

【2】发起请求

  • 不指定数据,使用默认数据

image-20230929162911539

  • 指定数据,使用指定的数据

image-20230929162931735

  • 布尔类型转换测试

    • 表示真的情况

      • yes
      • on
      • true
      • TRUE
      • 1
      • ...

      image-20230929163115453

      image-20230929163134686

      image-20230929163148557

    • 表示否的情况

      • 0
      • No
      • NO
      • no
      • ...

      image-20230929163203831

    • 传入无法识别的布尔类型

      • 提示我们必须传入布尔类型

    image-20230929163225670

【七】路径参数(字符串类型)验证

【1】定义视图

from fastapi import APIRouter, Path, Query
from typing import List

app03 = APIRouter()

# 路径参数(字符串类型)验证
# 路径参数 --- 查询参数类型
# from fastapi import Query
# Path 类就是用来校验路径参数用的
@app03.get('/query/validations')
async def query_validations(
        # str 字符串类型
        # ... 必填参数
        # min_length 最小长度
        # max_length 最大长度
        # regex 正则表达式匹配 -- 必须以a开头
        value: str = Query(..., min_length=3, max_length=16, regex="^a"),
        # List 列表类型
        # default 默认值
        # alias 参数别名
        values: List[str] = Query(default=['v1', 'v2'], alias="alias_name")
):
    return value, values

【2】发起请求

image-20230929164045116

  • 携带数据访问成功

image-20230929164137646