Package: pydantic-view
Pydantic view helper decoratorInstallationpipinstallpydantic_viewUsageIn[1]:fromuuidimportUUID,uuid4...:...:frompydanticimportBaseModel,Field...:frompydantic_viewimportview...:...:...:@view("Create",exclude={"id"})...:@view("Update")...:@view("Patch",optional={"username","password","address"})...:@view("Out",exclude={"password"})...:classUser(BaseModel):...:id:int...:username:str...:password:str...:address:str...:In[2]:user=User(id=0,username="human",password="iamaman",address="Earth")...:user.Out()...:Out[2]:UserOut(id=0,username='human',address='Earth')In[3]:User.Update(id=0,username="human",password="iamasuperman",address="Earth")...:Out[3]:UserUpdate(id=0,username='human',password='iamasuperman',address='Earth')In[4]:User.Patch(id=0,address="Mars")...:Out[4]:UserPatch(id=0,username=None,password=None,address='Mars')FastAPI examplefromtypingimportListfromfastapiimportFastAPIfromfastapi.testclientimportTestClientfrompydanticimportBaseModel,Fieldfrompydantic_viewimportview,view_validator@view("Out",exclude={"secret"})@view("Create",exclude={"id"},config={"extra":"forbid"})@view("Update",exclude={"id"})@view("UpdateMany")@view("Patch",exclude={"id"},optional={"name","secret"})@view("PatchMany",optional={"name","secret"})classGroup(BaseModel):id:intname:strsecret:str=None@view_validator(["Create","Update","UpdateMany","Patch","PatchMany"],"name",allow_reuse=True)defvalidate_name(cls,v):ifv=="admin":raiseValueError("Invalid name")returnv@view("Out",exclude={"password"},recursive=True)@view("Create",exclude={"id"},fields={"groups":Field(default_factory=lambda:[Group(id=0,name="default")])},config={"extra":"forbid"},recursive=True,)@view("Update",exclude={"id"},recursive=True)@view("UpdateMany",recursive=True)@view("Patch",exclude={"id"},optional={"username","password","groups"},recursive=True)@view("PatchMany",optional={"username","password","groups"},recursive=True)classUser(BaseModel):id:intusername:strpassword:strgroups:List[Group]app=FastAPI()db={}@app.get("/users/{user_id}",response_model=User.Out)asyncdefget(user_id:int)->User.Out:returndb[user_id]@app.post("/users",response_model=User.Out)asyncdefpost(user:User.Create)->User.Out:user_id=0# generate_user_id()db[0]=User(id=user_id,**user.dict())returndb[0]@app.put("/users/{user_id}",response_model=User.Out)asyncdefput(user_id:int,user:User.Update)->User.Out:db[user_id]=User(id=user_id,**user.dict())returndb[user_id]@app.put("/users",response_model=List[User.Out])asyncdefput_many(users:List[User.UpdateMany])->List[User.Out]:foruserinusers:db[user.id]=userreturnusers@app.patch("/users/{user_id}",response_model=User.Out)asyncdefpatch(user_id:int,user:User.Patch)->User.Out:db[user_id]=User(**{**db[user_id].dict(),**user.dict(exclude_unset=True)})returndb[user_id]@app.patch("/users",response_model=List[User.Out])asyncdefpatch_many(users:List[User.PatchMany])->List[User.Out]:foruserinusers:db[user.id]=User(**{**db[user.id].dict(),**user.dict(exclude_unset=True)})return[db[user.id]foruserinusers]deftest_fastapi():client=TestClient(app)# POSTresponse=client.post("/users",json={"username":"admin","password":"admin",},)assertresponse.status_code==200assertresponse.json()=={"id":0,"username":"admin","groups":[{"id":0,"name":"default"}],}# GETresponse=client.get("/users/0")assertresponse.status_code==200assertresponse.json()=={"id":0,"username":"admin","groups":[{"id":0,"name":"default"}],}# PUTresponse=client.put("/users/0",json={"username":"superadmin","password":"superadmin","groups":[],},)assertresponse.status_code==200assertresponse.json()=={"id":0,"username":"superadmin","groups":[],}# PUT manyresponse=client.put("/users",json=[{"id":0,"username":"admin","password":"admin","groups":[{"id":0,"name":"default","secret":"secret_value"}],}],)assertresponse.status_code==200assertresponse.json()==[{"id":0,"username":"admin","groups":[{"id":0,"name":"default"}],}]# PATCHresponse=client.patch("/users/0",json={"id":0,"username":"guest"})assertresponse.status_code==200assertresponse.json()=={"id":0,"username":"guest","groups":[{"id":0,"name":"default"}],}# PATCH manyresponse=client.patch("/users",json=[{"id":0,"groups":[]}])assertresponse.status_code==200assertresponse.json()==[{"id":0,"username":"guest","groups":[],}]