Usando Dataclasses¶
FastAPI está construido sobre Pydantic, y te he estado mostrando cómo usar modelos de Pydantic para declarar requests y responses.
Pero FastAPI también soporta el uso de dataclasses
de la misma manera:
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
Esto sigue siendo soportado gracias a Pydantic, ya que tiene soporte interno para dataclasses
.
Así que, incluso con el código anterior que no usa Pydantic explícitamente, FastAPI está usando Pydantic para convertir esos dataclasses estándar en su propia versión de dataclasses de Pydantic.
Y por supuesto, soporta lo mismo:
- validación de datos
- serialización de datos
- documentación de datos, etc.
Esto funciona de la misma manera que con los modelos de Pydantic. Y en realidad se logra de la misma manera internamente, utilizando Pydantic.
Información
Ten en cuenta que los dataclasses no pueden hacer todo lo que los modelos de Pydantic pueden hacer.
Así que, podrías necesitar seguir usando modelos de Pydantic.
Pero si tienes un montón de dataclasses por ahí, este es un buen truco para usarlos para potenciar una API web usando FastAPI. 🤓
Dataclasses en response_model
¶
También puedes usar dataclasses
en el 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"],
}
El dataclass será automáticamente convertido a un dataclass de Pydantic.
De esta manera, su esquema aparecerá en la interfaz de usuario de la documentación de la API:
Dataclasses en Estructuras de Datos Anidadas¶
También puedes combinar dataclasses
con otras anotaciones de tipos para crear estructuras de datos anidadas.
En algunos casos, todavía podrías tener que usar la versión de dataclasses
de Pydantic. Por ejemplo, si tienes errores con la documentación de la API generada automáticamente.
En ese caso, simplemente puedes intercambiar los dataclasses
estándar con pydantic.dataclasses
, que es un reemplazo directo:
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",
},
],
},
]
-
Todavía importamos
field
de losdataclasses
estándar. -
pydantic.dataclasses
es un reemplazo directo paradataclasses
. -
El dataclass
Author
incluye una lista de dataclassesItem
. -
El dataclass
Author
se usa como el parámetroresponse_model
. -
Puedes usar otras anotaciones de tipos estándar con dataclasses como el request body.
En este caso, es una lista de dataclasses
Item
. -
Aquí estamos regresando un diccionario que contiene
items
, que es una lista de dataclasses.FastAPI todavía es capaz de serializar los datos a JSON.
-
Aquí el
response_model
está usando una anotación de tipo de una lista de dataclassesAuthor
.Nuevamente, puedes combinar
dataclasses
con anotaciones de tipos estándar. -
Nota que esta path operation function usa
def
regular en lugar deasync def
.Como siempre, en FastAPI puedes combinar
def
yasync def
según sea necesario.Si necesitas un repaso sobre cuándo usar cuál, revisa la sección "¿Con prisa?" en la documentación sobre
async
yawait
. -
Esta path operation function no está devolviendo dataclasses (aunque podría), sino una lista de diccionarios con datos internos.
FastAPI usará el parámetro
response_model
(que incluye dataclasses) para convertir el response.
Puedes combinar dataclasses
con otras anotaciones de tipos en muchas combinaciones diferentes para formar estructuras de datos complejas.
Revisa las anotaciones en el código arriba para ver más detalles específicos.
Aprende Más¶
También puedes combinar dataclasses
con otros modelos de Pydantic, heredar de ellos, incluirlos en tus propios modelos, etc.
Para saber más, revisa la documentación de Pydantic sobre dataclasses.
Versión¶
Esto está disponible desde la versión 0.67.0
de FastAPI. 🔖