Skip to content

Commit 7304ece

Browse files
committed
第三章 请求参数和验证
1 parent 0ca5d65 commit 7304ece

File tree

1 file changed

+155
-5
lines changed

1 file changed

+155
-5
lines changed

tutorial/chapter03.py

Lines changed: 155 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,162 @@
22
# -*- coding:utf-8 -*-
33
# __author__ = '__Jack__'
44

5-
from fastapi import APIRouter
5+
from datetime import date
6+
from enum import Enum
7+
from typing import Optional, List
8+
9+
from fastapi import APIRouter, Query, Path, Body, Cookie, Header
10+
from pydantic import BaseModel, Field
611

712
app03 = APIRouter()
813

14+
"""Path Parameters and Number Validations 路径参数和数字验证"""
15+
16+
17+
@app03.get("/path/parameters")
18+
def path_params01():
19+
return {"message": "This is a message"}
20+
21+
22+
@app03.get("/path/{parameters}") # 函数的顺序就是路由的顺序
23+
def path_prams02(parameters: str):
24+
return {"message": parameters}
25+
26+
27+
class CityName(str, Enum):
28+
Beijing = "Beijing China"
29+
Shanghai = "Shanghai China"
30+
31+
32+
@app03.get("/enum/{city}") # 枚举类型的参数
33+
async def latest(city: CityName):
34+
if city == CityName.Shanghai:
35+
return {"city_name": city, "confirmed": 1492, "death": 7}
36+
if city == CityName.Beijing:
37+
return {"city_name": city, "confirmed": 971, "death": 9}
38+
return {"city_name": city, "latest": "unknown"}
39+
40+
41+
@app03.get("/files/{file_path:path}") # 通过path parameters传递文件路径
42+
def filepath(file_path: str):
43+
return f"The file path is {file_path}"
44+
45+
46+
@app03.get("/path/{num}") # 长度+正则表达式验证,比如长度8-16位,以a开头。其它校验方法看Query类的源码
47+
def path_params_validate(
48+
num: int = Path(None, title="Your Number", description="不可描述", ge=1, le=10), # None换成...就变成必填的参数
49+
):
50+
return num
51+
52+
53+
"""Query Parameters and String Validations 查询参数和字符串验证"""
54+
55+
56+
@app03.get("/query")
57+
def page_limit(page: int = 1, limit: Optional[int] = None): # 给了默认值就是选填的参数,没给默认值就是必填参数
58+
if limit:
59+
return {"page": page, "limit": limit}
60+
return {"page": page}
61+
62+
63+
@app03.get("/query/bool/conversion") # bool类型转换:yes on 1 True true会转换成true, 其它为false
64+
def type_conversion(param: bool = False):
65+
return param
66+
67+
68+
@app03.get("/query/validations") # 长度+正则表达式验证,比如长度8-16位,以a开头。其它校验方法看Query类的源码
69+
def query_params_validate(
70+
value: str = Query(..., min_length=8, max_length=16, regex="^a"), # ...换成None就变成选填的参数
71+
values: List[str] = Query(["v1", "v2"], alias="alias_name")
72+
): # 多个查询参数的列表。参数别名
73+
return value, values
74+
75+
76+
"""Request Body and Fields 请求体和字段"""
77+
78+
79+
class CityInfo(BaseModel):
80+
name: str = Field(..., example="Beijing") # example是注解的作用,只不会被验证
81+
country: str
82+
country_code: str = None # 给一个默认值
83+
country_population: int = Field(default=0, title="人口数量", description="国家的人口数量", ge=800)
84+
85+
class Config:
86+
schema_extra = {
87+
"example": {
88+
"name": "Shanghai",
89+
"country": "China",
90+
"country_code": "CN",
91+
"country_population": 1400000000,
92+
}
93+
}
94+
95+
96+
@app03.post("/request_body/city")
97+
def city_info(city: CityInfo):
98+
print(city.name, city.country) # 当在IDE中输入city.的时候,属性会自动弹出
99+
return city.dict()
100+
101+
102+
"""Request Body + Path parameters + Query parameters 多参数混合"""
103+
104+
105+
@app03.put("/request_body/city/{name}")
106+
def mix_city_info(
107+
name: str,
108+
city01: CityInfo,
109+
city02: CityInfo, # Body可以是多个的
110+
confirmed: int = Query(ge=0, description="确诊数", default=0),
111+
death: int = Query(ge=0, description="死亡数", default=0),
112+
):
113+
if name == "Shanghai":
114+
return {"Shanghai": {"confirmed": confirmed, "death": death}}
115+
return city01.dict(), city02.dict()
116+
117+
118+
@app03.put("/request_body/multiple/parameters")
119+
def body_multiple_parameters(
120+
city: CityInfo = Body(..., embed=True), # 当只有一个Body参数的时候,embed=True表示请求体参数嵌套。多个Body参数默认就是嵌套的
121+
confirmed: int = Query(ge=0, description="确诊数", default=0),
122+
death: int = Query(ge=0, description="死亡数", default=0),
123+
):
124+
print(f"{city.name} 确诊数:{confirmed} 死亡数:{death}")
125+
return city.dict()
126+
127+
128+
"""Request Body - Nested Models 数据格式嵌套的请求体"""
129+
130+
131+
class Data(BaseModel):
132+
city: List[CityInfo] = None # 这里就是定义数据格式嵌套的请求体
133+
date: date # 额外的数据类型,还有uuid datetime bytes frozenset等,参考:https://fastapi.tiangolo.com/tutorial/extra-data-types/
134+
confirmed: int = Field(ge=0, description="确诊数", default=0)
135+
deaths: int = Field(ge=0, description="死亡数", default=0)
136+
recovered: int = Field(ge=0, description="痊愈数", default=0)
137+
138+
139+
@app03.put("/request_body/nested")
140+
def nested_models(data: Data):
141+
return data
142+
143+
144+
"""Cookie 参数"""
145+
146+
147+
@app03.get("/cookie") # 效果只能用Postman测试
148+
def cookie(cookie_id: Optional[str] = Cookie(None)): # 定义Cookie参数需要使用Cookie类,否则就是查询参数
149+
return {"cookie_id": cookie_id}
150+
151+
152+
"""Header 参数"""
153+
9154

10-
@app03.get("/")
11-
async def tutorial():
12-
"""This is a simple tutorial"""
13-
return {"message": {"This is another route"}}
155+
@app03.get("/header")
156+
def header(user_agent: Optional[str] = Header(None, convert_underscores=True), x_token: List[str] = Header(None)):
157+
"""
158+
有些HTTP代理和服务器是不允许在请求头中带有下划线的,所以Header提供convert_underscores属性让设置
159+
:param user_agent: convert_underscores=True 会把 user_agent 变成 user-agent
160+
:param x_token x_token是包含多个值的列表
161+
:return:
162+
"""
163+
return {"User-Agent": user_agent, "x_token": x_token}

0 commit comments

Comments
 (0)