When working with APIs or configuration files, it’s common to receive raw JSON data that needs to be parsed into structured Pydantic models. However, Pydantic’s model_validate_json() can behave unexpectedly when your data is already a Python list or dictionary.
Let’s take a simple example.
from pydantic import BaseModel, Field
class UserDTO(BaseModel):
"""Model for user information."""
name: str = Field(..., description="Full name of the user")
email: str = Field(..., description="Email address of the user")
Suppose you receive this data from an API:
users = [
{"name": "Alice", "email": "alice@example.com"},
{"name": "Bob", "email": "bob@example.com"},
]
If you try this:
UserDTO.model_validate_json(users)
it won’t work, because model_validate_json() expects a JSON string, not a Python list or dict.
Option 1: Parsing from Python objects
If your JSON is already parsed into Python objects (for example, using json.loads()), use model_validate() or TypeAdapter.validate_python():
from pydantic import TypeAdapter
# Parse each item individually
models = [UserDTO.model_validate(item) for item in users]
# Or parse the entire list at once
adapter = TypeAdapter(list[UserDTO])
models = adapter.validate_python(users)
Option 2: Parsing directly from JSON
If you have the raw JSON string instead:
json_data = '[{"name": "Alice", "email": "alice@example.com"}]'
you can parse it in one step:
from pydantic import TypeAdapter
adapter = TypeAdapter(list[UserDTO])
models = adapter.validate_json(json_data)
Optional: Using a wrapper model
If you want a cleaner interface, you can define a wrapper model that represents a list of items:
class UserList(BaseModel):
__root__: list[UserDTO]
Now you can parse JSON directly:
UserList.model_validate_json(json_data)
and get structured, typed models ready for use.
Conclusion
- Use
model_validate()for Python dicts/lists - Use
model_validate_json()for raw JSON strings - Use
TypeAdapteror wrapper models for lists of objects
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.