about things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

serialization#

model_dump#

convert a model to a dict. control what's included:

class Track(BaseModel):
    id: int
    title: str
    artist_did: str
    internal_score: float

track.model_dump()  # all fields
track.model_dump(exclude={"internal_score"})  # omit internal fields
track.model_dump(include={"id", "title"})  # only these
track.model_dump(mode="json")  # json-compatible types (datetimes → strings)

mode="json" is important — without it, you get python objects (datetime, Decimal). with it, everything is JSON-serializable.

model_dump_json / model_validate_json#

skip the dict intermediary for performance:

# serialize directly to JSON string
json_str = track.model_dump_json()

# deserialize directly from JSON string
track = Track.model_validate_json(json_str)

faster than json.dumps(track.model_dump()) because pydantic uses rust-based serialization internally.

useful for Redis caching:

await redis.set(cache_key, response.model_dump_json(), ex=300)

cached = await redis.get(cache_key)
if cached:
    return AlbumResponse.model_validate_json(cached)

computed fields#

fields derived from other fields, included in serialization but not accepted as input:

from pydantic import BaseModel, computed_field

class Album(BaseModel):
    tracks: list[Track]

    @computed_field
    @property
    def track_count(self) -> int:
        return len(self.tracks)

    @computed_field
    @property
    def total_duration(self) -> float:
        return sum(t.duration for t in self.tracks)

shows up in model_dump() and JSON output. not stored, always recomputed.

TypeAdapter for ad-hoc validation#

validate data without defining a full model:

from pydantic import TypeAdapter

int_adapter = TypeAdapter(int)
int_adapter.validate_python("42")  # → 42
int_adapter.validate_python("abc")  # → ValidationError

# useful for parsing env var fragments
StatusCode = Annotated[int, Field(ge=100, le=599)]
code_adapter = TypeAdapter(StatusCode)
code_adapter.validate_python(429)  # → 429
code_adapter.validate_python(999)  # → ValidationError

also handles complex types: TypeAdapter(list[int]), TypeAdapter(dict[str, float]).

response models in FastAPI#

FastAPI uses pydantic models for automatic request validation and response serialization:

class PlaylistResponse(BaseModel):
    id: str
    name: str
    track_count: int
    created_at: str

@router.get("/playlists/{id}", response_model=PlaylistResponse)
async def get_playlist(id: str) -> PlaylistResponse:
    ...

the response_model strips any extra fields from the return value — useful when your internal object has more data than the API should expose.

sources: