Skip to content

Commit a2be0fa

Browse files
authored
doc: update docs/fastapi.md (#423)
1 parent b3e8be6 commit a2be0fa

File tree

1 file changed

+182
-46
lines changed

1 file changed

+182
-46
lines changed

docs/fastapi.md

Lines changed: 182 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
FastAPI 备忘清单
22
===
33

4-
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示。
4+
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示。Python: `3.9.5` FastAPI: `0.103.1`
55

66
入门
77
---
8+
<!--rehype:body-class=cols-1-->
89

910
### 最小程序
1011

@@ -25,10 +26,47 @@ if __name__ == '__main__':
2526
uvicorn.run(app='main:app', reload=True)
2627
```
2728

29+
### 路径参数
30+
31+
#### 最基本的路径参数
32+
33+
```python
34+
# http://127.0.0.1:8000/items/1
35+
@app.get("/items/{item_id}")
36+
async def read_item(item_id):
37+
return {"item_id": item_id} # item_id自定义
38+
```
39+
40+
#### 多个路径参数
41+
42+
```python
43+
# http://127.0.0.1:8000/items/1/2
44+
@app.get("/items/{item_id}/{user_id}")
45+
async def read_item(item_id, user_id):
46+
return {"item_id": item_id, "user_id": user_id}
47+
```
48+
49+
#### 有类型的路径参数
50+
51+
```python
52+
# http://127.0.0.1:8000/items/1
53+
@app.get("/items/{item_id}")
54+
async def read_item(item_id: int):
55+
return {"item_id": item_id}
56+
```
57+
58+
#### 文件路径参数
59+
60+
```python
61+
# http://127.0.0.1:8000/file//home/my/my.txt
62+
@app.get("/file/{file_path:path}")
63+
async def read_item(file_path):
64+
return {"file_path": file_path}
65+
```
66+
2867
### 查询参数
29-
<!--rehype:wrap-class=col-span-2 row-span-2-->
3068

31-
带默认值的查询参数
69+
#### 带默认值的查询参数
3270

3371
```python
3472
# http://127.0.0.1:8000/items/?skip=0&limit=2
@@ -38,7 +76,7 @@ async def read_item(skip: int = 0, limit: int = 10):
3876
return fake_items_db[skip: skip + limit]
3977
```
4078

41-
可选查询参数
79+
#### 可选查询参数
4280

4381
```python
4482
# http://127.0.0.1:8000/items/1?q=admin
@@ -50,7 +88,7 @@ async def read_item(item_id: str, q: Union[str, None] = None):
5088
return {"item_id": item_id}
5189
```
5290

53-
多路径多查询参数
91+
#### 多路径多查询参数
5492

5593
```python
5694
# http://127.0.0.1:8000/users/1/items/2
@@ -70,7 +108,7 @@ async def read_user_item(
70108
return item
71109
```
72110

73-
必需查询参数
111+
#### 必需查询参数
74112

75113
```python
76114
# http://127.0.0.1:8000/items/123?needy=yes
@@ -80,44 +118,6 @@ async def read_user_item(item_id: str, needy: str):
80118
return item
81119
```
82120

83-
### 路径参数
84-
85-
最基本的路径参数
86-
87-
```python
88-
# <http://127.0.0.1:8000/items/1>
89-
@app.get("/items/{item_id}")
90-
async def read_item(item_id):
91-
return {"item_id": item_id} # item_id自定义
92-
```
93-
94-
多个路径参数
95-
96-
```python
97-
# <http://127.0.0.1:8000/items/1/2>
98-
@app.get("/items/{item_id}/{user_id}")
99-
async def read_item(item_id, user_id):
100-
return {"item_id": item_id, "user_id": user_id}
101-
```
102-
103-
有类型的路径参数
104-
105-
```python
106-
# <http://127.0.0.1:8000/items/1>
107-
@app.get("/items/{item_id}")
108-
async def read_item(item_id: int):
109-
return {"item_id": item_id}
110-
```
111-
112-
文件路径参数
113-
114-
```python
115-
# <http://127.0.0.1:8000/file//home/my/my.txt>
116-
@app.get("/file/{file_path:path}")
117-
async def read_item(file_path):
118-
return {"file_path": file_path}
119-
```
120-
121121
### 请求体
122122

123123
```python
@@ -150,7 +150,6 @@ curl -X 'POST' \
150150
```
151151

152152
### 查询参数和字符串校验
153-
<!--rehype:wrap-class=col-span-2-->
154153

155154
```python
156155
from fastapi import Query
@@ -173,15 +172,152 @@ async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
173172
| alias | 别名参数 | string |
174173
| deprecated | 准备弃用参数 | bool |
175174

176-
多个相同的查询参数 <http://127.0.0.1:8000/items/?q=foo&q=bar>
175+
#### 多个相同的查询参数
177176

178177
```python
178+
# http://127.0.0.1:8000/items/?q=foo&q=bar
179179
@app.get("/items/")
180180
async def read_items(q: Union[List[str], None] = Query(default=None)):
181181
query_items = {"q": q}
182182
return query_items
183183
```
184184

185+
### 路径参数和数值校验
186+
187+
Path用法基本和Query相同,参考:[FastAPI官方文档](https://fastapi.tiangolo.com/zh/tutorial/path-params-numeric-validations/)
188+
189+
#### 导入 Path
190+
191+
```python
192+
from fastapi import FastAPI, Path, Query
193+
from typing_extensions import Annotated
194+
```
195+
196+
#### 声明元数据
197+
198+
```python
199+
@app.get("/items/{item_id}")
200+
async def read_items(
201+
item_id: Annotated[int, Path(title="The ID of the item to get")],
202+
q: Annotated[Union[str, None], Query(alias="item-query")] = None,
203+
):
204+
results = {"item_id": item_id}
205+
if q:
206+
results.update({"q": q})
207+
return results
208+
```
209+
210+
#### 参数列表
211+
212+
| 参数 | 含义 | 类型 |
213+
| ----- | ------------------- | --------- |
214+
| ... | 和Query具有相同参数 | ... |
215+
| ge | 大于等于 | int float |
216+
| gt | 大于 | int float |
217+
| le | 小于等于 | int float |
218+
| le | 小于等于 | int float |
219+
| title | api文档的标题 | string |
220+
221+
### 其他参数
222+
223+
都具有Query的参数,max_length、min_length等
224+
225+
#### Cookie参数
226+
227+
```python
228+
from fastapi import Cookie
229+
@app.get("/items/")
230+
async def read_items(ads_id: Annotated[Union[str, None], Cookie()] = None):
231+
return {"ads_id": ads_id}
232+
```
233+
234+
#### Header 参数
235+
236+
```python
237+
from fastapi import Header
238+
@app.get("/items/")
239+
async def read_items(user_agent: Annotated[Union[str, None], Header()] = None,items_id: Annotated[Union[int, None], Header(ge=1)] = None):
240+
return {"User-Agent": user_agent, "items_id": items_id}
241+
```
242+
243+
### 表单数据
244+
245+
接收的不是 JSON,而是表单字段时,要使用 Form。
246+
247+
#### 安装
248+
249+
`pip install python-multipart`
250+
251+
#### HTML
252+
253+
```html
254+
<!DOCTYPE html>
255+
<html lang="en">
256+
<head>
257+
<meta charset="UTF-8">
258+
</head>
259+
<body>
260+
<form method="post" action="http://127.0.0.1:8000/login">
261+
<span>账号:</span><input type="text" name="username">
262+
<br>
263+
<span>密码:</span><input type="password" name="password">
264+
<br>
265+
<input type="submit" value="登录">
266+
</form>
267+
</body>
268+
</html>
269+
```
270+
271+
#### FastAPI
272+
273+
```python
274+
from fastapi import FastAPI, Form
275+
import uvicorn
276+
app = FastAPI()
277+
@app.post("/login/")
278+
async def login(username: str = Form(), password: str = Form()):
279+
return {"username": username}
280+
if __name__ == '__main__':
281+
uvicorn.run(app='main:app', reload=True)
282+
```
283+
284+
### 文件上传
285+
286+
```python
287+
from fastapi import FastAPI, UploadFile
288+
from fastapi.responses import HTMLResponse
289+
@app.post("/uploadfile/")
290+
async def create_upload_file(file: UploadFile):
291+
print(file.file.read().decode())
292+
return {"filenames": file.filename, "type": str(type(file.file))}
293+
@app.get("/")
294+
async def main():
295+
content = """<body>
296+
<form action="/uploadfile/" enctype="multipart/form-data" method="post">
297+
<input name="file" type="file" multiple>
298+
<input type="submit">
299+
</form>
300+
</body>"""
301+
return HTMLResponse(content=content)
302+
```
303+
304+
#### UploadFile属性
305+
306+
| 属性名 | 含义 | 返回 |
307+
| ------------ | -------- | --------------------------------------- |
308+
| filename | 文件名 | 上传的文件名 |
309+
| content_type | 内容类型 | MIME 类型 |
310+
| file | 文件 | SpooledTemporaryFile具有read,write方法 |
311+
312+
#### UploadFile async方法
313+
314+
| 方法名 | 含义 |
315+
| ------------ | ----------------------------------------- |
316+
| write(data) |`data` 写入文件 |
317+
| read(size) | 按指定数量的字节读取文件内容 |
318+
| seek(offset) | 移动至文件 `offset``int`)字节处的位置 |
319+
| close() | 关闭文件 |
320+
185321
参考
186322
---
187323

0 commit comments

Comments
 (0)