ryanbalch's picture
finalizing top level metadata; storing things in vectorstore
4c91492
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)