天天看点

FastApi学习-04

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]声明接受多个文件。