IFX-trace-implementation / api /scripts /model_player.py
ryanbalch's picture
finalizing top level metadata; storing things in vectorstore
4c91492
Raw History Blame Contribute Delete
3.9 kB
import os
import json
from pydantic import BaseModel, Field, ValidationError
from typing import Literal, Optional, ClassVar
import hashlib
from slugify import slugify
class Player(BaseModel):
teams: ClassVar[list[str]] = ['Fraser Valley United', 'Everglade FC', 'Yucatan Force', 'Tierra Alta FC']
number: int
name: str
age: int
nationality: str
shirt_number: int
position: Literal[
"Goalkeeper", "Left Back", "Center Back", "Right Back",
"Full Back", "Defensive Mid", "Central Mid", "Attacking Mid",
"Left Wing", "Right Wing", "Forward/Winger", "Striker", "Various"
]
preferred_foot: Literal["Left", "Right", "Mixed"]
role: Literal["Starter", "Bench", "Reserve/Prospect"]
@property
def id(self):
if not self.team:
raise ValueError("Team must not be empty")
# return hashlib.sha256(f"{self.team}_{self.number}".encode()).hexdigest()
return slugify(f"{self.team}_{self.number}")
@property
def filename(self):
return f'{self.team.replace(" ", "_")}_{self.number}.json'
# Optional flair / simulation fields
team: Optional[str] = None
height_cm: Optional[int] = Field(None, ge=150, le=210)
weight_kg: Optional[int] = Field(None, ge=50, le=110)
overall_rating: Optional[int] = Field(None, ge=1, le=100)
is_injured: Optional[bool] = False
form: Optional[int] = Field(None, ge=1, le=10) # recent performance (1-10)
# Stats placeholder — useful if you want to track across games
goals: Optional[int] = 0
assists: Optional[int] = 0
yellow_cards: Optional[int] = 0
red_cards: Optional[int] = 0
# Narrative hook
bio: Optional[str] = None
# AI-generated profile pic
profile_pic: Optional[str] = None
@classmethod
def from_row(cls, row):
if len(row) != 8:
raise ValueError("Row must have 8 elements")
return cls(
number=row[0],
name=row[1],
position=row[2],
age=row[3],
nationality=row[4],
shirt_number=row[5],
preferred_foot=row[6],
role=row[7],
)
def player_info(self):
return {
"number": self.number,
"name": self.name,
"position": self.position,
"age": self.age,
"nationality": self.nationality,
"shirt_number": self.shirt_number,
"preferred_foot": self.preferred_foot,
"role": self.role,
}
def player_vector_metadata(self):
return {
"type": "player",
"number": self.number,
"name": slugify(self.name),
"position": slugify(self.position),
"age": self.age,
"nationality": slugify(self.nationality),
"shirt_number": self.shirt_number,
"preferred_foot": slugify(self.preferred_foot),
"role": slugify(self.role),
"team": slugify(self.team),
}
def save(self):
with open(os.path.join("/workspace/data/huge-league/players", self.filename), 'w') as f:
json.dump(self.model_dump(), f)
@classmethod
def load(cls, filename):
with open(os.path.join("/workspace/data/huge-league/players", filename), 'r') as f:
data = json.load(f)
return cls.model_validate(data)
@classmethod
def get_players(cls, team=None):
for filename in os.listdir("/workspace/data/huge-league/players"):
player = cls.load(filename)
if team and player.team != team:
continue
yield player
def save_image(self, image_bytes):
filename = self.filename.replace(".json", ".png")
with open(os.path.join("/workspace/data/huge-league/players_pics", filename), 'wb') as f:
f.write(image_bytes)