Files
Dennis Thiessen 181cfe6588
Some checks failed
Deploy / lint (push) Failing after 8s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped
major update
2026-02-27 16:08:09 +01:00

83 lines
2.1 KiB
Python

"""Pydantic schemas for scoring endpoints."""
from __future__ import annotations
from datetime import datetime
from pydantic import BaseModel, Field
class SubScoreResponse(BaseModel):
"""A single sub-score within a dimension breakdown."""
name: str
score: float
weight: float
raw_value: float | str | None = None
description: str = ""
class ScoreBreakdownResponse(BaseModel):
"""Breakdown of a dimension score into sub-scores."""
sub_scores: list[SubScoreResponse]
formula: str
unavailable: list[dict[str, str]] = []
class CompositeBreakdownResponse(BaseModel):
"""Breakdown of the composite score showing dimension weights and re-normalization."""
weights: dict[str, float]
available_dimensions: list[str]
missing_dimensions: list[str]
renormalized_weights: dict[str, float]
formula: str
class DimensionScoreResponse(BaseModel):
"""A single dimension score."""
dimension: str
score: float
is_stale: bool
computed_at: datetime | None = None
breakdown: ScoreBreakdownResponse | None = None
class ScoreResponse(BaseModel):
"""Full score response for a ticker: composite + all dimensions."""
symbol: str
composite_score: float | None = None
composite_stale: bool = False
weights: dict[str, float] = {}
dimensions: list[DimensionScoreResponse] = []
missing_dimensions: list[str] = []
computed_at: datetime | None = None
composite_breakdown: CompositeBreakdownResponse | None = None
class WeightUpdateRequest(BaseModel):
"""Request to update dimension weights."""
weights: dict[str, float] = Field(
...,
description="Dimension name → weight mapping. All weights must be positive.",
)
class RankingEntry(BaseModel):
"""A single entry in the rankings list."""
symbol: str
composite_score: float
dimensions: list[DimensionScoreResponse] = []
class RankingResponse(BaseModel):
"""Rankings response: tickers sorted by composite score descending."""
rankings: list[RankingEntry] = []
weights: dict[str, float] = {}