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