Usando Dataclasses¶
FastAPI é construído em cima do Pydantic, e eu tenho mostrado como usar modelos Pydantic para declarar requisições e respostas.
Mas o FastAPI também suporta o uso de dataclasses
da mesma forma:
from dataclasses import dataclass
from typing import Union
from fastapi import FastAPI
@dataclass
class Item:
name: str
price: float
description: Union[str, None] = None
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
Isso ainda é suportado graças ao Pydantic, pois ele tem suporte interno para dataclasses
.
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. 🤓
Dataclasses em response_model
¶
Você também pode usar dataclasses
no parâmetro response_model
:
from dataclasses import dataclass, field
from typing import List, Union
from fastapi import FastAPI
@dataclass
class Item:
name: str
price: float
tags: List[str] = field(default_factory=list)
description: Union[str, None] = None
tax: Union[float, None] = None
app = FastAPI()
@app.get("/items/next", response_model=Item)
async def read_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:
Dataclasses em Estruturas de Dados Aninhadas¶
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:
from dataclasses import field # (1)
from typing import List, Union
from fastapi import FastAPI
from pydantic.dataclasses import dataclass # (2)
@dataclass
class Item:
name: str
description: Union[str, None] = None
@dataclass
class Author:
name: str
items: List[Item] = field(default_factory=list) # (3)
app = FastAPI()
@app.post("/authors/{author_id}/items/", response_model=Author) # (4)
async def create_author_items(author_id: str, items: List[Item]): # (5)
return {"name": author_id, "items": items} # (6)
@app.get("/authors/", response_model=List[Author]) # (7)
def get_authors(): # (8)
return [ # (9)
{
"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",
},
],
},
]
-
Ainda importamos
field
dasdataclasses
padrão. -
pydantic.dataclasses
é um substituto direto paradataclasses
. -
A dataclass
Author
inclui uma lista de dataclassesItem
. -
A dataclass
Author
é usada como o parâmetroresponse_model
. -
Você pode usar outras anotações de tipo padrão com dataclasses como o corpo da requisição.
Neste caso, é uma lista de dataclasses
Item
. -
Aqui estamos retornando um dicionário que contém
items
, que é uma lista de dataclasses.O FastAPI ainda é capaz de serializar os dados para JSON.
-
Aqui o
response_model
está usando uma anotação de tipo de uma lista de dataclassesAuthor
.Novamente, você pode combinar
dataclasses
com anotações de tipo padrão. -
Note que esta função de operação de rota usa
def
regular em vez deasync def
.Como sempre, no FastAPI você pode combinar
def
easync def
conforme necessário.Se você precisar de uma atualização sobre quando usar qual, confira a seção "Com pressa?" na documentação sobre
async
eawait
. -
Esta função de operação de rota não está retornando dataclasses (embora pudesse), mas uma lista de dicionários com dados internos.
O FastAPI usará o parâmetro
response_model
(que inclui dataclasses) para converter a resposta.
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.
Saiba Mais¶
Você também pode combinar dataclasses
com outros modelos Pydantic, herdar deles, incluí-los em seus próprios modelos, etc.
Para saber mais, confira a documentação do Pydantic sobre dataclasses.
Versão¶
Isso está disponível desde a versão 0.67.0
do FastAPI. 🔖