Cookie和Header
前面的学习记录提到过FastApi框架提供了Cookie和Header方法用于接受cookie和header参数。
cookie参数的接受和Query没有什么不同
@app.get("/request01")
def request01(*, val: str = Cookie(...)):
return val
@app.get("/request02")
def request02(*, val: str = Header(...)):
return val
@app.get("/request03")
def request03(*, val_item: str = Header(...)):
return val_item
@app.get("/request04")
def request04(*, val_list: List[str] = Header(...)):
return val_list
Header的用法也类似,注意,header的分隔符要求是减号"-",但是"-"在变量名称是不合法的,所以调用时传入val-item,在接收时会自动转化成val_item, 同时也会忽略大小写,比如调用时传入Val-Item,在接收val_item就可以。如果传入多个相同val-item时,后台可以以数组的形式接收。
Response Model返回的数据
和request-body相对的,返回的数据模型。
class Item(BaseModel):
name: str
age: int = 18
@app.post("/request05", response_model=Item)
def request05(*, item: Item):
return item
@app.post("/request06", response_model=List[Item])
def request06(*, item: Item):
return [item, item]
class OutItem(BaseModel):
name: str
@app.post("/request07", response_model=OutItem)
def request07(*, item: Item):
return item
@app.post("/request08", response_model=Item, response_model_exclude_unset=True)
def request08(*, item: Item):
return item
@app.post("/request09", response_model=Item, response_model_include={"name"})
def request09(*, item: Item):
return item
@app.post("/request10", response_model=Item, response_model_exclude={"age"})
def request10(*, item: Item):
return item
通过response_model来指定返回的数据模型
request06:可以指定为数据的类型
request07:可以指定的别的数据类型,最后返回的结果只包含两个Model都包含的字段。
request08:response_mode_exclude_unset=True, 在response_model中并没有被设置时,在返回时被忽略。
request09-10:response_model_include和response_model_exclude,注意是set类型,在返回的数据中是否包含该key
其他的Model处理
class Item1(BaseModel):
name: str
age: int = 1
class Item2(BaseModel):
name: str
age: int
alias_name: str = "别名"
class Item3(Item1):
alias_name: str = "别名"
class Item4(BaseModel):
alias_name: str = "别名"
@app.post("/request11")
def request11(*, item: Item1):
print(item.dict())
item2 = Item2(**item.dict())
return item2
@app.post("/request12")
def request12(*, item: Item1):
item3 = Item3(**item.dict(), alias_name="哈哈")
return item3
@app.post("/request13", response_model=Union[Item1, Item4])
def request13(*, item: Item1):
return item
@app.post("/request14", response_model=Dict[str, int])
def reqeust14():
return {"a": 1, "b": 2}
Pydantic的Basemodel可以适用dict形式的数据赋值,item是一个BaseModel实例,item.dict()得到的是一个dict类型的数据,**item.dict()就像解构一样,给BaseModel赋值。
可以利用继承的特性,避免重复的key。
可以使用Union(from typing import Union),联合多个BaseModel作为response_model。
response_model可以声明成Dict[str, int]字典类型的(和request-body相同)
response_model可以声明成List(Item1)数组类型(和request-body相同)
Form表单数据
@app.post("/request15")
def request15(name: str = Form(...)):
return name
适用Form方法,和Query,Path使用方法想用,但是得提前安装一个库pip install python-multipart
File和UploadFile上传
@app.post("/request16")
def request16(file: bytes = File(...)):
return len(file)
@app.post("/request17")
async def request17(file: UploadFile = File(...)):
with open("./%s" % file.filename, "wb") as f:
content = await file.read()
f.write(content)
f.close()
return file.filename
@app.post("/reqeust18")
def request18(files: List[UploadFile] = File(...)):
res = []
for file in files:
res.append(file.filename)
return res
使用File和UploadFile来接受上传的文件。也可以适用bytes和File来接收文件,但是UploadFile更有优势。
UploadFile提供了属性:filename和content-type和read, seek, close, write等方法用于操作文件流,但是注意的是这些方法都是异步的,所以调用时应使用await装饰,同时接口函数也应该定义成async异步。
request17实现了一个简单的文件上传并保存,将文件流写入到文件句柄中并保存。
request18适用List[UploadFile]声明接受多个文件。