Então, mesmo com o código acima que não usa Pydantic explicitamente, o FastAPI está usando Pydantic para converter essas dataclasses padrão para a versão do Pydantic.
E claro, ele suporta o mesmo:
validação de dados
serialização de dados
documentação de dados, etc.
Isso funciona da mesma forma que com os modelos Pydantic. E na verdade é alcançado da mesma maneira por baixo dos panos, usando Pydantic.
Informação
Lembre-se de que dataclasses não podem fazer tudo o que os modelos Pydantic podem fazer.
Então, você ainda pode precisar usar modelos Pydantic.
Mas se você tem um monte de dataclasses por aí, este é um truque legal para usá-las para alimentar uma API web usando FastAPI. 🤓
Você também pode usar dataclasses no parâmetro response_model:
fromdataclassesimportdataclass,fieldfromtypingimportList,UnionfromfastapiimportFastAPI@dataclassclassItem:name:strprice:floattags:List[str]=field(default_factory=list)description:Union[str,None]=Nonetax:Union[float,None]=Noneapp=FastAPI()@app.get("/items/next",response_model=Item)asyncdefread_next_item():return{"name":"Island In The Moon","price":12.99,"description":"A place to be playin' and havin' fun","tags":["breater"],}
A dataclass será automaticamente convertida para uma dataclass Pydantic.
Dessa forma, seu esquema aparecerá na interface de documentação da API:
Você também pode combinar dataclasses com outras anotações de tipo para criar estruturas de dados aninhadas.
Em alguns casos, você ainda pode ter que usar a versão do Pydantic das dataclasses. Por exemplo, se você tiver erros com a documentação da API gerada automaticamente.
Nesse caso, você pode simplesmente trocar as dataclasses padrão por pydantic.dataclasses, que é um substituto direto:
fromdataclassesimportfield# fromtypingimportList,UnionfromfastapiimportFastAPIfrompydantic.dataclassesimportdataclass# @dataclassclassItem:name:strdescription:Union[str,None]=None@dataclassclassAuthor:name:stritems:List[Item]=field(default_factory=list)# app=FastAPI()@app.post("/authors/{author_id}/items/",response_model=Author)# asyncdefcreate_author_items(author_id:str,items:List[Item]):# return{"name":author_id,"items":items}# @app.get("/authors/",response_model=List[Author])# defget_authors():# return[# {"name":"Breaters","items":[{"name":"Island In The Moon","description":"A place to be playin' and havin' fun",},{"name":"Holy Buddies"},],},{"name":"System of an Up","items":[{"name":"Salt","description":"The kombucha mushroom people's favorite",},{"name":"Pad Thai"},{"name":"Lonely Night","description":"The mostests lonliest nightiest of allest",},],},]
Você pode combinar dataclasses com outras anotações de tipo em muitas combinações diferentes para formar estruturas de dados complexas.
Confira as dicas de anotação no código acima para ver mais detalhes específicos.