learn from https://fastapi.tiangolo.com/zh/tutorial/response-model/
响应模型 不是 路径参数
from typing import Optional, List
from fastapi import Cookie, FastAPI, Header
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_items(item: Item):
return item
or
@app.post("/items/", response_model=List[Item]) # 装饰器方法的一个参数
async def create_items(item: Item):
return [item, item]
响应模型 对 返回的数据 进行转换,校验
例如:
from typing import Optional, List
from fastapi import Cookie, FastAPI, Header
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
永远不要 存储用户的 明文密码,也不要在响应中 发送密码。
from typing import Optional, List
from fastapi import Cookie, FastAPI, Header
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_exclude_unset
参数 True,输出忽略 未明确设置的 字段response_model_exclude_defaults=True
,忽略跟默认值一样的字段response_model_exclude_none=True
,忽略 None 的字段from typing import Optional, List
from fastapi import Cookie, FastAPI, Header
from pydantic import BaseModel, EmailStr
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
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)
async def read_item(item_id: str):
return items[item_id]
如果参数 改为 False,或者 删除该参数,未设置的值 也显示出来了
它们接收一个由属性名称 str 组成的 set 来包含(忽略其他的)或者排除(包含其他的)这些属性
response_model_include
, 只包含指定字段response_model_exclude
,排除指定字段from typing import Optional, List
from fastapi import Cookie, FastAPI, Header
from pydantic import BaseModel, EmailStr
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"},
# { } 表示 set, 使用 [ ] 也可以
)
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]
from typing import Optional
from fastapi import FastAPI
from pydantic import EmailStr, BaseModel
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
class UserInDB(BaseModel):
username: str
hashed_password: str
email: EmailStr
full_name: Optional[str] = None
def fake_password_hasher(raw_password: str):
return "supersecret" + raw_password
def fake_save_user(user_in: UserIn):
hashed_password = fake_password_hasher(user_in.password)
user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
# 使用user_in的数据初始化UserInDB , 并添加hashed_password字段
print("User saved! ..not really")
return user_in_db
@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
user_saved = fake_save_user(user_in)
return user_saved
from typing import Optional
from fastapi import FastAPI
from pydantic import EmailStr, BaseModel
app = FastAPI()
class UserBase(BaseModel):
username: str
email: EmailStr
full_name: Optional[str] = None
class UserIn(UserBase):
password: str
class UserOut(UserBase):
pass
class UserInDB(UserBase):
hashed_password: str
def fake_password_hasher(raw_password: str):
return "supersecret" + raw_password
def fake_save_user(user_in: UserIn):
hashed_password = fake_password_hasher(user_in.password)
user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
# 使用user_in的数据初始化UserInDB , 并添加hashed_password字段
print("User saved! ..not really")
return user_in_db
@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
user_saved = fake_save_user(user_in)
return user_saved
from typing import Optional, Union
class BaseItem(BaseModel):
description: str
type: str
class CarItem(BaseItem):
type = "car"
class PlaneItem(BaseItem):
type = "plane"
size: int
items = {
"item1": {"description": "All my friends drive a low rider", "type": "car"},
"item2": {
"description": "Music is my aeroplane, it's my aeroplane",
"type": "plane",
"size": 5,
},
}
@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
return items[item_id]
@app.get("/keyword-weights/", response_model=Dict[str, float])
async def read_keyword_weights():
return {"foo": 2.3, "bar": 3.4}
status_code
参数来声明用于响应的 HTTP 状态码
@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem],
status_code=208)
async def read_item(item_id: str):
return items[item_id]
关于 HTTP 状态码
在 HTTP 协议中,你将发送 3 位数的数字状态码作为响应的一部分。
100
及以上状态码用于「消息」响应。你很少直接使用它们。具有这些状态代码的响应不能带有响应体。200
及以上状态码用于「成功」响应。这些是你最常使用的。200
是默认状态代码,它表示一切「正常」。201
,「已创建」。它通常在数据库中创建了一条新记录后使用。204
,「无内容」。此响应在没有内容返回给客户端时使用,因此该响应不能包含响应体。300
及以上状态码用于「重定向」。具有这些状态码的响应可能有或者可能没有响应体,但 304
「未修改」是个例外,该响应不得含有响应体。400
及以上状态码用于「客户端错误」响应。这些可能是你第二常使用的类型。404
,用于「未找到」响应。400
。500
及以上状态码用于服务器端错误。你几乎永远不会直接使用它们。当你的应用程序代码或服务器中的某些部分出现问题时,它将自动返回这些状态代码之一。from fastapi import FastAPI, status
status_code=status.HTTP_201_CREATED # 可以使用代码补全,不必记住
from fastapi import FastAPI, Form
app = FastAPI()
@app.post("/login/")
async def login(username: str = Form(...),
password: str = Form(...)):
return {"username" : username}