From dd027f7fa02ac20bc579471e229abe4704ab80f4 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Tue, 25 Jul 2023 00:19:33 -0500 Subject: [PATCH] Added /games --- app/db_engine.py | 4 +- app/main.py | 3 +- app/routers_v3/stratgame.py | 154 ++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 app/routers_v3/stratgame.py diff --git a/app/db_engine.py b/app/db_engine.py index c7d50de..a6632c6 100644 --- a/app/db_engine.py +++ b/app/db_engine.py @@ -1840,7 +1840,7 @@ class Injury(BaseModel): class StratGame(BaseModel): season = IntegerField() week = IntegerField() - game_num = IntegerField() + game_num = IntegerField(null=True) season_type = CharField(default='regular') away_team = ForeignKeyField(Team) home_team = ForeignKeyField(Team) @@ -1935,6 +1935,6 @@ class StratPlay(BaseModel): db.create_tables([ Current, Division, Manager, Team, Result, Player, Schedule, Transaction, BattingStat, PitchingStat, Standings, - BattingCareer, PitchingCareer, FieldingCareer, Manager, Award, DiceRoll, DraftList, Keeper + BattingCareer, PitchingCareer, FieldingCareer, Manager, Award, DiceRoll, DraftList, Keeper, StratGame ]) db.close() diff --git a/app/main.py b/app/main.py index 3376bd6..9a49df8 100644 --- a/app/main.py +++ b/app/main.py @@ -7,7 +7,7 @@ from fastapi import Depends, FastAPI, Request # from fastapi.openapi.utils import get_openapi from .routers_v3 import current, players, results, schedules, standings, teams, transactions, battingstats, \ - pitchingstats, fieldingstats, draftpicks, draftlist, managers, awards, draftdata, keepers + pitchingstats, fieldingstats, draftpicks, draftlist, managers, awards, draftdata, keepers, stratgame date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' log_level = logging.INFO if os.environ.get('LOG_LEVEL') == 'INFO' else 'WARN' @@ -38,6 +38,7 @@ app.include_router(managers.router) app.include_router(awards.router) app.include_router(draftdata.router) app.include_router(keepers.router) +app.include_router(stratgame.router) # @app.get("/docs", include_in_schema=False) diff --git a/app/routers_v3/stratgame.py b/app/routers_v3/stratgame.py new file mode 100644 index 0000000..a629008 --- /dev/null +++ b/app/routers_v3/stratgame.py @@ -0,0 +1,154 @@ +from fastapi import APIRouter, Depends, HTTPException, Query +from typing import List, Optional, Literal +import copy +import logging +import pydantic + +from ..db_engine import db, StratGame, Team, model_to_dict, chunked, fn +from ..dependencies import oauth2_scheme, valid_token + +router = APIRouter( + prefix='/api/v3/games', + tags=['games'] +) + + +class GameModel(pydantic.BaseModel): + season: int + week: int + game_num: Optional[int] = None + season_type: Optional[str] = 'regular' + away_team_id: int + home_team_id: int + away_score: Optional[int] = None + home_score: Optional[int] = None + + +class GameList(pydantic.BaseModel): + games: List[GameModel] + + +@router.get('') +async def get_games( + season: list = Query(default=None), week: list = Query(default=None), game_num: list = Query(default=None), + season_type: Literal['regular', 'post', 'all'] = 'all', away_team_id: list = Query(default=None), + home_team_id: list = Query(default=None), week_start: Optional[int] = None, week_end: Optional[int] = None, + team1_id: list = Query(default=None), team2_id: list = Query(default=None), played: Optional[bool] = None, + short_output: Optional[bool] = False): + all_games = StratGame.select() + + if season is not None: + all_games = all_games.where(StratGame.season << season) + if week is not None: + all_games = all_games.where(StratGame.week << week) + if game_num is not None: + all_games = all_games.where(StratGame.game_num << game_num) + if season_type != 'all': + all_games = all_games.where(StratGame.season_type == season_type) + if away_team_id is not None: + all_games = all_games.where(StratGame.away_team_id << away_team_id) + if home_team_id is not None: + all_games = all_games.where(StratGame.home_team_id << home_team_id) + if week_start is not None: + all_games = all_games.where(StratGame.week >= week_start) + if week_end is not None: + all_games = all_games.where(StratGame.week <= week_end) + if team1_id is not None: + all_games = all_games.where( + (StratGame.away_team_id << team1_id) | (StratGame.home_team_id << team1_id) + ) + if team2_id is not None: + all_games = all_games.where( + (StratGame.away_team_id << team2_id) | (StratGame.home_team_id << team2_id) + ) + if played is not None: + all_games = all_games.where(StratGame.game_num.is_null(played)) + + return_games = { + 'count': all_games.count(), + 'games': [model_to_dict(x, recurse=not short_output) for x in all_games] + } + db.close() + return return_games + + +@router.patch('/{game_id}') +async def patch_game( + game_id: int, game_num: Optional[int] = None, away_score: Optional[int] = None, + home_score: Optional[int] = None, token: str = Depends(oauth2_scheme)): + if not valid_token(token): + logging.warning(f'patch_game - Bad Token: {token}') + raise HTTPException(status_code=401, detail='Unauthorized') + + this_game = StratGame.get_or_none(StratGame.id == game_id) + if not this_game: + db.close() + raise HTTPException(status_code=404, detail=f'StratGame ID {game_id} not found') + + if game_num is not None: + if not game_num: + this_game.game_num = None + else: + this_game.game_num = game_num + if away_score is not None: + if not away_score: + this_game.away_score = None + else: + this_game.away_score = away_score + if home_score is not None: + if not home_score: + this_game.home_score = None + else: + this_game.home_score = home_score + + if this_game.save() == 1: + g_result = model_to_dict(this_game) + db.close() + return g_result + else: + db.close() + raise HTTPException(status_code=500, detail=f'Unable to patch game {game_id}') + + +@router.post('') +async def post_games(game_list: GameList, token: str = Depends(oauth2_scheme)): + if not valid_token(token): + logging.warning(f'post_games - Bad Token: {token}') + raise HTTPException(status_code=401, detail='Unauthorized') + + new_games = [] + for x in game_list.games: + if Team.get_or_none(Team.id == x.away_team_id) is None: + raise HTTPException(status_code=404, detail=f'Team ID {x.away_team_id} not found') + if Team.get_or_none(Team.id == x.home_team_id) is None: + raise HTTPException(status_code=404, detail=f'Team ID {x.home_team_id} not found') + + new_games.append(x.dict()) + + with db.atomic(): + for batch in chunked(new_games, 16): + StratGame.insert_many(batch).on_conflict_replace().execute() + db.close() + + return f'Inserted {len(new_games)} games' + + +@router.delete('/{game_id}') +async def delete_game(game_id: int, token: str = Depends(oauth2_scheme)): + if not valid_token(token): + logging.warning(f'delete_game - Bad Token: {token}') + raise HTTPException(status_code=401, detail='Unauthorized') + + this_game = StratGame.get_or_none(StratGame.id == game_id) + if not this_game: + db.close() + raise HTTPException(status_code=404, detail=f'StratGame ID {game_id} not found') + + count = this_game.delete_instance() + db.close() + + if count == 1: + return f'StratGame {game_id} has been deleted' + else: + raise HTTPException(status_code=500, detail=f'StratGame {game_id} could not be deleted') +