Using Dataclasses

Warning

The current page still doesn’t have a translation for this language.

But you can help translating it: Contributing.

FastAPI is built on top of Pydantic, and I have been showing you how to use Pydantic models to declare requests and responses.

But FastAPI also supports using dataclasses the same way:

  1. from dataclasses import dataclass
  2. from typing import Union
  3. from fastapi import FastAPI
  4. @dataclass
  5. class Item:
  6. name: str
  7. price: float
  8. description: Union[str, None] = None
  9. tax: Union[float, None] = None
  10. app = FastAPI()
  11. @app.post("/items/")
  12. async def create_item(item: Item):
  13. return item

This is still supported thanks to Pydantic, as it has internal support for dataclasses.

So, even with the code above that doesn’t use Pydantic explicitly, FastAPI is using Pydantic to convert those standard dataclasses to Pydantic’s own flavor of dataclasses.

And of course, it supports the same:

  • data validation
  • data serialization
  • data documentation, etc.

This works the same way as with Pydantic models. And it is actually achieved in the same way underneath, using Pydantic.

Info

Have in mind that dataclasses can’t do everything Pydantic models can do.

So, you might still need to use Pydantic models.

But if you have a bunch of dataclasses laying around, this is a nice trick to use them to power a web API using FastAPI. 🤓

Dataclasses in response_model

You can also use dataclasses in the response_model parameter:

  1. from dataclasses import dataclass, field
  2. from typing import List, Union
  3. from fastapi import FastAPI
  4. @dataclass
  5. class Item:
  6. name: str
  7. price: float
  8. tags: List[str] = field(default_factory=list)
  9. description: Union[str, None] = None
  10. tax: Union[float, None] = None
  11. app = FastAPI()
  12. @app.get("/items/next", response_model=Item)
  13. async def read_next_item():
  14. return {
  15. "name": "Island In The Moon",
  16. "price": 12.99,
  17. "description": "A place to be be playin' and havin' fun",
  18. "tags": ["breater"],
  19. }

The dataclass will be automatically converted to a Pydantic dataclass.

This way, its schema will show up in the API docs user interface:

Using Dataclasses - 图1

Dataclasses in Nested Data Structures

You can also combine dataclasses with other type annotations to make nested data structures.

In some cases, you might still have to use Pydantic’s version of dataclasses. For example, if you have errors with the automatically generated API documentation.

In that case, you can simply swap the standard dataclasses with pydantic.dataclasses, which is a drop-in replacement:

  1. from dataclasses import field #
  2. from typing import List, Union
  3. from fastapi import FastAPI
  4. from pydantic.dataclasses import dataclass #
  5. @dataclass
  6. class Item:
  7. name: str
  8. description: Union[str, None] = None
  9. @dataclass
  10. class Author:
  11. name: str
  12. items: List[Item] = field(default_factory=list) #
  13. app = FastAPI()
  14. @app.post("/authors/{author_id}/items/", response_model=Author) #
  15. async def create_author_items(author_id: str, items: List[Item]): #
  16. return {"name": author_id, "items": items} #
  17. @app.get("/authors/", response_model=List[Author]) #
  18. def get_authors(): #
  19. return [ #
  20. {
  21. "name": "Breaters",
  22. "items": [
  23. {
  24. "name": "Island In The Moon",
  25. "description": "A place to be be playin' and havin' fun",
  26. },
  27. {"name": "Holy Buddies"},
  28. ],
  29. },
  30. {
  31. "name": "System of an Up",
  32. "items": [
  33. {
  34. "name": "Salt",
  35. "description": "The kombucha mushroom people's favorite",
  36. },
  37. {"name": "Pad Thai"},
  38. {
  39. "name": "Lonely Night",
  40. "description": "The mostests lonliest nightiest of allest",
  41. },
  42. ],
  43. },
  44. ]

You can combine dataclasses with other type annotations in many different combinations to form complex data structures.

Check the in-code annotation tips above to see more specific details.

Learn More

You can also combine dataclasses with other Pydantic models, inherit from them, include them in your own models, etc.

To learn more, check the Pydantic docs about dataclasses.

Version

This is available since FastAPI version 0.67.0. 🔖