File size: 3,161 Bytes
c6abe34 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from uuid import UUID
from datetime import datetime
class PlayerStatRow(BaseModel):
no: Optional[int] = Field(None, alias="jersey_number")
player: str = Field(..., alias="name_raw")
pos: Optional[str] = Field(None, alias="position")
mins: Optional[str] = None
pts: int = 0
fg_m: int = 0
fg_a: int = 0
fg_pct: float = 0.0
fg: Optional[str] = "0-0"
tp_m: int = 0
tp_a: int = 0
tp_pct: float = 0.0
tp: Optional[str] = "0-0" # 2-pointers
thp_m: int = 0
thp_a: int = 0
thp_pct: float = 0.0
thp: Optional[str] = "0-0" # 3-pointers
ft_m: int = 0
ft_a: int = 0
ft_pct: float = 0.0
ft: Optional[str] = "0-0"
off: int = 0
def_reb: int = Field(0, alias="def")
reb: int = 0
ast: int = 0
to_cnt: int = Field(0, alias="to")
stl: int = 0
blk: int = 0
blkr: int = 0 # Blocks received
pf: int = 0
fls_on: int = 0 # Fouls on (received)
plus_minus: Optional[int] = None
index: Optional[int] = None
row_confidence: Optional[float] = None
# UI helper
is_starter: bool = False
# Auto-linking
linked_player_profile_id: Optional[UUID] = None
link_confidence: Optional[float] = None
link_reason: Optional[str] = None
model_config = {
"populate_by_name": True
}
class TeamTotalsRow(BaseModel):
pts: int = 0
fg_m: int = 0
fg_a: int = 0
fg_pct: float = 0.0
tp_m: int = 0
tp_a: int = 0
tp_pct: float = 0.0
thp_m: int = 0
thp_a: int = 0
thp_pct: float = 0.0
ft_m: int = 0
ft_a: int = 0
ft_pct: float = 0.0
off: int = 0
def_reb: int = 0
reb: int = 0
ast: int = 0
to_cnt: int = 0
stl: int = 0
blk: int = 0
pf: int = 0
fls_on: int = 0
index: int = 0
class TeamStatistics(BaseModel):
points_from_turnovers: int = 0
points_in_paint: int = 0
second_chance_points: int = 0
fast_break_points: int = 0
bench_points: int = 0
biggest_lead: int = 0
biggest_scoring_run: int = 0
class ExtractedMatchStatsPreview(BaseModel):
team_name: Optional[str] = None
coach: Optional[str] = None
assistant: Optional[str] = None
opponent_name: Optional[str] = None
match_date: Optional[str] = None
competition: Optional[str] = None
final_score_for: Optional[int] = None
final_score_against: Optional[int] = None
players: List[PlayerStatRow] = []
starters: List[PlayerStatRow] = []
bench: List[PlayerStatRow] = []
team_totals: Optional[TeamTotalsRow] = None
team_statistics: Optional[TeamStatistics] = None
overall_confidence: float = 0.0
class MatchStatUploadResponse(BaseModel):
id: UUID
match_id: UUID
organization_id: UUID
uploaded_by: UUID
storage_path: str
file_type: str
extract_status: str
extracted_json: Optional[Dict[str, Any]] = None
confidence: Optional[float] = None
created_at: datetime
updated_at: datetime
class StatsConfirmRequest(BaseModel):
extracted_json: ExtractedMatchStatsPreview
|