# SBA API Models Specification **Purpose**: Pydantic models that exactly match SBA API responses **File**: `backend/app/models/api_models.py` (SBA section) --- ## Overview SBA player data comes from **1 API call**: - `/players/:player_id?short_output=false` - Player with nested team data Much simpler than PD - no separate ratings calls needed. --- ## Base URL ```python SBA_API_BASE_URL = "https://api.sba.manticorum.com/" ``` --- ## Model Hierarchy ``` SbaPlayerApi (player data) └─ team: SbaTeamApi ├─ manager1: SbaManagerApi ├─ manager2: Optional[SbaManagerApi] └─ division: SbaDivisionApi ``` --- ## Nested Models ### SbaManagerApi **JSON Example**: ```json { "id": 3, "name": "Cal", "image": null, "headline": null, "bio": null } ``` **Pydantic Model**: ```python class SbaManagerApi(BaseModel): """SBA Manager (nested in team response)""" id: int name: str image: Optional[str] = None headline: Optional[str] = None bio: Optional[str] = None ``` ### SbaDivisionApi **JSON Example**: ```json { "id": 41, "division_name": "Big Chungus", "division_abbrev": "BBC", "league_name": "SBa", "league_abbrev": "SBa", "season": 12 } ``` **Pydantic Model**: ```python class SbaDivisionApi(BaseModel): """SBA Division (nested in team response)""" id: int division_name: str division_abbrev: str league_name: str league_abbrev: str season: int ``` ### SbaTeamApi **JSON Example**: ```json { "id": 499, "abbrev": "WV", "sname": "Black Bears", "lname": "West Virginia Black Bears", "manager_legacy": null, "division_legacy": null, "gmid": "258104532423147520", "gmid2": null, "manager1": { "id": 3, "name": "Cal", "image": null, "headline": null, "bio": null }, "manager2": null, "division": { "id": 41, "division_name": "Big Chungus", "division_abbrev": "BBC", "league_name": "SBa", "league_abbrev": "SBa", "season": 12 }, "mascot": null, "stadium": "https://i.postimg.cc/rpRZ2NNF/wvpark.png", "gsheet": null, "thumbnail": "https://i.postimg.cc/HjDc8bBF/blackbears-transparent.png", "color": "6699FF", "dice_color": null, "season": 12, "auto_draft": null } ``` **Pydantic Model**: ```python class SbaTeamApi(BaseModel): """SBA Team (nested in player response)""" id: int abbrev: str sname: str # Short name lname: str # Long name manager_legacy: Optional[str] = None division_legacy: Optional[str] = None gmid: str # Discord Guild/Manager ID gmid2: Optional[str] = None manager1: SbaManagerApi manager2: Optional[SbaManagerApi] = None division: SbaDivisionApi mascot: Optional[str] = None stadium: Optional[str] = None gsheet: Optional[str] = None thumbnail: Optional[str] = None color: str # Hex color without # dice_color: Optional[str] = None season: int auto_draft: Optional[bool] = None ``` --- ## Player Model ### SbaPlayerApi **API Endpoint**: `GET /players/:player_id?short_output=false` **JSON Example**: ```json { "id": 12288, "name": "Ronald Acuna Jr", "wara": 0.0, "image": "https://sba-cards-2024.s3.us-east-1.amazonaws.com/2024-cards/ronald-acuna-jr.png", "image2": null, "team": { "id": 499, "abbrev": "WV", "sname": "Black Bears", "lname": "West Virginia Black Bears", "manager_legacy": null, "division_legacy": null, "gmid": "258104532423147520", "gmid2": null, "manager1": { "id": 3, "name": "Cal", "image": null, "headline": null, "bio": null }, "manager2": null, "division": { "id": 41, "division_name": "Big Chungus", "division_abbrev": "BBC", "league_name": "SBa", "league_abbrev": "SBa", "season": 12 }, "mascot": null, "stadium": "https://i.postimg.cc/rpRZ2NNF/wvpark.png", "gsheet": null, "thumbnail": "https://i.postimg.cc/HjDc8bBF/blackbears-transparent.png", "color": "6699FF", "dice_color": null, "season": 12, "auto_draft": null }, "season": 12, "pitcher_injury": null, "pos_1": "RF", "pos_2": null, "pos_3": null, "pos_4": null, "pos_5": null, "pos_6": null, "pos_7": null, "pos_8": null, "last_game": null, "last_game2": null, "il_return": null, "demotion_week": 16, "headshot": null, "vanity_card": null, "strat_code": "Acuna,R", "bbref_id": "acunaro01", "injury_rating": "5p30", "sbaplayer": null } ``` **Pydantic Model**: ```python class SbaPlayerApi(BaseModel): """SBA Player API response""" id: int name: str wara: float # Wins Above Replacement Average image: str # Card image URL image2: Optional[str] = None team: SbaTeamApi season: int # Positions (up to 8) pos_1: Optional[str] = None pos_2: Optional[str] = None pos_3: Optional[str] = None pos_4: Optional[str] = None pos_5: Optional[str] = None pos_6: Optional[str] = None pos_7: Optional[str] = None pos_8: Optional[str] = None # Injury/status tracking pitcher_injury: Optional[str] = None last_game: Optional[str] = None last_game2: Optional[str] = None il_return: Optional[str] = None # Injured list return date demotion_week: Optional[int] = None # Additional metadata headshot: Optional[str] = None vanity_card: Optional[str] = None strat_code: Optional[str] = None # Strat-O-Matic code bbref_id: str # Baseball Reference ID injury_rating: Optional[str] = None # e.g., "5p30" sbaplayer: Optional[int] = None # Link to another player record? ``` --- ## Usage Example ```python import httpx from app.models.api_models import SbaPlayerApi # Fetch and deserialize player async with httpx.AsyncClient() as client: response = await client.get( "https://api.sba.manticorum.com/players/12288?short_output=false" ) player = SbaPlayerApi(**response.json()) # Access nested data with full type safety print(f"{player.name} plays for {player.team.lname}") print(f"Manager: {player.team.manager1.name}") print(f"Division: {player.team.division.division_name}") ``` --- ## Differences from PD | Aspect | SBA | PD | |--------|-----|-----| | **API Calls** | 1 call | 3 calls (player + batting + pitching) | | **Primary Key** | `id` | `player_id` | | **Name Field** | `name` | `p_name` | | **Team Data** | Full nested object | Just `mlbclub` string | | **Ratings** | None (simplified gameplay) | Detailed outcome probabilities | | **Complexity** | Simple | Complex | --- ## Notes 1. **Single API call**: Much simpler than PD - all data in one response 2. **Rich team data**: Full team/manager/division hierarchy included 3. **No ratings**: SBA uses simplified result charts, not detailed probabilities 4. **Position handling**: Same pos_1-8 pattern as PD 5. **Injury tracking**: Additional fields for roster management (IL, demotion) --- **Next**: See [game-models.md](./game-models.md) for game-optimized player models