FastAPI Web框架 [1.7]
Posted Ch4536251
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FastAPI Web框架 [1.7]相关的知识,希望对你有一定的参考价值。
响应模型
# 可以在任意的路径操作中使用 response_model 参数来声明用于响应的模型:
# @app.get()
# @app.post()
# @app.put()
# @app.delete() 等等
from typing import Optional,List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name:str
description:Optional[str] = None
price:float
tax:Optional[float] = None
tags:List[str] = []
@app.post("/items/",response_model=Item)
async def create_item(item:Item):
return item
# 注意,response_model是「装饰器」方法(get,post 等)的一个参数。不像之前的所有参数和请求体,它不属于路径操作函数。
# 它接收的类型与你将为 Pydantic 模型属性所声明的类型相同,因此它可以是一个 Pydantic 模型,但也可以是一个由 Pydantic 模型组成的 list,例如 List[Item]。
# FastAPI 将使用此 response_model 来:
# 将输出数据转换为其声明的类型。
# 校验数据。
# 在 OpenAPI 的路径操作中为响应添加一个 JSON Schema。
# 并在自动生成文档系统中使用。
# 会将输出数据限制在该模型定义内。
# 响应模型在参数中被声明,而不是作为函数返回类型的注解,这是因为路径函数可能不会真正返回该响应模型,而是返回一个 dict、数据库对象或其他模型,然后再使用 response_model 来执行字段约束和序列化。
# 返回与输入相同的数据
# 我们声明一个 UserIn 模型,它将包含一个明文密码属性。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app=FastAPI()
class UserIn(BaseModel):
username:str
password:str
email:EmailStr
full_name:Optional[str] = None
# 不要在生产中这样做!!!!!!
@app.post("/user/", response_model=UserIn)
async def create_user(user: UserIn):
return user
# 正在使用此模型声明输入数据,并使用同一模型声明输出数据
# 现在,每当浏览器使用一个密码创建用户时,API 都会在响应中返回相同的密码。
# 在这个案例中,这可能不算是问题,因为用户自己正在发送密码。
# 如果我们在其他的路径操作中使用相同的模型,则可能会将用户的密码发送给每个客户端。
# 永远不要存储用户的明文密码,也不要在响应中发送密码。
# 添加输出模型
# 相反,我们可以创建一个有明文密码的输入模型和一个没有明文密码的输出模型:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel): #输入
username: str
password: str
email: EmailStr
full_name: Optional[str] = None
class UserOut(BaseModel): #输出
username: str
email: EmailStr
full_name: Optional[str] = None
@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
return user
# 即便我们的路径操作函数将会返回包含密码的相同输入用户:我们已经将 response_model 声明为了不包含密码的 UserOut 模型:
# FastAPI 将会负责过滤掉未在输出模型中声明的所有数据(使用 Pydantic)
# 响应模型编码参数
# 你的响应模型可以具有默认值,例如:
from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None # description: Optional[str] = None 具有默认值 None。
price: float
tax: float = 10.5 # tax: float = 10.5 具有默认值 10.5.
tags: List[str] = [] # tags: List[str] = [] 具有一个空列表作为默认值: [].
# 如果它们并没有存储实际的值,你可能想从结果中忽略它们的默认值。
items =
"foo": "name": "Foo", "price": 50.2,
"bar": "name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2,
"baz": "name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": [],
@app.get(
"/items/item_id",
response_model=Item,
response_model_exclude_unset=True #response_model_exclude_unset参数:响应中将不会包含那些默认值,而是仅有实际设置的值。
)
async def read_item(item_id:str):
return items[item_id]
# 如果你向路径操作发送 ID 为 foo 的商品的请求,则响应(不包括默认值)将为:
#
# "name": "Foo",
# "price": 50.2
#
# FastAPI 通过 Pydantic 模型的 .dict() 配合 该方法的 exclude_unset 参数 来实现此功能。
# 你还可以使用:
# response_model_exclude_defaults=True
# response_model_exclude_none=True
# 默认值字段有实际值的数据:
# 但是,如果你的数据在具有默认值的模型字段中有实际的值,例如 ID 为 bar 的项:
#
# "name": "Bar",
# "description": "The bartenders",
# "price": 62,
# "tax": 20.2
#
# 这些值将包含在响应中。
# 具有与默认值相同值的数据
## 如果数据具有与默认值相同的值,例如 ID 为 baz 的项:
#
# "name": "Baz",
# "description": None,
# "price": 50.2,
# "tax": 10.5,
# "tags": []
#
# 即使 description、tax 和 tags 具有与默认值相同的值,FastAPI 足够聪明 (实际上是 Pydantic 足够聪明) 去认识到这一点,它们的值被显式地所设定(而不是取自默认值)。
# 因此,它们将包含在 JSON 响应中。
##请注意默认值可以是任何值,而不仅是None。它们可以是一个列表([]),一个值为 10.5的 float,等等。
#response_model_include 和 response_model_exclude
# 使用路径操作装饰器的 response_model_include 和 response_model_exclude 参数。
# 它们接收一个由属性名称 str 组成的 set 来包含(忽略其他的)或者排除(包含其他的)这些属性。
# 如果你只有一个 Pydantic 模型,并且想要从输出中移除一些数据,则可以使用这种快捷方法。
# 但是依然建议你使用上面提到的主意,使用多个类而不是这些参数。
#
# 这是因为即使使用 response_model_include 或 response_model_exclude 来省略某些属性,在应用程序的 OpenAPI 定义(和文档)中生成的 JSON Schema 仍将是完整的模型。
# 这也适用于作用类似的 response_model_by_alias。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
items =
"foo": "name": "Foo", "price": 50.2,
"bar": "name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2,
"baz":
"name": "Baz",
"description": "There goes my baz",
"price": 50.2,
"tax": 10.5,
@app.get(
"/items/item_id/name",
response_model=Item,
response_model_include="name", "description", #包括,"name", "description" 语法创建一个具有这两个值的 set。等同于 set(["name", "description"])。
)
async def read_item_name(item_id: str):
return items[item_id]
@app.get(
"/items/item_id/public",
response_model=Item,
response_model_exclude="tax" #排除tax属性
)
async def read_item_public_data(item_id: str):
return items[item_id]
# 使用 list 而不是 set
# 如果你忘记使用 set 而是使用 list 或 tuple,FastAPI 仍会将其转换为 set 并且正常工作:]
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
items =
"foo": "name": "Foo", "price": 50.2,
"bar": "name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2,
"baz":
"name": "Baz",
"description": "There goes my baz",
"price": 50.2,
"tax": 10.5,
,
@app.get(
"/items/item_id/name",
response_model=Item,
response_model_include=["name", "description"],
)
async def read_item_name(item_id: str):
return items[item_id]
@app.get(
"/items/item_id/public",
response_model=Item,
response_model_exclude=["tax"]
)
async def read_item_public_data(item_id: str):
return items[item_id]
# 使用路径操作装饰器的 response_model 参数来定义响应模型,特别是确保私有数据被过滤掉。
# 使用 response_model_exclude_unset 来仅返回显式设定的值。
以上是关于FastAPI Web框架 [1.7]的主要内容,如果未能解决你的问题,请参考以下文章