175 lines
6.4 KiB
Python
175 lines
6.4 KiB
Python
from pydantic import BaseModel, Field
|
|
from typing import Optional
|
|
|
|
|
|
# ──────────────────────────────────────────────
|
|
# Core review models
|
|
# ──────────────────────────────────────────────
|
|
|
|
class Review(BaseModel):
|
|
"""A single review of a movie, book, or television show."""
|
|
|
|
date: str = Field(
|
|
...,
|
|
description="Date the review was recorded, in YYYY-MM-DD format.",
|
|
examples=["2025-02-06"],
|
|
)
|
|
unixTime: int = Field(
|
|
...,
|
|
description="Unix timestamp corresponding to the review date.",
|
|
examples=[1738796400],
|
|
)
|
|
category: Optional[str] = Field(
|
|
None,
|
|
description="Media type: Movies, Books, or Television.",
|
|
examples=["Movies"],
|
|
)
|
|
title: Optional[str] = Field(
|
|
None,
|
|
description="Title of the work being reviewed.",
|
|
examples=["The Brutalist"],
|
|
)
|
|
creator: Optional[str] = Field(
|
|
None,
|
|
description="Director, author, or showrunner of the work.",
|
|
examples=["Brady Corbet"],
|
|
)
|
|
genre: Optional[str] = Field(
|
|
None,
|
|
description="Genre classification of the work.",
|
|
examples=["Drama"],
|
|
)
|
|
rating: Optional[float] = Field(
|
|
None,
|
|
description="Rating on a scale from -3.0 (worst) to 3.0 (best). A rating of 0.0 indicates a neutral opinion (it was meh).",
|
|
examples=[3.0],
|
|
)
|
|
review: Optional[str] = Field(
|
|
None,
|
|
description="Free-text review. Empty string or '.' indicates no written review.",
|
|
examples=[
|
|
"A wonderfully expansive film about the immigrant experience."
|
|
],
|
|
)
|
|
|
|
year: Optional[int] = Field(
|
|
None,
|
|
description="Release or publication year of the work.",
|
|
examples=[2024],
|
|
)
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ReviewListResponse(BaseModel):
|
|
"""Paginated response wrapper for a list of reviews."""
|
|
|
|
total: int = Field(
|
|
...,
|
|
description="Total number of reviews matching the query filters.",
|
|
examples=[642],
|
|
)
|
|
limit: int = Field(
|
|
...,
|
|
description="Maximum number of reviews returned in this response.",
|
|
examples=[20],
|
|
)
|
|
offset: int = Field(
|
|
...,
|
|
description="Number of reviews skipped from the start of the result set.",
|
|
examples=[0],
|
|
)
|
|
results: list[Review] = Field(
|
|
...,
|
|
description="The reviews for the current page.",
|
|
)
|
|
|
|
|
|
# ──────────────────────────────────────────────
|
|
# Discovery models
|
|
# ──────────────────────────────────────────────
|
|
|
|
class CategoryCount(BaseModel):
|
|
"""A category with its review count."""
|
|
|
|
category: str = Field(..., description="The media category name.", examples=["Movies"])
|
|
count: int = Field(..., description="Number of reviews in this category.", examples=[412])
|
|
|
|
|
|
class GenreCount(BaseModel):
|
|
"""A genre with its review count."""
|
|
|
|
genre: str = Field(..., description="The genre name.", examples=["Science Fiction"])
|
|
count: int = Field(..., description="Number of reviews in this genre.", examples=[58])
|
|
|
|
|
|
class CreatorCount(BaseModel):
|
|
"""A creator with their review count."""
|
|
|
|
creator: str = Field(..., description="Name of the director, author, or showrunner.", examples=["Steven Spielberg"])
|
|
count: int = Field(..., description="Number of works by this creator that have been reviewed.", examples=[7])
|
|
|
|
|
|
# ──────────────────────────────────────────────
|
|
# Stats models
|
|
# ──────────────────────────────────────────────
|
|
|
|
class CategoryBreakdown(BaseModel):
|
|
"""Review count for a single category."""
|
|
|
|
category: str = Field(..., examples=["Movies"])
|
|
count: int = Field(..., examples=[412])
|
|
|
|
|
|
class OverviewStats(BaseModel):
|
|
"""High-level statistics across all reviews."""
|
|
|
|
total_reviews: int = Field(..., description="Total number of reviews in the database.", examples=[642])
|
|
categories: list[CategoryBreakdown] = Field(..., description="Number of reviews per category.")
|
|
average_rating: float = Field(..., description="Mean rating across all reviews.", examples=[1.02])
|
|
earliest_review: str = Field(..., description="Date of the oldest review.", examples=["2001-06-29"])
|
|
latest_review: str = Field(..., description="Date of the most recent review.", examples=["2025-02-09"])
|
|
|
|
|
|
class CreatorStats(BaseModel):
|
|
"""A creator ranked by number of reviewed works."""
|
|
|
|
creator: str = Field(..., description="Name of the creator.", examples=["Steven Spielberg"])
|
|
review_count: int = Field(..., description="Number of reviewed works by this creator.", examples=[7])
|
|
average_rating: float = Field(..., description="Mean rating across this creator's reviewed works.", examples=[1.57])
|
|
|
|
|
|
class GenreStats(BaseModel):
|
|
"""A genre with aggregated review statistics."""
|
|
|
|
genre: str = Field(..., description="The genre name.", examples=["Science Fiction"])
|
|
review_count: int = Field(..., description="Number of reviews in this genre.", examples=[58])
|
|
average_rating: float = Field(..., description="Mean rating for reviews in this genre.", examples=[1.24])
|
|
|
|
|
|
class YearActivity(BaseModel):
|
|
"""Review activity for a single year."""
|
|
|
|
year: str = Field(..., description="The four-digit year.", examples=["2025"])
|
|
review_count: int = Field(..., description="Number of reviews recorded in this year.", examples=[3])
|
|
average_rating: float = Field(..., description="Mean rating for reviews in this year.", examples=[1.67])
|
|
|
|
|
|
class DecadeStats(BaseModel):
|
|
"""Review activity grouped by the decade the work was released."""
|
|
|
|
decade: str = Field(
|
|
...,
|
|
description="The decade label (e.g. '1990s').",
|
|
examples=["1990s"],
|
|
)
|
|
review_count: int = Field(
|
|
...,
|
|
description="Number of reviewed works released in this decade.",
|
|
examples=[45],
|
|
)
|
|
average_rating: float = Field(
|
|
...,
|
|
description="Mean rating for works released in this decade.",
|
|
examples=[1.35],
|
|
)
|