Files
fastapi_tutor_yb/router/features/validation.py
T

134 lines
3.9 KiB
Python
Raw Normal View History

2026-09-19 10:41:18 +08:00
import fastapi
from fastapi import APIRouter,Query,Path,HTTPException
from pydantic import Field,BaseModel,field_validator,model_validator
from typing import Annotated,Union,Optional
route = APIRouter(prefix="/validations",tags=["validations"])
@route.get("/annotated_query")
async def get(option: Annotated[str|None, Query(max_length=10)] = None):
return option
@route.get("/annotated_query_lst")
async def get(option: Annotated[list[str], Query()] = None):
return option
@route.get("/annotated_query_re")
async def get(option: Annotated[str|None, Query(min_length=2,max_length=10,pattern="^g.*k$")] = None):
return option
@route.get("/annotated_path/{option}")
async def get(option: Annotated[str|None, Path(max_length=10)]):
return option
@route.get("/query")
async def get(option: str = Query(min_length=2, max_length=10)):
return option
@route.get("/params_validate")
async def params_validate(name:Union[str,None], # default
id: Optional[int]):
pass
# @route.get("/field")
# async def get(option: str = Field(min_length=2, max_length=10)):
# return option
class Clazz(BaseModel):
name: str = Field(min_length=2,max_length=12)
@route.get("/field")
async def get(clazz: Clazz):
return clazz
@route.get("/field_body")
async def get(clazz: Clazz = fastapi.Body()):
return clazz
@route.get("/path_path/{option}")
async def get(option: str = Path(min_length=2, max_length=10)):
return option
#
# @route.get("/path_query/{option}")
# async def get(option: str = Query(min_length=2, max_length=10)):
# return option
# param not got!
@route.get("/path_bad")
async def get(option: str = Path(min_length=2, max_length=10)):
return option
@route.get("/items/")
async def read_items(q: str|None = Query(default=None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
@route.get("/items_default_bad/")
async def read_items(q: str = Query(default=None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
# field/model_validator
class User(BaseModel):
name: str
passwd: str
# @field_validator("passwd")
# def check_passwd(cls,passwd,values): #
# # print(f'{values=}') # values=ValidationInfo(config={'title': 'User'}, context=None, data={'name': 'string'}, field_name='passwd')
# # 无法cannot access passwd/ name ?!
# # print(f'{values["passwd"]=}')
# # print(f'{values["name"]=}')
# if passwd == '001':
# raise HTTPException(status_code=408,detail="001 only root can set!")
# return passwd
@model_validator(mode="before")
def check_model_before(cls, data): #
print('model_validator before............')
return data
@field_validator("passwd","name")
def check_field(cls,value,values): #
# print(f'{values=}') # values=ValidationInfo(config={'title': 'User'}, context=None, data={'name': 'string'}, field_name='passwd')
# cannot access passwd/ name ?!
# print(f'{values["passwd"]=}')
# print(f'{values["name"]=}')
print('field_validator............')
if value == '001':
raise HTTPException(status_code=408,detail="001 only root can set!")
if value == 'root':
raise HTTPException(status_code=408,detail="only root can set name!")
return value
@model_validator(mode="after")
def check_model_after(self): #
print('model_validator............')
if self.passwd == '001':
raise HTTPException(status_code=408,detail="model : 001 only root can set!")
if self.name == 'root':
raise HTTPException(status_code=408,detail="model : only root can set name!")
return self
# u = User(age="20", name="geeker")
@route.post("/registe")
def registe(user: User):
return user