Convert REST API Response JSON to Python Classes
Learn how to convert a complete REST API response with metadata, pagination, and nested data into a hierarchy of Python dataclasses or Pydantic models.
Detailed Explanation
Modeling a Full API Response in Python
Production API responses include metadata, pagination, error envelopes, and nested resources. Converting these into Python types requires a systematic approach.
Example JSON
{
"status": "ok",
"data": {
"users": [
{"id": 1, "name": "Alice", "email": "alice@example.com"},
{"id": 2, "name": "Bob", "email": "bob@example.com"}
]
},
"pagination": {
"page": 1,
"per_page": 20,
"total": 152,
"total_pages": 8
}
}
Generated Python (Dataclass)
from dataclasses import dataclass
@dataclass
class User:
id: int
name: str
email: str
@dataclass
class UserData:
users: list[User]
@dataclass
class Pagination:
page: int
per_page: int
total: int
total_pages: int
@dataclass
class ApiResponse:
status: str
data: UserData
pagination: Pagination
Generated Python (Pydantic)
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
class UserData(BaseModel):
users: list[User]
class Pagination(BaseModel):
page: int
per_page: int
total: int
total_pages: int
class ApiResponse(BaseModel):
status: str
data: UserData
pagination: Pagination
Generic Response Wrapper
For APIs that use the same envelope for every endpoint:
from typing import Generic, TypeVar
T = TypeVar("T")
@dataclass
class ApiResponse(Generic[T]):
status: str
data: T
pagination: Pagination
# Usage
response: ApiResponse[UserData] = ...
Error Handling
APIs return different shapes for errors:
from typing import Optional
@dataclass
class ApiError:
code: str
message: str
@dataclass
class ApiResponse(Generic[T]):
status: str
data: Optional[T] = None
pagination: Optional[Pagination] = None
error: Optional[ApiError] = None
Deserialization with dacite
from dacite import from_dict
response = from_dict(data_class=ApiResponse, data=json.loads(raw_json))
for user in response.data.users:
print(user.name)
Best Practices
- Define leaf types first —
User, thenUserData, thenApiResponse. - Extract reusable types —
Paginationis shared across endpoints. - Use generics for wrappers — Avoid duplicating the envelope for each resource.
Use Case
You are building a Python SDK for a REST API and need a complete type hierarchy that models success responses, error responses, and pagination metadata for every endpoint.
Try It — JSON to Python Converter
Related Topics
Convert Nested JSON Objects to Python Dataclasses
Dataclasses
Convert JSON to a Pydantic BaseModel in Python
Pydantic & TypedDict
Convert JSON Arrays to Python List Type Annotations
Type Annotations
Handle Optional and Nullable JSON Fields in Python
Type Annotations
Create Custom JSON Encoders for Python Dataclasses
Serialization