from db_engine import * import datetime import logging import os from typing import Optional, List from fastapi import FastAPI, HTTPException, Depends, Response from fastapi.security import OAuth2PasswordBearer import pydantic from playhouse.shortcuts import model_to_dict from pandas import DataFrame # TODO: remove block comments from GET /schedules and /transactions 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' logging.basicConfig( filename=f'logs/database/{date}.log', format='%(asctime)s - database - %(levelname)s - %(message)s', level=log_level ) SEASON_DEFAULT = 7 db.create_tables([Current, Division, Manager, Team, Result, Player, Schedule, Transaction, BattingStat, PitchingStat, Standings, BattingCareer, PitchingCareer, FieldingCareer, Manager, Award, DiceRoll, DraftList]) db.close() app = FastAPI() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def valid_token(token): if token == os.environ.get('API_TOKEN'): return True else: return False class PlayerPydantic(pydantic.BaseModel): name: str wara: float image: str image2: Optional[str] = None team_id: int season: int pitcher_injury: Optional[int] = None pos_1: str 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 last_game: Optional[str] = None last_game2: Optional[str] = None il_return: Optional[str] = None demotion_week: Optional[int] = None strat_code: Optional[str] = None bbref_id: Optional[str] = None injury_rating: Optional[str] = None class PlayerModel(pydantic.BaseModel): players: List[PlayerPydantic] class ResultModel(pydantic.BaseModel): week: int game: int away_team_id: int home_team_id: int away_score: int home_score: int season: int scorecard_url: Optional[str] = None class BatStat(pydantic.BaseModel): player_id: int team_id: int pos: str pa: int ab: int run: int hit: int rbi: int double: int triple: int hr: int bb: int so: int hbp: int sac: int ibb: int gidp: int sb: int cs: int bphr: int bpfo: int bp1b: int bplo: int xba: int xbt: int xch: int xhit: int error: int pb: int sbc: int csc: int roba: int robs: int raa: int rto: int week: int game: int season: int class BattingStatModel(pydantic.BaseModel): count: int stats: List[BatStat] class PitStat(pydantic.BaseModel): player_id: int team_id: int ip: float hit: int run: int erun: int so: int bb: int hbp: int wp: int balk: int hr: int gs: int win: int loss: int hold: int sv: int bsv: int ir: int irs: int week: int game: int season: int class PitchingStatModel(pydantic.BaseModel): count: int stats: List[PitStat] class GameModel(pydantic.BaseModel): season: int week: int away_team_id: int home_team_id: int game_num: int class TransactionPydantic(pydantic.BaseModel): week: int player_id: int oldteam_id: int newteam_id: int season: int moveid: str cancelled: Optional[bool] = False frozen: Optional[bool] = False class TransModel(pydantic.BaseModel): count: int moves: List[TransactionPydantic] class DraftPickPydantic(pydantic.BaseModel): overall: Optional[int] = None round: int origowner_id: int owner_id: Optional[int] = None season: int player_id: Optional[int] = None class DraftPickModel(pydantic.BaseModel): picks: List[DraftPickPydantic] class ManagerModel(pydantic.BaseModel): name: str image: Optional[str] = None headline: Optional[str] = None bio: Optional[str] = None class AwardPydantic(pydantic.BaseModel): name: str season: int timing: Optional[str] = "In-Season" manager1_id: Optional[int] = None manager2_id: Optional[int] = None player_id: Optional[int] = None team_id: Optional[int] = None image: Optional[str] = None class AwardModel(pydantic.BaseModel): count: int awards: List[AwardPydantic] class DiceRollPydantic(pydantic.BaseModel): season: int week: int team_id: int roller: int dsix: Optional[int] twodsix: Optional[int] threedsix: Optional[int] dtwenty: Optional[int] class DiceModel(pydantic.BaseModel): count: int rolls: List[DiceRollPydantic] class DraftListPydantic(pydantic.BaseModel): season: int team_id: int rank: int player_id: int class DraftListModel(pydantic.BaseModel): count: int draft_list: List[DraftListPydantic] class SchedulePydantic(pydantic.BaseModel): week: int away_team_id: int home_team_id: int game_count: int season: int class ScheduleModel(pydantic.BaseModel): count: int schedules: List[SchedulePydantic] class TeamModel(pydantic.BaseModel): abbrev: str sname: str lname: str gmid: Optional[int] = None gmid2: Optional[int] = None manager1_id: Optional[int] = None manager2_id: Optional[int] = None division_id: Optional[int] = None stadium: Optional[str] = None thumbnail: Optional[str] = None color: Optional[str] = None dice_color: Optional[str] = None season: int class CurrentModel(pydantic.BaseModel): week: Optional[int] = 0 freeze: Optional[bool] = False season: int transcount: Optional[int] = 0 bstatcount: Optional[int] = 0 pstatcount: Optional[int] = 0 bet_week: Optional[int] = 0 trade_deadline: int pick_trade_start: int pick_trade_end: int playoffs_begin: int injury_count: Optional[int] = 0 @app.get('/api/v1/current') async def v1_current(season: Optional[int] = None, return_type: Optional[str] = 'json'): if season: current = Current.get_or_none(season=season) else: current = Current.latest() if return_type == 'csv': current_list = [ ['season', 'week', 'trade deadline', 'pick trade start', 'pick trade end', 'playoffs begin', 'injury count'], [current.season, current.week, current.trade_deadline, current.pick_trade_start, current.pick_trade_end, current.playoffs_begin, current.injury_count] ] return_current = DataFrame(current_list).to_csv(header=False, index=False) db.close() return Response(content=return_current, media_type='text/csv') else: db.close() return model_to_dict(current) @app.patch('/api/v1/current') async def v1_current_patch( season: Optional[int] = SEASON_DEFAULT, week: Optional[int] = None, freeze: Optional[bool] = None, transcount: Optional[int] = None, bstatcount: Optional[int] = None, pstatcount: Optional[int] = None, bet_week: Optional[int] = None, trade_deadline: Optional[int] = None, pick_trade_start: Optional[int] = None, pick_trade_end: Optional[int] = None, injury_count: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post current') current = Current.get_or_none(season=season) if not current: db.close() raise HTTPException(status_code=404, detail=f'Current for season {season} not found') if week is not None: current.week = week if freeze is not None: current.freeze = freeze if transcount is not None: current.transcount = transcount if bstatcount is not None: current.bstatcount = bstatcount if pstatcount is not None: current.pstatcount = pstatcount if bet_week is not None: current.bet_week = bet_week if trade_deadline is not None: current.trade_deadline = trade_deadline if pick_trade_start is not None: current.pick_trade_start = pick_trade_start if pick_trade_end is not None: current.pick_trade_end = pick_trade_end if injury_count is not None: current.injury_count = injury_count current.save() db.close() return model_to_dict(current) @app.post('/api/v1/current') async def v1_current_post(current: CurrentModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post current') this_current = Current( week=current.week, freeze=current.freeze, season=current.season, transcount=current.transcount, bstatcount=current.bstatcount, pstatcount=current.pstatcount, bet_week=current.bet_week, trade_deadline=current.trade_deadline, pick_trade_start=current.pick_trade_start, pick_trade_end=current.pick_trade_end, playoffs_begin=current.playoffs_begin, injury_count=current.injury_count ) saved = this_current.save() db.close() if saved == 1: return model_to_dict(this_current) else: raise HTTPException(status_code=418, detail='Well slap my ass and call me a teapot. I could not post that.') @app.get('/api/v1/teams') async def v1_teams_get( season: Optional[int] = None, owner_id: Optional[int] = None, manager_id: Optional[int] = None, active_only: Optional[bool] = False, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ Param: season: int Param: team_abbrev: string Param: owner_id: int """ if season: all_teams = Team.select_season(season) else: all_teams = Team.select() if manager_id: print(f'query: {all_teams}') try: this_manager = Manager.get_by_id(manager_id) except: db.close() raise HTTPException(status_code=404, detail=f'Manager ID {manager_id} not found') all_teams = all_teams.where( (Team.manager1 == this_manager) | (Team.manager2 == this_manager) ).order_by(-Team.season) if owner_id: all_teams = all_teams.where((Team.gmid == owner_id) | (Team.gmid2 == owner_id)) if active_only: all_teams = all_teams.where( ~(Team.abbrev.endswith('IL')) & ~(Team.abbrev.endswith('MiL')) ) if all_teams.count() == 0: db.close() logging.error(f'No teams found\n\nseason: {season} / {owner_id}') raise HTTPException(status_code=404, detail=f'Season {season} not found') if return_type == 'csv' or csv: teams_list = [['abbrev', 'sname', 'lname', 'league', 'division', 'stadium', 'manager1', 'manager2', 'thumbnail', 'color', 'season', 'dice_color', 'id']] for line in all_teams: teams_list.append( [ line.abbrev, line.sname, line.lname, line.division.league_abbrev if line.division else '', line.division.division_name if line.division else '', line.stadium, line.manager1.name if line.manager1 else '', line.manager2.name if line.manager2 else '', line.thumbnail, line.color, line.season, line.dice_color, line.id ] ) return_teams = DataFrame(teams_list).to_csv(header=False, index=False) db.close() return Response(content=return_teams, media_type='text/csv') else: return_teams = {'count': all_teams.count(), 'teams': []} for team in all_teams: return_teams['teams'].append(model_to_dict(team)) db.close() return return_teams @app.get('/api/v1/teams/{id_or_abbrev}') async def v1_teams_get_one(id_or_abbrev, season: Optional[int] = SEASON_DEFAULT): try: this_team = Team.get_by_id(id_or_abbrev) except Exception as e: if season: this_team = Team.get_season(id_or_abbrev, season) else: this_team = Team.get_season(id_or_abbrev, Current.latest().season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {id_or_abbrev} not found') else: db.close() return model_to_dict(this_team) @app.get('/api/v1/teams/{id_or_abbrev}/roster/{which}') async def v1_teams_get_roster(id_or_abbrev, which, sort: Optional[str] = None): try: this_team = Team.get_by_id(id_or_abbrev) except Exception as e: this_team = Team.get_season(id_or_abbrev, SEASON_DEFAULT) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {id_or_abbrev} not found') if which != 'current' and which != 'next': db.close() raise HTTPException(status_code=404, detail=f'Missing /current or /next') if which == 'current': full_roster = this_team.get_this_week() else: full_roster = this_team.get_next_week() active_players = copy.deepcopy(full_roster['active']['players']) sil_players = copy.deepcopy(full_roster['shortil']['players']) lil_players = copy.deepcopy(full_roster['longil']['players']) full_roster['active']['players'] = [] full_roster['shortil']['players'] = [] full_roster['longil']['players'] = [] for player in active_players: full_roster['active']['players'].append(model_to_dict(player)) for player in sil_players: full_roster['shortil']['players'].append(model_to_dict(player)) for player in lil_players: full_roster['longil']['players'].append(model_to_dict(player)) if sort: if sort == 'wara-desc': full_roster['active']['players'].sort(key=lambda p: p["wara"], reverse=True) full_roster['active']['players'].sort(key=lambda p: p["wara"], reverse=True) full_roster['active']['players'].sort(key=lambda p: p["wara"], reverse=True) db.close() return full_roster @app.get('/api/v1/teams/{id_or_abbrev}/record/{week_num}') async def v1_teams_get_record(id_or_abbrev, week_num: int): try: this_team = Team.get_by_id(id_or_abbrev) except Exception as e: this_team = Team.get_season(id_or_abbrev, Current.latest().season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {id_or_abbrev} not found') db.close() return this_team.get_record(week=week_num) @app.patch('/api/v1/teams/{team_id}') async def v1_teams_patch( team_id, manager1_id: Optional[int] = None, manager2_id: Optional[int] = None, gmid: Optional[int] = None, gmid2: Optional[int] = None, mascot: Optional[str] = None, stadium: Optional[str] = None, thumbnail: Optional[str] = None, color: Optional[str] = None, abbrev: Optional[str] = None, sname: Optional[str] = None, lname: Optional[str] = None, dice_color: Optional[str] = None, division_id: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch teams') try: this_team = Team.get_by_id(team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {team_id}') if abbrev is not None: this_team.abbrev = abbrev if manager1_id is not None: if manager1_id == 0: this_team.manager1 = None else: try: this_manager = Manager.get_by_id(manager1_id) this_team.manager1 = this_manager except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No manager found with id {manager1_id}') if manager2_id is not None: print('in mgr2') if manager2_id == 0: print('deleting mgr2') this_team.manager2 = None else: try: print('trying mgr2') this_manager = Manager.get_by_id(manager2_id) this_team.manager2 = this_manager print('set mgr2') except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No manager found with id {manager2_id}') if gmid is not None: this_team.gmid = gmid if gmid2 is not None: if gmid2 == 0: this_team.gmid2 = None else: this_team.gmid2 = gmid2 if mascot is not None: if mascot == 'False': this_team.mascot = None else: this_team.mascot = mascot if stadium is not None: this_team.stadium = stadium if thumbnail is not None: this_team.thumbnail = thumbnail if color is not None: this_team.color = color if dice_color is not None: this_team.dice_color = dice_color if sname is not None: this_team.sname = sname if lname is not None: this_team.lname = lname if division_id is not None: if division_id == 0: this_team.division = None else: try: this_division = Division.get_by_id(division_id) this_team.division = this_division except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No division found with id {division_id}') if this_team.save(): db.close() return model_to_dict(this_team) else: db.close() raise HTTPException(status_code=400, detail='This update did not go through') @app.post('/api/v1/teams') async def v1_teams_post(team: TeamModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post teams') dupe_team = Team.get_or_none(Team.season == team.season, Team.abbrev == team.abbrev) if dupe_team: db.close() raise HTTPException(status_code=400, detail=f'There is already a season {team.season} team using {team.abbrev}') manager1 = None if team.manager1_id: try: manager1 = Manager.get_by_id(team.manager1_id) except: db.close() raise HTTPException(status_code=404, detail=f'Manager with id {team.manager1_id} not found') manager2 = None if team.manager2_id: try: manager2 = Manager.get_by_id(team.manager2_id) except: db.close() raise HTTPException(status_code=404, detail=f'Manager with id {team.manager2_id} not found') division = None if team.division_id: try: division = Division.get_by_id(team.division_id) except: db.close() raise HTTPException(status_code=404, detail=f'Division with id {team.division_id} not found') this_team = Team( season=team.season, abbrev=team.abbrev, sname=team.sname, lname=team.lname, gmid=team.gmid, gmid2=team.gmid2, manager1=manager1, manager2=manager2, division=division, stadium=team.stadium, thumbnail=team.thumbnail, color=team.color, dice_color=team.dice_color ) saved = this_team.save() db.close() if saved == 1: return model_to_dict(this_team) else: raise HTTPException(status_code=418, detail='Well slap my ass and call me a teapot; I could not save that team') @app.delete('/api/v1/teams/{team_id}') async def v1_teams_delete(team_id, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to delete teams') try: this_team = Team.get_by_id(team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {team_id}') count = this_team.delete_instance() db.close() if count == 1: raise HTTPException(status_code=200, detail=f'Team {team_id} has been deleted') else: raise HTTPException(status_code=500, detail=f'Team {team_id} was not deleted') @app.get('/api/v1/results') async def v1_results_get( season: int, team_abbrev: Optional[str] = None, week: Optional[int] = None, game: Optional[int] = None, away_abbrev: Optional[str] = None, home_abbrev: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ Param: team_abbrev: string, may not use with away_abbrev or home_abbrev Param: week: int Param: away_abbrev: string, may not use with team_abbrev Param: home_abbrev: string, may not use with team_abbrev """ all_results = Result.select_season(season) # if all_results.count() == 0: # db.close() # raise HTTPException(status_code=404, detail=f'Season {season} not found') if week: all_results = all_results.where(Result.week == week) if game: all_results = all_results.where(Result.game == game) if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_results = all_results.where( (Result.awayteam == this_team) | (Result.hometeam == this_team) ) else: if away_abbrev: this_team = Team.get_season(away_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Player {away_abbrev} not found') all_results = all_results.where(Result.awayteam == this_team) if home_abbrev: this_team = Team.get_season(home_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Player {home_abbrev} not found') all_results = all_results.where(Result.hometeam == this_team) if return_type == 'csv' or csv: helper_list = [['season', 'week', 'game_num', 'away_team', 'away_score', 'home_team', 'home_score']] for game in all_results: helper_list.append([game.season, game.week, game.game, game.awayteam.abbrev, game.awayscore, game.hometeam.abbrev, game.homescore]) return_results = DataFrame(helper_list).to_csv(header=False, index=False) db.close() return Response(content=return_results, media_type='text/csv') else: return_results = {} for game in all_results: return_results[f'{game.id}'] = model_to_dict(game) db.close() return return_results @app.post('/api/v1/results') async def v1_results_post(result: ResultModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post results') away_team = Team.get_by_id(result.away_team_id) if not away_team: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {result.away_team_id}') home_team = Team.get_by_id(result.home_team_id) if not home_team: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {result.home_team_id}') new_result = Result( week=result.week, game=result.game, awayteam=away_team, hometeam=home_team, awayscore=result.away_score, homescore=result.home_score, season=result.season, scorecard_url=result.scorecard_url ) saved = new_result.save() if saved != 1: db.close() raise HTTPException(status_code=400, detail=f'Unable to create {away_team.abbrev} @ {home_team.abbrev} ' f'w{result.week}g{result.game}') # new_result.update_standings() # away_team.run_pythag_last8() # home_team.run_pythag_last8() # # away_team.division.sort_division(new_result.season) # if away_team.division != home_team.division: # home_team.division.sort_division(new_result.season) # # away_team.division.sort_wildcard(new_result.season, away_team.division.league_abbrev) # if away_team.division.league_abbrev != home_team.division.league_abbrev: # home_team.division.sort_wildcard(new_result.season, home_team.division.league_abbrev) db.close() raise HTTPException(status_code=200, detail=f'{away_team.abbrev} @ {home_team.abbrev} ' f'w{result.week}g{result.game} has been logged') @app.patch('/api/v1/results/{result_id}') async def v1_results_patch( result_id, away_score: Optional[int] = None, home_score: Optional[int] = None, scorecard_url: Optional[str] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch results') try: this_result = Result.get_by_id(result_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Result id {result_id} not found') if away_score: this_result.awayscore = away_score if home_score: this_result.homescore = home_score if scorecard_url: this_result.scorecard_url = scorecard_url this_result.save() db.close() return model_to_dict(this_result) @app.delete('/api/v1/results/{result_id}') async def v1_results_delete(result_id, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch results') try: this_result = Result.get_by_id(result_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Result id {result_id} not found') this_result.delete_instance() db.close() raise HTTPException(status_code=200, detail=f'Deleted 1 result') @app.get('/api/v1/schedules') async def v1_schedules_get( season: Optional[int] = SEASON_DEFAULT, team_abbrev1: Optional[str] = None, team_abbrev2: Optional[str] = None, away_abbrev: Optional[str] = None, home_abbrev: Optional[str] = None, week_start: Optional[int] = None, week_end: Optional[int] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ Param: team_abbrev1: string, may not use with away_abbrev or home_abbrev Param: team_abbrev2: string, may not use with away_abbrev or home_abbrev Param: away_abbrev: string, may not use with team_abbrev1/2 Param: home_abbrev: string, may not use with team_abbrev1/2 Param: week_start: int Param: week_end: int """ if not season: season = SEASON_DEFAULT schedule = Schedule.select_season(season) # if schedule.count() == 0: # db.close() # raise HTTPException(status_code=404, detail=f'Season {season} not found') # Check for team_abbrev or away/home_abbrev if team_abbrev1 or team_abbrev2: if team_abbrev1: this_team = Team.get_season(team_abbrev1, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev1} not found') schedule = schedule.where( (Schedule.hometeam == this_team) | (Schedule.awayteam == this_team) ) if team_abbrev2: this_team = Team.get_season(team_abbrev2, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev2} not found') schedule = schedule.where( (Schedule.hometeam == this_team) | (Schedule.awayteam == this_team) ) else: if away_abbrev: this_team = Team.get_season(away_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {away_abbrev} not found') schedule = schedule.where(Schedule.awayteam == this_team) if home_abbrev: this_team = Team.get_season(home_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {home_abbrev} not found') schedule = schedule.where(Schedule.hometeam == this_team) # Check for week limits start = 0 end = Schedule.select(fn.MAX(Schedule.week)).scalar() if week_start: start = week_start if week_end: end = week_end if start > end: logging.error('Start week is after end week - cannot pull schedule') db.close() raise HTTPException(status_code=404, detail=f'Start week {start} is after end week {end} - cannot pull schedule') schedule = schedule.where( (Schedule.week >= start) & (Schedule.week <= end) ) logging.info(f'schedule query: {schedule}') if return_type == 'csv' or csv: schedule_list = [['season', 'week', 'away_abbrev', 'home_abbrev', 'game_count']] for line in schedule: schedule_list.append( [ line.season, line.week, line.awayteam.abbrev, line.hometeam.abbrev, line.gamecount ] ) return_schedule = DataFrame(schedule_list).to_csv(header=False, index=False) db.close() return Response(content=return_schedule, media_type='text/csv') else: return_schedule = {} for game in schedule: return_schedule[f'{game.id}'] = model_to_dict(game) db.close() return return_schedule @app.post('/api/v1/schedules') async def v1_schedules_post(schedule: ScheduleModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post schedules') all_scheds = [] for x in schedule.schedules: try: away_team = Team.get_by_id(x.away_team_id) if not away_team: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {x.away_team_id}') home_team = Team.get_by_id(x.home_team_id) if not home_team: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {x.home_team_id}') this_sched = Schedule( season=x.season, week=x.week, awayteam=away_team, hometeam=home_team, gamecount=x.game_count ) all_scheds.append(this_sched) except: db.close() raise HTTPException( status_code=404, detail=f'Failed to enter Team {x.away_team_id} @ Team {x.home_team_id}' ) with db.atomic(): Schedule.bulk_create(all_scheds, batch_size=20) db.close() raise HTTPException(status_code=200, detail=f'Added {schedule.count} game{"s" if schedule.count > 1 else ""}') @app.patch('/api/v1/schedules/{schedule_id}') async def v1_schedules_patch( schedule_id: int, week: Optional[int] = None, away_team_id: Optional[int] = None, home_team_id: Optional[int] = None, game_count: Optional[int] = None, season: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch schedules') this_schedule = None try: this_schedule = Schedule.get_by_id(schedule_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No schedule found with id {schedule_id}') if week is not None: this_schedule.week = week if away_team_id is not None: try: away_team = Team.get_by_id(away_team_id) this_schedule.awayteam = away_team except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {away_team_id}') if home_team_id is not None: try: home_team = Team.get_by_id(home_team_id) this_schedule.hometeam = home_team except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {home_team_id}') if game_count is not None: this_schedule.gamecount = game_count if season is not None: this_schedule.season = season this_schedule.save() db.close() return model_to_dict(this_schedule) @app.delete('/api/v1/schedules/{schedule_id}') async def v1_schedules_delete(schedule_id: int, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to delete schedules') delete_query = Schedule.delete().where(Schedule.id == schedule_id) count = delete_query.execute() db.close() if count > 0: raise HTTPException(status_code=200, detail=f'Removed {count} schedules') else: raise HTTPException(status_code=418, detail=f'Well slap my ass and call me a teapot; ' f'I did not delete any records') @app.get('/api/v1/transactions') async def v1_transactions( season = SEASON_DEFAULT, team_abbrev: Optional[str] = None, week_start: Optional[int] = 0, week_end: Optional[int] = None, cancelled: Optional[bool] = None, frozen: Optional[bool] = None, player_name: Optional[str] = None, player_id: Optional[int] = None, move_id: Optional[str] = None, is_trade: Optional[bool] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ Param: season: int Param: team_abbrev: string Param: week_start: int Param: week_end: int Param: player_id: int, overrides player_name (and season) Param: player_name: string, overridden by player_id Param: include_cancelled: bool, default False Param: include_frozen: bool, default False """ if season: transactions = Transaction.select_season(season) else: transactions = Transaction.select() # if transactions.count() == 0: # db.close() # raise HTTPException(status_code=404, detail=f'Season {season} not found') if team_abbrev: these_teams = Team.select().where( (Team.abbrev == team_abbrev.upper()) | (Team.abbrev == f'{team_abbrev.upper()}SIL') | (Team.abbrev == f'{team_abbrev.upper()}MiL') | (Team.abbrev == f'{team_abbrev.upper()}IL') ) if these_teams.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') transactions = transactions.where( (Transaction.newteam << these_teams) | (Transaction.oldteam << these_teams) ) if week_start is not None: transactions = transactions.where(Transaction.week >= week_start) if week_end is not None: transactions = transactions.where(Transaction.week <= week_end) if move_id: transactions = transactions.where(Transaction.moveid == move_id) if player_id or player_name: if player_id: try: this_player = Player.get_by_id(player_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') transactions = transactions.where(Transaction.player == this_player) else: these_players = Player.select().where(fn.Lower(Player.name) == player_name.lower()) print(f'these_players: {these_players}\nCount: {these_players.count()}') if these_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Player {player_name} not found') transactions = transactions.where(Transaction.player << these_players) if cancelled: transactions = transactions.where(Transaction.cancelled == 1) else: transactions = transactions.where(Transaction.cancelled == 0) if frozen: transactions = transactions.where(Transaction.frozen == 1) else: transactions = transactions.where(Transaction.frozen == 0) if is_trade is not None: if not is_trade: db.close() raise HTTPException(status_code=501, detail='The is_trade parameter only supports True') # if is_trade is not None: # if is_trade: # old_team = Team.alias() # new_team = Team.alias() # transactions = transactions.join(Team, on=Transaction.oldteam).where( # Transaction.oldteam.gmid != Transaction.newteam.gmid # ) # logging.info(transactions) # # # # Get IL, MIL and FA teams # # ilteams = Team.select_season(season).where((fn.Lower(Team.abbrev).endswith('il'))) # # all_teams = Team.select_season(season).where( # # ~(Team.abbrev.endswith('IL')) & ~(Team.abbrev.endswith('MiL')) # # ) # # fa_team = Team.get(Team.season == season, Team.abbrev == 'FA') # # # # # Get transactions where new team << bad_teams # # transactions = transactions.where( # # (~(Transaction.oldteam << fa_team) & (Transaction.oldteam << all_teams) & # # ~(Transaction.newteam << ilteams)) | # # ((Transaction.oldteam << all_teams) & ~(Transaction.newteam << ilteams)) # # ) # # # Get transactions where old team << bad_teams # else: # db.close() # raise HTTPException(status_code=501, detail='The "is_trade" parameter only supports True') transactions = transactions.order_by(-Transaction.week, Transaction.moveid) if return_type == 'csv' or csv: trans_list = [['season', 'week', 'player_name', 'old_team_abbrev', 'new_team_abbrev', 'move_id']] for line in transactions: if (is_trade and line.oldteam.gmid and line.newteam.gmid and line.oldteam.gmid != line.newteam.gmid and 'rule5' not in line.moveid) or not is_trade: trans_list.append( [ line.season, line.week, line.player.name, line.oldteam.abbrev, line.newteam.abbrev, line.moveid ] ) return_trans = DataFrame(trans_list).to_csv(header=False, index=False) db.close() return Response(content=return_trans, media_type='text/csv') else: return_trans = {} for line in transactions: if (is_trade and line.oldteam.gmid and line.newteam.gmid and line.oldteam.gmid != line.newteam.gmid and 'rule5' not in line.moveid) or not is_trade: return_trans[f'{line.id}'] = model_to_dict(line) db.close() return return_trans @app.post('/api/v1/transactions') async def v1_transactions_post(moves: TransModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post transactions') all_moves = [] for x in moves.moves: try: old_team = Team.get_by_id(x.oldteam_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Old team with id {x.oldteam_id} not found') try: new_team = Team.get_by_id(x.newteam_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Away team with id {x.newteam_id} not found') try: this_player = Player.get_by_id(x.player_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {x.player_id} not found') this_move = Transaction( week=x.week, player=this_player, oldteam=old_team, newteam=new_team, season=x.season, moveid=x.moveid, cancelled=x.cancelled, frozen=x.frozen ) all_moves.append(this_move) with db.atomic(): Transaction.bulk_create(all_moves, batch_size=15) db.close() raise HTTPException(status_code=200, detail=f'{len(all_moves)} of {moves.count} lines have been added') @app.patch('/api/v1/transactions/{move_id}') async def v1_transactions_patch( move_id, token: str = Depends(oauth2_scheme), frozen: Optional[bool] = None, cancelled: Optional[bool] = None): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch transactions') these_moves = Transaction.select().where(Transaction.moveid == move_id) if these_moves.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Move ID {move_id} not found') if frozen is not None: for x in these_moves: x.frozen = frozen x.save() if cancelled is not None: for x in these_moves: x.cancelled = cancelled x.save() db.close() raise HTTPException(status_code=200, detail=f'Updated {these_moves.count()} transactions') @app.delete('/api/v1/transactions/{move_id}') async def v1_transactions_delete( move_id, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch transactions') delete_query = Transaction.delete().where(Transaction.moveid == move_id) count = delete_query.execute() db.close() if count > 0: raise HTTPException(status_code=200, detail=f'Removed {count} transactions') else: raise HTTPException(status_code=418, detail=f'Well slap my ass and call me a teapot; ' f'I did not delete any records') @app.get('/api/v1/players') async def v1_players_get( season: Optional[int] = SEASON_DEFAULT, team_abbrev: Optional[str] = None, sort: Optional[str] = None, injured: Optional[bool] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ Param: season: int Param: team_abbrev: string Param: sort: string, [wara-desc] """ all_players = Player.select_season(season) if all_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Season {season} not found') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_players = all_players.where(Player.team == this_team) if sort: if sort == 'wara-desc': all_players = all_players.order_by(-Player.wara) if injured is not None: all_players = all_players.where(Player.il_return.is_null(False)) if return_type == 'csv' or csv: player_list = [ ['name', 'wara', 'image', 'vanity_card', 'team_abbrev', 'pit_inj', 'pos_1', 'pos_2', 'pos_3', 'pos_4', 'pos_5', 'pos_6', 'pos_7', 'pos_8', 'last_game', 'last_game2', 'il_return', 'dem_week'] ] for line in all_players: player_list.append( [ line.name, line.wara, line.image, line.vanity_card, line.team.abbrev, line.pitcher_injury, line.pos_1, line.pos_2, line.pos_3, line.pos_4, line.pos_5, line.pos_6, line.pos_7, line.pos_8, line.last_game, line.last_game2, line.il_return, line.demotion_week ] ) return_players = DataFrame(player_list).to_csv(header=False, index=False) db.close() return Response(content=return_players, media_type='text/csv') else: return_players = {} for player in all_players: return_players[f'{player.name}'] = model_to_dict(player) db.close() return return_players @app.get('/api/v2/players') async def v2_players_get( season: Optional[int] = SEASON_DEFAULT, team_abbrev: Optional[str] = None, sort: Optional[str] = None, injured: Optional[bool] = None, csv: Optional[bool] = False): """ Param: season: int Param: team_abbrev: string Param: sort: string, [wara-desc] """ all_players = Player.select_season(season) if all_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Season {season} not found') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_players = all_players.where(Player.team == this_team) if sort: if sort == 'wara-desc': all_players = all_players.order_by(-Player.wara) if injured is not None: all_players = all_players.where(Player.il_return.is_null(False)) if csv: player_list = [ ['name', 'wara', 'image', 'vanity_card', 'team_abbrev', 'inj_rat', 'pos_1', 'pos_2', 'pos_3', 'pos_4', 'pos_5', 'pos_6', 'pos_7', 'pos_8', 'last_game', 'last_game2', 'il_return', 'dem_week', 'strat_code', 'bbref_id'] ] for line in all_players: player_list.append( [ line.name, line.wara, line.image, line.vanity_card, line.team.abbrev, line.injury_rating, line.pos_1, line.pos_2, line.pos_3, line.pos_4, line.pos_5, line.pos_6, line.pos_7, line.pos_8, line.last_game, line.last_game2, line.il_return, line.demotion_week, line.strat_code, line.bbref_id ] ) return_players = DataFrame(player_list).to_csv(header=False, index=False) db.close() return Response(content=return_players, media_type='text/csv') else: return_players = {} for player in all_players: return_players[f'{player.name}'] = model_to_dict(player) db.close() return return_players @app.get('/api/v3/players') async def v3_players_get( season: Optional[int] = SEASON_DEFAULT, team_abbrev: Optional[str] = None, sort: Optional[str] = None, injured: Optional[bool] = None, csv: Optional[bool] = False): """ Param: season: int Param: team_abbrev: string Param: sort: string, [wara-desc] """ all_players = Player.select_season(season) if all_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Season {season} not found') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_players = all_players.where(Player.team == this_team) if sort: if sort == 'wara-desc': all_players = all_players.order_by(-Player.wara) if injured is not None: all_players = all_players.where(Player.il_return.is_null(False)) if csv: player_list = [ ['name', 'wara', 'image', 'vanity_card', 'team_abbrev', 'inj_rat', 'pos_1', 'pos_2', 'pos_3', 'pos_4', 'pos_5', 'pos_6', 'pos_7', 'pos_8', 'last_game', 'last_game2', 'il_return', 'dem_week', 'strat_code', 'bbref_id'] ] for line in all_players: player_list.append( [ line.name, line.wara, line.image, line.vanity_card, line.team.abbrev, line.injury_rating, line.pos_1, line.pos_2, line.pos_3, line.pos_4, line.pos_5, line.pos_6, line.pos_7, line.pos_8, line.last_game, line.last_game2, line.il_return, line.demotion_week, line.strat_code, line.bbref_id ] ) return_players = DataFrame(player_list).to_csv(header=False, index=False) db.close() return Response(content=return_players, media_type='text/csv') else: return_players = {'count': all_players.count(), 'players': []} for player in all_players: return_players['players'].append(model_to_dict(player)) db.close() return return_players @app.get('/api/v2/players/{id_or_name}') async def v2_players_get_one(id_or_name, season: Optional[int] = SEASON_DEFAULT, csv: Optional[bool] = False): this_player = None try: this_player = Player.get_by_id(id_or_name) except Exception as e: this_player = Player.get_season(id_or_name, season) if this_player: if csv: player_list = [['name', 'wara', 'image', 'image2', 'team_abbrev', 'inj_rat', 'pos_1', 'pos_2', 'pos_3', 'pos_4', 'pos_5', 'pos_6', 'pos_7', 'pos_8', 'last_game', 'last_game2', 'il_return', 'dem_week', 'strat_code', 'bbref_id'], [this_player.name, this_player.wara, this_player.image, this_player.image2, this_player.team.abbrev, this_player.injury_rating, this_player.pos_1, this_player.pos_2, this_player.pos_3, this_player.pos_4, this_player.pos_5, this_player.pos_6, this_player.pos_7, this_player.pos_8, this_player.last_game, this_player.last_game2, this_player.il_return, this_player.demotion_week, this_player.strat_code, this_player.bbref_id] ] return_players = DataFrame(player_list).to_csv(header=False, index=False) db.close() return Response(content=return_players, media_type='text/csv') else: db.close() return model_to_dict(this_player) else: db.close() raise HTTPException(status_code=404, detail=f'Player id {id_or_name} not found') @app.get('/api/v1/players/{id_or_name}') async def v1_players_get_one(id_or_name, season: Optional[int] = SEASON_DEFAULT, return_type: Optional[str] = 'json', csv: Optional[bool] = False): this_player = None try: this_player = Player.get_by_id(id_or_name) except Exception as e: this_player = Player.get_season(id_or_name, season) if this_player: if return_type == 'csv' or csv: player_list = [['name', 'wara', 'image', 'image2', 'team_abbrev', 'pit_inj', 'pos_1', 'pos_2', 'pos_3', 'pos_4', 'pos_5', 'pos_6', 'pos_7', 'pos_8', 'last_game', 'last_game2', 'il_return', 'dem_week'], [this_player.name, this_player.wara, this_player.image, this_player.image2, this_player.team.abbrev, this_player.pitcher_injury, this_player.pos_1, this_player.pos_2, this_player.pos_3, this_player.pos_4, this_player.pos_5, this_player.pos_6, this_player.pos_7, this_player.pos_8, this_player.last_game, this_player.last_game2, this_player.il_return, this_player.demotion_week] ] return_players = DataFrame(player_list).to_csv(header=False, index=False) db.close() return Response(content=return_players, media_type='text/csv') else: db.close() return model_to_dict(this_player) else: db.close() raise HTTPException(status_code=404, detail=f'Player id {id_or_name} not found') @app.patch('/api/v2/players/{pid}') async def v1_players_patch( pid: int, token: str = Depends(oauth2_scheme), name: Optional[str] = None, wara: Optional[float] = None, image: Optional[str] = None, image2=None, team_id: Optional[int] = None, season: Optional[int] = None, pitcher_injury=None, pos_1=None, pos_2=None, pos_3=None, pos_4=None, pos_5=None, pos_6=None, pos_7=None, pos_8=None, last_game=None, last_game2=None, il_return=None, demotion_week=None, headshot=None, vanity_card=None, strat_code=None, bbref_id=None, injury_rating=None): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch players') try: this_player = Player.get_by_id(pid) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {pid} not found') if team_id: try: this_team = Team.get_by_id(team_id) this_player.team = this_team except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Team id {team_id} not found') if name: this_player.name = name if wara is not None: this_player.wara = wara if image: this_player.image = image if image2 is not None: if image2.lower() == 'false': this_player.image2 = None else: this_player.image2 = image2 if season: this_player.season = season if pitcher_injury is not None: if pitcher_injury.lower() == 'false': this_player.pitcher_injury = None else: this_player.pitcher_injury = pitcher_injury if pos_1: this_player.pos_1 = pos_1 if pos_2 is not None: if pos_2.lower() == 'false': this_player.pos_2 = None else: this_player.pos_2 = pos_2 if pos_3 is not None: if pos_3.lower() == 'false': this_player.pos_3 = None else: this_player.pos_3 = pos_3 if pos_4 is not None: if pos_4.lower() == 'false': this_player.pos_4 = None else: this_player.pos_4 = pos_4 if pos_5 is not None: if pos_5.lower() == 'false': this_player.pos_5 = None else: this_player.pos_5 = pos_5 if pos_6 is not None: if pos_6.lower() == 'false': this_player.pos_6 = None else: this_player.pos_6 = pos_6 if pos_7 is not None: if pos_7.lower() == 'false': this_player.pos_7 = None else: this_player.pos_7 = pos_7 if pos_8 is not None: if pos_8.lower() == 'false': this_player.pos_8 = None else: this_player.pos_8 = pos_8 if last_game is not None: if last_game.lower() == 'false': this_player.last_game = None else: this_player.last_game = last_game if last_game2 is not None: if last_game2.lower() == 'false': this_player.last_game2 = None else: this_player.last_game2 = last_game2 if il_return is not None: if il_return.lower() == 'false': this_player.il_return = None else: this_player.il_return = il_return if demotion_week is not None: if demotion_week.lower() == 'false': this_player.demotion_week = None else: this_player.demotion_week = demotion_week if headshot is not None: if headshot.lower() == 'false': this_player.headshot = None else: this_player.headshot = headshot if vanity_card is not None: if vanity_card.lower() == 'false': this_player.vanity_card = None else: this_player.vanity_card = vanity_card if strat_code is not None: if strat_code.lower() == 'false': this_player.strat_code = None else: this_player.strat_code = strat_code if bbref_id is not None: if bbref_id.lower() == 'false': this_player.bbref_id = None else: this_player.bbref_id = bbref_id if injury_rating is not None: if injury_rating.lower() == 'false': this_player.injury_rating = None else: this_player.injury_rating = injury_rating saved = this_player.save() db.close() if saved == 1: return model_to_dict(this_player) else: raise HTTPException(status_code=400, detail=f'Unable to update {this_player.name}') @app.post('/api/v2/players') async def v1_players_post(players: PlayerModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to post players') new_players = [] for x in players.players: logging.info(f'x: {x}') this_player = Player( name=x.name, wara=x.wara, image=x.image, image2=x.image2, team_id=x.team_id, season=x.season, pitcher_injury=x.pitcher_injury, pos_1=x.pos_1, pos_2=x.pos_2, pos_3=x.pos_3, pos_4=x.pos_4, pos_5=x.pos_5, pos_6=x.pos_6, pos_7=x.pos_7, pos_8=x.pos_8, last_game=x.last_game, last_game2=x.last_game2, il_return=x.il_return, demotion_week=x.demotion_week, strat_code=x.strat_code, bbref_id=x.bbref_id, injury_rating=x.injury_rating ) new_players.append(this_player) with db.atomic(): Player.bulk_create(new_players, batch_size=15) db.close() raise HTTPException(status_code=200, detail=f'{len(new_players)} players have been added') @app.get('/api/v1/battingcareer/{id_or_name}') async def v1_battingcareer_get(id_or_name, csv: Optional[bool] = False): this_career = None try: this_career = BattingCareer.get_by_id(id_or_name) except Exception as e: logging.info(f'Could not find BattingCareer with id {id_or_name}') if not this_career: this_career = BattingCareer.get_or_none(fn.Lower(BattingCareer.name) == id_or_name.lower()) if this_career: if csv: career_list = [ ['name', 'pa', 'ab', 'run', 'hit', 'rbi', 'double', 'triple', 'hr', 'bb', 'so', 'hbp', 'sac', 'ibb', 'gidp', 'sb', 'cs', 'bphr', 'bpfo', 'bp1b', 'bplo', 'games'], [this_career.name, this_career.pa, this_career.ab, this_career.run, this_career.hit, this_career.rbi, this_career.double, this_career.triple, this_career.hr, this_career.bb, this_career.so, this_career.hbp, this_career.sac, this_career.ibb, this_career.gidp, this_career.sb, this_career.cs, this_career.bphr, this_career.bpfo, this_career.bp1b, this_career.bplo, this_career.games] ] return_career = DataFrame(career_list).to_csv(header=False, index=False) db.close() return Response(content=return_career, media_type='text/csv') else: db.close() return model_to_dict(this_career) else: db.close() raise HTTPException(status_code=404, detail=f'Career id {id_or_name} not found') @app.get('/api/v1/pitchingcareer/{id_or_name}') async def v1_pitchingcareer_get(id_or_name, csv: Optional[bool] = False): this_career = None try: this_career = PitchingCareer.get_by_id(id_or_name) except Exception as e: logging.info(f'Could not find PitchingCareer with id {id_or_name}') if not this_career: this_career = PitchingCareer.get_or_none(fn.Lower(PitchingCareer.name) == id_or_name.lower()) if this_career: if csv: career_list = [ ['name', 'ip', 'hit', 'run', 'erun', 'so', 'bb', 'hbp', 'wp', 'balk', 'hr', 'ir', 'irs', 'gs', 'win', 'loss', 'hold', 'sv', 'bsv', 'game'], [this_career.name, this_career.ip, this_career.hit, this_career.run, this_career.erun, this_career.so, this_career.bb, this_career.hbp, this_career.wp, this_career.balk, this_career.hr, this_career.ir, this_career.irs, this_career.gs, this_career.win, this_career.loss, this_career.hold, this_career.sv, this_career.bsv, this_career.game] ] return_career = DataFrame(career_list).to_csv(header=False, index=False) db.close() return Response(content=return_career, media_type='text/csv') else: db.close() return model_to_dict(this_career) else: db.close() raise HTTPException(status_code=404, detail=f'Career id {id_or_name} not found') @app.get('/api/v1/battingstats/s{season}/{s_type}') async def v1_battingstats_get( s_type: str, season: int = SEASON_DEFAULT, team_abbrev: Optional[str] = None, player_name: Optional[str] = None, player_id: Optional[int] = None, week_start: Optional[int] = None, week_end: Optional[int] = None, game_num: Optional[int] = None, position: Optional[str] = None, limit: Optional[int] = None, sort: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ :param season: int :param s_type: string (regular, post, combined) :param team_abbrev: string :param player_name: string :param player_id: integer, overrides player_name :param week_start: integer :param week_end: integer :param game_num: integer :param position: string :param limit: int :param sort: string, 'oldest' or 'newest' to return first :return: """ if s_type.lower() == 'post': all_stats = BattingStat.post_season(season) if all_stats.count() == 0: db.close() return {} elif s_type.lower() == 'combined': all_stats = BattingStat.combined_season(season) if all_stats.count() == 0: db.close() return {} else: all_stats = BattingStat.regular_season(season) if not all_stats: db.close() return {} if position: all_stats = all_stats.where(BattingStat.pos == position.upper()) if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_stats = all_stats.where(BattingStat.team == this_team) if player_name or player_id: if player_id: try: this_player = Player.get_by_id(player_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') else: this_player = Player.get_season(player_name, season) if not this_player: db.close() raise HTTPException(status_code=404, detail=f'Player {player_name} not found') all_stats = all_stats.where(BattingStat.player == this_player) start = 1 end = Current.get(Current.season == season).week if week_start is not None: start = week_start if week_end is not None: end = min(week_end, end) if start > end: db.close() raise HTTPException(status_code=404, detail=f'Start week {start} is after end week {end} - cannot pull stats') if start + 5 < end and team_abbrev is None and player_name is None and player_id is None and not csv: start = end - 5 logging.info(f'\n\nweek_start: {week_start} / week_end: {week_end} / game_num: {game_num} / ' f'start: {start} / end: {end}') all_stats = all_stats.where( (BattingStat.week >= start) & (BattingStat.week <= end) ) if game_num: all_stats = all_stats.where(BattingStat.game == game_num) if limit: all_stats = all_stats.limit(limit) if sort: if sort == 'newest': all_stats = all_stats.order_by(-BattingStat.week, -BattingStat.game) if return_type == 'csv' or csv: stats_list = [['season', 'week', 'game_num', 'player', 'team', 'pos', 'pa', 'ab', 'run', 'hit', 'rbi', 'double', 'triple', 'hr', 'bb', 'so', 'hbp', 'sac', 'ibb', 'gidp', 'sb', 'cs', 'xba', 'xbt']] for line in all_stats: stats_list.append( [ line.season, line.week, line.game, line.player.name, line.team.abbrev, line.pos, line.pa, line.ab, line.run, line.hit, line.rbi, line.double, line.triple, line.hr, line.bb, line.so, line.hbp, line.sac, line.ibb, line.gidp, line.sb, line.cs, line.xba, line.xbt ] ) return_stats = DataFrame(stats_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_stats = {} for line in all_stats: return_stats[f'{line.id}'] = model_to_dict(line) # Need recurse set to false to allow JSON data # return_stats[f'{line.id}'] = model_to_dict(line, recurse=False) db.close() return return_stats @app.post('/api/v1/battingstats') async def v1_battingstats_post(stats: BattingStatModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to post batting stats') all_stats = [] season = None week = None teams = [] game_num = None for x in stats.stats: try: team = Team.get_by_id(x.team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {x.team_id}') try: this_player = Player.get_by_id(x.player_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {x.player_id} not found') # Helpers for query if team not in teams: teams.append(team) if not season: season = x.season if not week: week = x.week if not game_num: game_num = x.game new_stats = BattingStat( player=this_player, team=team, pos=x.pos, pa=x.pa, ab=x.ab, run=x.run, hit=x.hit, rbi=x.rbi, double=x.double, triple=x.triple, hr=x.hr, bb=x.bb, so=x.so, hbp=x.hbp, sac=x.sac, ibb=x.ibb, gidp=x.gidp, sb=x.sb, cs=x.cs, bphr=x.bphr, bpfo=x.bpfo, bp1b=x.bp1b, bplo=x.bplo, xba=x.xba, xbt=x.xbt, xch=x.xch, xhit=x.xhit, error=x.error, pb=x.pb, sbc=x.sbc, csc=x.csc, roba=x.roba, robs=x.robs, raa=x.raa, rto=x.rto, week=x.week, game=x.game, season=x.season, ) all_stats.append(new_stats) with db.atomic(): BattingStat.bulk_create(all_stats, batch_size=15) this_game_stats = BattingStat.select().where( (BattingStat.season == season) & (BattingStat.week == week) & (BattingStat.game == game_num) & ((BattingStat.team == teams[0]) | (BattingStat.team == teams[1])) ) logging.warning(f'I pulled {this_game_stats.count()} batting lines with this query:\n{this_game_stats}') # Update season and career stats with freshly submitted for regular season games if (season > 2) and week <= 22: s_type = 'Regular' else: s_type = 'Post' for line in this_game_stats: this_season = BattingSeason.get_or_none(player=line.player, season=line.player.season, season_type=s_type) if not this_season: this_season = BattingSeason(player=line.player, season=line.player.season, season_type=s_type) this_season.save() this_career = BattingCareer.get_or_none(BattingCareer.name == this_season.player.name) if not this_career: this_career = BattingCareer(name=this_season.player.name) this_career.save() fielding_season = FieldingSeason.get_or_none( player=line.player, season=line.player.season, pos=line.pos, season_type=s_type ) if not fielding_season: fielding_season = FieldingSeason( player=line.player, season=line.player.season, pos=line.pos, season_type=s_type ) fielding_season.save() fielding_career = FieldingCareer.get_or_none(name=line.player.name, pos=line.pos) if not fielding_career: fielding_career = FieldingCareer(name=line.player.name, pos=line.pos) fielding_career.save() this_season.pa += line.pa this_season.ab += line.ab this_season.run += line.run this_season.hit += line.hit this_season.rbi += line.rbi this_season.double += line.double this_season.triple += line.triple this_season.hr += line.hr this_season.bb += line.bb this_season.so += line.so this_season.hbp += line.hbp this_season.sac += line.sac this_season.ibb += line.ibb this_season.gidp += line.gidp this_season.sb += line.sb this_season.cs += line.cs this_season.bphr += line.bphr this_season.bpfo += line.bpfo this_season.bp1b += line.bp1b this_season.bplo += line.bplo this_season.xba += line.xba this_season.xbt += line.xbt this_season.game += 1 fielding_season.xch += line.xch fielding_season.xhit += line.xhit fielding_season.error += line.error fielding_season.pb += line.pb fielding_season.sbc += line.sbc fielding_season.csc += line.csc fielding_season.roba += line.roba fielding_season.robs += line.robs fielding_season.raa += line.raa fielding_season.rto += line.rto fielding_season.game += 1 if s_type == 'Regular': this_career.pa += line.pa this_career.ab += line.ab this_career.run += line.run this_career.hit += line.hit this_career.rbi += line.rbi this_career.double += line.double this_career.triple += line.triple this_career.hr += line.hr this_career.bb += line.bb this_career.so += line.so this_career.hbp += line.hbp this_career.sac += line.sac this_career.ibb += line.ibb this_career.gidp += line.gidp this_career.sb += line.sb this_career.cs += line.cs this_career.bphr += line.bphr this_career.bpfo += line.bpfo this_career.bp1b += line.bp1b this_career.bplo += line.bplo this_career.xba += line.xba this_career.xbt += line.xbt this_career.game += 1 fielding_career.xch += line.xch fielding_career.xhit += line.xhit fielding_career.error += line.error fielding_career.pb += line.pb fielding_career.sbc += line.sbc fielding_career.csc += line.csc fielding_career.roba += line.roba fielding_career.robs += line.robs fielding_career.raa += line.raa fielding_career.rto += line.rto fielding_career.game += 1 this_season.save() this_career.save() fielding_season.save() fielding_career.save() db.close() raise HTTPException(status_code=200, detail=f'{len(all_stats)} of {stats.count} lines have been added') @app.delete('/api/v1/battingstats') async def v1_battingstats_delete(game: GameModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to delete batting stats') # Get teams try: away_team = Team.get_by_id(game.away_team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Away team with id {game.away_team_id} not found') try: home_team = Team.get_by_id(game.home_team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Away team with id {game.home_team_id} not found') # Check for matchup this_matchup = Schedule.select_season(Current.latest().season).where( (Schedule.awayteam == away_team) & (Schedule.hometeam == home_team) & (Schedule.week == game.week) ) if this_matchup.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No game found between {away_team.abbrev} and {home_team.abbrev} ' f'in week {game.week}') # Check for game batting stats this_game_stats = BattingStat.select().where( (BattingStat.season == game.season) & (BattingStat.week == game.week) & (BattingStat.game == game.game_num) & ((BattingStat.team == away_team) | (BattingStat.team == home_team)) & (BattingStat.pa > 0) ) if this_game_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No stats found for {away_team.abbrev} at {home_team.abbrev} in ' f'that matchup') # # Remove stats from season lines # for line in this_game_stats: # this_season = BattingSeason.get_or_none(player=line.player, season=line.player.season) # if not this_season: # db.close() # raise HTTPException(status_code=404, detail=f'Could not find existing batting season stats ' # f'for {line.player.name} (ID: {line.player.id})') # this_career = BattingCareer.get_or_none(BattingCareer.name == this_season.player.name) # if not this_career: # this_career = BattingCareer(name=this_season.player.name) # this_career.save() # # this_season.pa -= line.pa # # this_career.pa -= line.pa # this_season.ab -= line.ab # # this_career.ab -= line.ab # this_season.run -= line.run # # this_career.run -= line.run # this_season.hit -= line.hit # # this_career.hit -= line.hit # this_season.rbi -= line.rbi # # this_career.rbi -= line.rbi # this_season.double -= line.double # # this_career.double -= line.double # this_season.triple -= line.triple # # this_career.triple -= line.triple # this_season.hr -= line.hr # # this_career.hr -= line.hr # this_season.bb -= line.bb # # this_career.bb -= line.bb # this_season.so -= line.so # # this_career.so -= line.so # this_season.hbp -= line.hbp # # this_career.hbp -= line.hbp # this_season.sac -= line.sac # # this_career.sac -= line.sac # this_season.ibb -= line.ibb # # this_career.ibb -= line.ibb # this_season.gidp -= line.gidp # # this_career.gidp -= line.gidp # this_season.sb -= line.sb # # this_career.sb -= line.sb # this_season.cs -= line.cs # # this_career.cs -= line.cs # this_season.game -= 1 # # this_career.game -= 1 # # this_season.save() # # this_career.save() # # this_career.recalculate() # # # Check for game fielding stats # this_game_stats = BattingStat.select().where( # (BattingStat.season == game.season) & (BattingStat.week == game.week) & (BattingStat.game == game.game_num) & # ((BattingStat.team == away_team) | (BattingStat.team == home_team)) & (BattingStat.xch + BattingStat.sbc > 0) # ) # if this_game_stats.count() == 0: # db.close() # raise HTTPException(status_code=404, detail=f'No stats found for {away_team.abbrev} at {home_team.abbrev} in ' # f'that matchup') # # # Remove stats from season lines # for line in this_game_stats: # this_season = FieldingSeason.get_or_none(player=line.player, season=line.player.season) # if not this_season: # db.close() # raise HTTPException(status_code=404, detail=f'Could not find existing batting season stats ' # f'for {line.player.name} (ID: {line.player.id})') # this_career = FieldingCareer.get_or_none(FieldingCareer.name == this_season.player.name, # FieldingCareer.pos == line.pos) # if not this_career: # this_career = FieldingCareer(name=this_season.player.name, pos=this_season.pos) # this_career.save() # # this_season.xch -= line.xch # # this_career.xch -= line.xch # this_season.xhit -= line.xhit # # this_career.xhit -= line.xhit # this_season.error -= line.error # # this_career.error -= line.error # this_season.pb -= line.pb # # this_career.pb -= line.pb # this_season.sbc -= line.sbc # # this_career.sbc -= line.sbc # this_season.csc -= line.csc # # this_career.csc -= line.csc # this_season.game -= 1 # # this_career.game -= 1 # # this_season.save() # # this_career.save() # # this_career.recalculate() # Delete the stats delete_query = BattingStat.delete().where( (BattingStat.season == game.season) & (BattingStat.week == game.week) & ((BattingStat.team == away_team) | (BattingStat.team == home_team)) ) if game.game_num: delete_query = delete_query.where(BattingStat.game == game.game_num) count = delete_query.execute() db.close() if count > 0: raise HTTPException(status_code=200, detail=f'Removed {count} batting stat lines') else: raise HTTPException(status_code=418, detail=f'Well slap my ass and call me a teapot; ' f'I did not delete any records') @app.get('/api/v1/pitchingstats/s{season}/{s_type}') async def v1_pitchingstat_get( s_type: str, season: int, team_abbrev: Optional[str] = None, player_name: Optional[str] = None, player_id: Optional[int] = None, week_start: Optional[int] = None, week_end: Optional[int] = None, game_num: Optional[int] = None, limit: Optional[int] = None, sort: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ :param season: int :param s_type: string (regular, post, combined) :param team_abbrev: string :param player_name: string :param player_id: integer, overrides player_name :param week_start: integer :param week_end: integer :param limit: int :param sort: string, 'newest' or 'oldest' to get those first :return: """ if s_type.lower() == 'post': all_stats = PitchingStat.post_season(season) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No postseason stats found for season {season}') elif s_type.lower() == 'combined': all_stats = PitchingStat.combined_season(season) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No stats found for season {season}') else: all_stats = PitchingStat.regular_season(season) if not all_stats: db.close() return {} if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_stats = all_stats.where(PitchingStat.team == this_team) if player_name or player_id: if player_id: try: this_player = Player.get_by_id(player_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') else: this_player = Player.get_season(player_name, season) if not this_player: db.close() raise HTTPException(status_code=404, detail=f'Player {player_name} not found') all_stats = all_stats.where(PitchingStat.player == this_player) start = 1 end = Current.get(Current.season == season).week if week_start is not None: start = week_start if week_end is not None: end = min(week_end, end) if start > end: db.close() raise HTTPException(status_code=404, detail=f'Start week {start} is after end week {end} - cannot pull stats') if start + 5 < end and team_abbrev is None and player_name is None and player_id is None and not csv: start = end - 5 all_stats = all_stats.where( (PitchingStat.week >= start) & (PitchingStat.week <= end) ) if game_num: all_stats = all_stats.where(PitchingStat.game == game_num) if limit: all_stats = all_stats.limit(limit) if sort: if sort == 'newest': all_stats = all_stats.order_by(-PitchingStat.week, -PitchingStat.game) if return_type == 'csv' or csv: stats_list = [['pitcher', 'team', 'ip', 'h', 'r', 'er', 'so', 'bb', 'hbp', 'wp', 'bk', 'hr', 'gs', 'w', 'l', 'hd', 'sv', 'bs', 'week', 'game', 'code']] for line in all_stats: stats_list.append( [ line.player.name, line.team.abbrev, line.ip, line.hit, line.run, line.erun, line.so, line.bb, line.hbp, line.wp, line.balk, line.hr, line.gs, line.win, line.loss, line.hold, line.sv, line.bsv, line.week, line.game, f'{line.week}.{line.game}' ] ) return_stats = DataFrame(stats_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_stats = {} for line in all_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.post('/api/v1/pitchingstats') async def v1_pitchingstats_post(stats: PitchingStatModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to post pitching stats') all_stats = [] season = None week = None teams = [] game_num = None for x in stats.stats: team = Team.get_by_id(x.team_id) if not team: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {x.team_id}') player = Player.get_by_id(x.player_id) if not player: db.close() raise HTTPException(status_code=404, detail=f'No player found with id {x.player_id}') # Helpers for query if team not in teams: teams.append(team) if not season: season = x.season if not week: week = x.week if not game_num: game_num = x.game new_stats = PitchingStat( player=player, team=team, ip=x.ip, hit=x.hit, run=x.run, erun=x.erun, so=x.so, bb=x.bb, hbp=x.hbp, wp=x.wp, balk=x.balk, hr=x.hr, gs=x.gs, win=x.win, loss=x.loss, hold=x.hold, sv=x.sv, bsv=x.bsv, ir=x.ir, irs=x.irs, week=x.week, game=x.game, season=x.season ) all_stats.append(new_stats) with db.atomic(): PitchingStat.bulk_create(all_stats, batch_size=20) this_game_stats = PitchingStat.select().where( (PitchingStat.season == season) & (PitchingStat.week == week) & (PitchingStat.game == game_num) & ((PitchingStat.team == teams[0]) | (PitchingStat.team == teams[1])) ) # Update season stats with freshly submitted for regular season games if (season > 2) and week <= 22: s_type = 'Regular' else: s_type = 'Post' for line in this_game_stats: this_season = PitchingSeason.get_or_none( player=line.player, season=line.season, season_type=s_type ) if not this_season: this_season = PitchingSeason(player=line.player, season=line.season, season_type=s_type) this_season.save() this_career = PitchingCareer.get_or_none(name=line.player.name) if not this_career: this_career = PitchingCareer(name=line.player.name) this_career.save() this_season.ip += line.ip this_season.hit += line.hit this_season.run += line.run this_season.erun += line.erun this_season.so += line.so this_season.bb += line.bb this_season.hbp += line.hbp this_season.wp += line.wp this_season.balk += line.balk this_season.hr += line.hr this_season.ir += line.ir this_season.irs += line.irs this_season.gs += line.gs this_season.win += line.win this_season.loss += line.loss this_season.hold += line.hold this_season.sv += line.sv this_season.bsv += line.bsv this_season.game += 1 if s_type == 'Regular': this_career.ip += line.ip this_career.hit += line.hit this_career.run += line.run this_career.erun += line.erun this_career.so += line.so this_career.bb += line.bb this_career.hbp += line.hbp this_career.wp += line.wp this_career.balk += line.balk this_career.hr += line.hr this_career.ir += line.ir this_career.irs += line.irs this_career.gs += line.gs this_career.win += line.win this_career.loss += line.loss this_career.hold += line.hold this_career.sv += line.sv this_career.bsv += line.bsv this_career.game += 1 this_season.save() this_career.save() db.close() raise HTTPException(status_code=200, detail=f'{len(all_stats)} of {stats.count} lines have been added') @app.delete('/api/v1/pitchingstats') async def v1_pitchingstats_delete(game: GameModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to delete pitching stats') # Get teams try: away_team = Team.get_by_id(game.away_team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Away team with id {game.away_team_id} not found') try: home_team = Team.get_by_id(game.home_team_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Away team with id {game.home_team_id} not found') # Check for matchup this_matchup = Schedule.select_season(Current.latest().season).where( (Schedule.awayteam == away_team) & (Schedule.hometeam == home_team) & (Schedule.week == game.week) ) if this_matchup.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No game found between {away_team.abbrev} and {home_team.abbrev} ' f'in week {game.week}') # # Check for game stats # this_game_stats = PitchingStat.select().where( # (PitchingStat.season == game.season) & (PitchingStat.week == game.week) & # ((PitchingStat.team == away_team) | (PitchingStat.team == home_team)) # ) # if game.game_num: # this_game_stats = this_game_stats.where(PitchingStat.game == game.game_num) # if this_game_stats.count() == 0: # db.close() # raise HTTPException(status_code=404, detail=f'No stats found for {away_team.abbrev} at {home_team.abbrev} in ' # f'that matchup') # # # Remove stats from season lines # for line in this_game_stats: # this_season = PitchingSeason.get_or_none(player=line.player, season=line.player.season) # if not this_season: # db.close() # raise HTTPException(status_code=404, detail=f'Could not find existing pitching season stats ' # f'for {line.player.name} (ID: {line.player.id})') # this_career = PitchingCareer.get_or_none(PitchingCareer.name == this_season.player.name) # if not this_career: # this_career = PitchingCareer(name=this_season.player.name) # this_career.save() # # # this_career.ip -= line.ip # this_season.ip -= line.ip # # this_career.hit -= line.hit # this_season.hit -= line.hit # # this_career.run -= line.run # this_season.run -= line.run # # this_career.erun -= line.erun # this_season.erun -= line.erun # # this_career.so -= line.so # this_season.so -= line.so # # this_career.bb -= line.bb # this_season.bb -= line.bb # # this_career.hbp -= line.hbp # this_season.hbp -= line.hbp # # this_career.wp -= line.wp # this_season.wp -= line.wp # # this_career.balk -= line.balk # this_season.balk -= line.balk # # this_career.hr -= line.hr # this_season.hr -= line.hr # # this_career.gs -= line.gs # this_season.gs -= line.gs # # this_career.win -= line.win # this_season.win -= line.win # # this_career.loss -= line.loss # this_season.loss -= line.loss # # this_career.hold -= line.hold # this_season.hold -= line.hold # this_season.sv -= line.sv # # this_career.sv -= line.sv # this_season.bsv -= line.bsv # # this_career.bsv -= line.bsv # this_season.game -= 1 # # this_career.game -= 1 # # this_season.save() # # this_career.save() # # this_career.recalculate() # Delete the stats delete_query = PitchingStat.delete().where( (PitchingStat.season == game.season) & (PitchingStat.week == game.week) & ((PitchingStat.team == away_team) | (PitchingStat.team == home_team)) ) if game.game_num: delete_query = delete_query.where(PitchingStat.game == game.game_num) count = delete_query.execute() db.close() if count > 0: raise HTTPException(status_code=200, detail=f'Removed {count} pitching stat lines') else: raise HTTPException(status_code=418, detail=f'Well slap my ass and call me a teapot; ' f'I did not delete any records') @app.get('/api/v1/fieldingstats/s{season}/{s_type}') async def v1_fieldingstats_get( s_type: str, season: int = SEASON_DEFAULT, team_abbrev: Optional[str] = None, player_name: Optional[str] = None, player_id: Optional[int] = None, week_start: Optional[int] = None, week_end: Optional[int] = None, position: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ :param season: int :param s_type: string (regular, post, combined) :param team_abbrev: string :param player_name: string :param player_id: integer, overrides player_name :param week_start: integer :param week_end: integer :param position: string :return: """ if s_type.lower() == 'post': all_stats = BattingStat.post_season(season) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No postseason stats found for season {season}') elif s_type.lower() == 'combined': all_stats = BattingStat.combined_season(season) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No stats found for season {season}') else: all_stats = BattingStat.regular_season(season) if not all_stats: db.close() return {} all_stats = all_stats.where( (BattingStat.xch > 0) | (BattingStat.pb > 0) | (BattingStat.sbc > 0) ) if position: all_stats = all_stats.where(BattingStat.pos == position.upper()) if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_stats = all_stats.where(BattingStat.team == this_team) if player_name or player_id: if player_id: try: this_player = Player.get_by_id(player_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') else: this_player = Player.get_season(player_name, season) if not this_player: db.close() raise HTTPException(status_code=404, detail=f'Player {player_name} not found') all_stats = all_stats.where(BattingStat.player == this_player) start = 1 end = Current.get(Current.season == season).week if week_start is not None: start = week_start if week_end is not None: end = min(week_end, end) if start > end: db.close() raise HTTPException(status_code=404, detail=f'Start week {start} is after end week {end} - cannot pull stats') if start + 5 < end and team_abbrev is None and player_name is None and player_id is None and not csv: start = end - 5 all_stats = all_stats.where( (BattingStat.week >= start) & (BattingStat.week <= end) ) if return_type == 'csv' or csv: stats_list = [['season', 'week', 'game_num', 'player', 'team', 'pos', 'xch', 'xhit', 'error', 'pb', 'sbc', 'csc', 'roba', 'robs', 'raa', 'rto']] for line in all_stats: stats_list.append( [ line.season, line.week, line.game, line.player.name, line.team.abbrev, line.pos, line.xch, line.xhit, line.error, line.pb, line.sbc, line.csc, line.roba, line.robs, line.raa, line.rto ] ) return_stats = DataFrame(stats_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_stats = {} for line in all_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.post('/api/v1/battingseasons/recalculate') async def v1_battingseasons_recalculate( season: Optional[int] = None, team_id: Optional[int] = None, player_id: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to recalculate stats') all_players = BattingSeason.select() if season: all_players = all_players.where(BattingSeason.season == season) if team_id: try: this_team = Team.get_by_id(team_id) all_players = all_players.join(Player).where(BattingSeason.player.team == this_team) except: db.close() raise HTTPException(status_code=404, detail=f'Team id {team_id} not found') if player_id: try: this_player = Player.get_by_id(player_id) except: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') all_players = all_players.where(BattingSeason.player == this_player) if all_players.count() == 0: if BattingStat.select().where(BattingStat.player == this_player).count() > 0: this_season = BattingSeason(player=this_player, season=this_player.season) this_season.save() else: db.close() raise HTTPException(status_code=404, detail=f'No batting stats found for player id {player_id}') for line in all_players: count = line.recalculate() db.close() raise HTTPException(status_code=200, detail=f'Recalculated {all_players.count()} batting seasons') @app.post('/api/v1/pitchingseasons/recalculate') async def v1_pitchingseasons_recalculate( season: Optional[int] = None, team_id: Optional[int] = None, player_id: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to recalculate stats') all_players = PitchingSeason.select() if season: all_players = all_players.where(PitchingSeason.season == season) if team_id: try: this_team = Team.get_by_id(team_id) all_players = all_players.join(Player).where(PitchingSeason.player.team == this_team) except: db.close() raise HTTPException(status_code=404, detail=f'Team id {team_id} not found') if player_id: try: this_player = Player.get_by_id(player_id) except: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') all_players = all_players.where(PitchingSeason.player == this_player) if all_players.count() == 0: if PitchingStat.select().where(PitchingStat.player == this_player).count() > 0: this_season = PitchingSeason(player=this_player, season=this_player.season) this_season.save() else: db.close() raise HTTPException(status_code=404, detail=f'No pitching stats found for player id {player_id}') for line in all_players: count = line.recalculate() db.close() raise HTTPException(status_code=200, detail=f'Recalculated {all_players.count()} pitching seasons') @app.post('/api/v1/fieldingseasons/recalculate') async def v1_fieldingseasons_recalculate( season: Optional[int] = None, team_id: Optional[int] = None, player_id: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to recalculate stats') all_players = FieldingSeason.select() if season: all_players = all_players.where(FieldingSeason.season == season) if team_id: try: this_team = Team.get_by_id(team_id) all_players = all_players.join(Player).where(FieldingSeason.player.team == this_team) except: db.close() raise HTTPException(status_code=404, detail=f'Team id {team_id} not found') if player_id: try: this_player = Player.get_by_id(player_id) except: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') all_players = all_players.where(FieldingSeason.player == this_player) if all_players.count() == 0: search_query = BattingStat.select().where( (BattingStat.player == this_player) & (BattingStat.xch + BattingStat.sbc > 0) ) if search_query.count() > 0: pos_list = [] for x in search_query: pos_list.append(x.pos) for x in pos_list: this_season = FieldingSeason(player=this_player, season=this_player.season, pos=x) this_season.save() else: db.close() raise HTTPException(status_code=404, detail=f'No fielding stats found for player id {player_id}') for line in all_players: count = line.recalculate() logging.info(count) db.close() raise HTTPException(status_code=200, detail=f'Recalculated {all_players.count()} fielding seasons') # @app.post('/api/v1/seasonstats/recalculate') # async def v1_seasonstats_recalculate( # which: str, season_start: int, season_end: int, mgr_start: int, mgr_end: int, # token: str = Depends(oauth2_scheme)): # if not valid_token(token): # db.close() # raise HTTPException(status_code=401, detail='You are not authorized to recalculate stats') # # if mgr_start > mgr_end: # db.close() # raise HTTPException(status_code=404, detail=f'mgr_start may not be greater than mgr_end') # if season_start > season_end: # db.close() # raise HTTPException(status_code=404, detail=f'season_start may not be greater than season_end') # if which not in ['batting', 'fielding', 'pitching']: # db.close() # raise HTTPException(status_code=404, detail=f'Invalid which value') # # x = season_start # while x <= season_end: # y = mgr_start # while y <= mgr_end: # if which == 'batting': # BattingSeason.recalculate(x, y) # elif which == 'pitching': # PitchingSeason.recalculate(x, y) # elif which == 'fielding': # FieldingSeason.recalculate(x, y) # # db.close() # raise HTTPException(status_code=200, detail='Season stats have been recalculated') @app.post('/api/v1/careerstats/recalculate') async def v1_careerstats_recalculate(which: str, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to recalculate stats') if which == 'all': BattingCareer.recalculate() PitchingCareer.recalculate() FieldingCareer.recalculate() elif which == 'batting': BattingCareer.recalculate() elif which == 'pitching': PitchingCareer.recalculate() elif which == 'fielding': FieldingCareer.recalculate() db.close() raise HTTPException(status_code=200, detail='Career stats have been recalculated') @app.get('/api/v1/standings') async def v1_standings( season: Optional[int] = SEASON_DEFAULT, team_abbrev: Optional[str] = None, return_type: Optional[str] = 'json', league_abbrev: Optional[str] = None, division_abbrev: Optional[str] = None, csv: Optional[bool] = False): """ :param season: int :param team_abbrev: string, overrides league/division_abbrev :param league_abbrev: string :param division_abbrev: string """ standings = Standings.select_season(season) if standings.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for season {season}') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') db.close() return model_to_dict(Standings.get_or_none(Standings.team == this_team)) if league_abbrev: these_divisions = Division.select().where(fn.Lower(Division.league_abbrev) == league_abbrev.lower()) if these_divisions.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for league {league_abbrev}') standings = standings.where(Standings.team.division << these_divisions) if division_abbrev: this_division = Division.select().where(fn.Lower(Division.division_abbrev) == division_abbrev.lower()) if not this_division: db.close() raise HTTPException(status_code=404, detail=f'No output for division {division_abbrev}') standings = standings.where(Standings.team.division << this_division) def win_pct(this_team_stan): if this_team_stan.wins + this_team_stan.losses == 0: return 0 else: return (this_team_stan.wins / (this_team_stan.wins + this_team_stan.losses)) + \ (this_team_stan.run_diff * .000001) div_teams = [team_stan for team_stan in standings] div_teams.sort(key=lambda team: win_pct(team), reverse=True) if return_type == 'csv' or csv: standings_list = [ ['season', 'team', 'league', 'division', 'wins', 'losses', 'run diff', 'div gb', 'div enum', 'wc gb', 'wc enum', 'home wins', 'home losses', 'away wins', 'away losses', 'last 8 wins', 'last 8 losses', 'streak wl', 'streak num', 'one run wins', 'one run losses', 'pythag_wins', 'pythag losses', 'wins v bote', 'losses v bote', 'wins v dc', 'losses v dc', 'wins v nlw', 'losses v nlw'] ] for line in div_teams: standings_list.append( [line.team.season, line.team.abbrev, line.team.division.league_abbrev, line.team.division.division_name, line.wins, line.losses, line.run_diff, line.div_gb, line.div_e_num, line.wc_gb, line.wc_e_num, line.home_wins, line.home_losses, line.away_wins, line.away_losses, line.last8_wins, line.last8_losses, line.streak_wl, line.streak_num, line.one_run_wins, line.one_run_losses, line.pythag_wins, line.pythag_losses, line.div1_wins, line.div1_losses, line.div2_wins, line.div2_losses, line.div3_wins, line.div3_losses] ) return_stats = DataFrame(standings_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_standings = {} for line in div_teams: return_standings[f'{line.team.abbrev}'] = model_to_dict(line) db.close() return return_standings @app.patch('/api/v1/standings/{stan_id}') async def v1_standings_patch( stan_id, wins: Optional[int] = None, losses: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch standings') try: this_stan = Standings.get_by_id(stan_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {stan_id}') if wins: this_stan.wins = wins if losses: this_stan.losses = losses this_stan.save() db.close() return model_to_dict(this_stan) @app.post('/api/v1/standings/s{season}/recalculate') async def v1_standings_recalculate(season: int, token: str = Depends(oauth2_scheme)): if not valid_token(token): db.close() raise HTTPException(status_code=401, detail='You are not authorized to calculate stats') code = Standings.recalculate(season) db.close() if code == 69: HTTPException(status_code=500, detail=f'Error recreating Standings rows') raise HTTPException(status_code=200, detail=f'Just recalculated standings for season {season}') @app.get('/api/v1/battingseasons') async def v1_battingseasons_get( season: Optional[int] = SEASON_DEFAULT, team_abbrev: Optional[str] = None, sort: Optional[str] = None, season_type: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ :param season: int :param player_id: int, overrides other args :param player_name: int, overrides team_abbrev :param team_abbrev: str, lowest priority arg :param sort: str, pa-desc; wara-desc """ all_stats = BattingSeason.select().where(BattingSeason.pa > 0) if season: all_stats = all_stats.where(BattingSeason.season == season) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for season {season}') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_players = Player.select_season(season).where(Player.team == this_team) all_stats = all_stats.where(BattingSeason.player << all_players) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for team {team_abbrev}') if season_type: all_stats = all_stats.where(fn.Lower(BattingSeason.season_type) == season_type.lower()) if sort: if sort == 'pa-desc': all_stats = all_stats.order_by(-BattingSeason.pa) elif sort == 'wara-desc': all_stats = all_stats.order_by(-BattingSeason.player.wara) if return_type == 'csv' or csv: stat_list = [ ['season', 'season_type', 'player', 'pa', 'ab', 'run', 'hit', 'rbi', 'double', 'triple', 'hr', 'bb', 'so', 'hbp', 'sac', 'ibb', 'gidp', 'sb', 'cs', 'bphr', 'bpfo', 'bp1b', 'bplo', 'xba', 'xbt'] ] for line in all_stats: stat_list.append( [line.player.season, line.season_type, line.player.name, line.pa, line.ab, line.run, line.hit, line.rbi, line.double, line.triple, line.hr, line.bb, line.so, line.hbp, line.sac, line.ibb, line.gidp, line.sb, line.cs, line.bphr, line.bpfo, line.bp1b, line.bplo, line.xba, line.xbt] ) return_stats = DataFrame(stat_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_stats = {} for line in all_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.get('/api/v1/battingseasons/{id_or_name}') async def v1_battingseasons_get_player(id_or_name): try: this_player = Player.get_by_id(id_or_name) except Exception as e: this_player = None if this_player: these_stats = BattingSeason.get_or_none(BattingSeason.player == this_player) if these_stats: db.close() return model_to_dict(these_stats) else: db.close() return {} else: these_players = Player.select().where(fn.Lower(Player.name) == id_or_name.lower()) if these_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Player {id_or_name} not found') these_stats = BattingSeason.select().where(BattingSeason.player << these_players) return_stats = {} for line in these_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.get('/api/v1/pitchingseasons') async def v1_pitchingseasons_get( season: int = SEASON_DEFAULT, team_abbrev: Optional[str] = None, sort: Optional[str] = None, season_type: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ :param season: int :param team_abbrev: str, lowest priority arg :param sort: str, ip-desc; wara-desc """ all_stats = PitchingSeason.select_season(season) if season: all_stats = all_stats.where(PitchingSeason.season == season) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for season {season}') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_players = Player.select_season(season).where(Player.team == this_team) all_stats = all_stats.where(PitchingSeason.player << all_players) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for team {team_abbrev}') if season_type: all_stats = all_stats.where(fn.Lower(PitchingSeason.season_type) == season_type.lower()) if sort: logging.warning('In sort!') if sort == 'ip-desc': logging.warning('Matched ip-desc') all_stats = all_stats.order_by(-PitchingSeason.ip) logging.warning(all_stats) elif sort == 'wara-desc': all_stats = all_stats.order_by(-PitchingSeason.player.wara) if return_type == 'csv' or csv: stat_list = [ ['season', 'season_type', 'player', 'ip', 'hit', 'run', 'erun', 'so', 'bb', 'hbp', 'wp', 'balk', 'hr', 'ir', 'irs', 'gs', 'win', 'loss', 'hold', 'sv', 'bsv', 'games'] ] for line in all_stats: stat_list.append( [line.player.season, line.season_type, line.player.name, line.ip, line.hit, line.run, line.erun, line.so, line.bb, line.hbp, line.wp, line.balk, line.hr, line.ir, line.irs, line.gs, line.win, line.loss, line.hold, line.sv, line.bsv, line.game] ) return_stats = DataFrame(stat_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_stats = {} for line in all_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.get('/api/v1/pitchingseasons/{id_or_name}') async def v1_pitchingseasons_get_player(id_or_name): try: this_player = Player.get_by_id(id_or_name) except Exception as e: this_player = None if this_player: these_stats = PitchingSeason.get_or_none(PitchingSeason.player == this_player) if these_stats: db.close() return model_to_dict(these_stats) else: db.close() return {} else: these_players = Player.select().where(fn.Lower(Player.name) == id_or_name.lower()) if these_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Player {id_or_name} not found') these_stats = PitchingSeason.select().where(PitchingSeason.player << these_players) return_stats = {} for line in these_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.get('/api/v1/fieldingseasons') async def v1_fieldingseasons_get( season: int = SEASON_DEFAULT, team_abbrev: Optional[str] = None, position: Optional[str] = None, season_type: Optional[str] = None, sort: Optional[str] = None, return_type: Optional[str] = 'json', csv: Optional[bool] = False): """ :param season: int :param player_id: int, overrides other args :param player_name: int, overrides team_abbrev :param team_abbrev: str, lowest priority arg :param position: str :param sort: str, pa-desc; wara-desc """ all_stats = FieldingSeason.select_season(season).where((FieldingSeason.xch + FieldingSeason.sbc) > 0) if season: all_stats = all_stats.where(FieldingSeason.season == season) if position: all_stats = all_stats.where(FieldingSeason.pos == position.upper()) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for season {season}') if team_abbrev: this_team = Team.get_season(team_abbrev, season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {team_abbrev} not found') all_players = Player.select_season(season).where(Player.team == this_team) all_stats = all_stats.where(FieldingSeason.player << all_players) if all_stats.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for team {team_abbrev}') if season_type: all_stats = all_stats.where(fn.Lower(FieldingSeason.season_type) == season_type.lower()) if sort: if sort == 'xch-desc': all_stats = all_stats.order_by(-(FieldingSeason.xch + FieldingSeason.sbc)) elif sort == 'wara-desc': all_stats = all_stats.order_by(-FieldingSeason.player.wara) if return_type == 'csv' or csv: stat_list = [ ['season', 'season_type', 'player', 'pos', 'xch', 'xhit', 'error', 'pb', 'sbc', 'csc', 'roba', 'robs', 'raa', 'rto'] ] for line in all_stats: stat_list.append( [line.player.season, line.season_type, line.player.name, line.pos, line.xch, line.xhit, line.error, line.pb, line.sbc, line.csc, line.roba, line.robs, line.raa, line.rto] ) return_stats = DataFrame(stat_list).to_csv(header=False, index=False) db.close() return Response(content=return_stats, media_type='text/csv') else: return_stats = {} for line in all_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.get('/api/v1/fieldingseasons/{id_or_name}') async def v1_fieldingseasons_get_player(id_or_name): try: this_player = Player.get_by_id(id_or_name) except Exception as e: this_player = None if this_player: these_stats = FieldingSeason.get_or_none(FieldingSeason.player == this_player) if these_stats: db.close() return model_to_dict(these_stats) else: db.close() return {} else: these_players = Player.select().where(fn.Lower(Player.name) == id_or_name.lower()) if these_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Player {id_or_name} not found') these_stats = FieldingSeason.select().where(FieldingSeason.player << these_players) return_stats = {} for line in these_stats: return_stats[f'{line.id}'] = model_to_dict(line) db.close() return return_stats @app.get('/api/v1/draftpicks') async def v1_draftpicks_get( season: int = SEASON_DEFAULT, owner_team_abbrev: Optional[str] = None, orig_team_abbrev: Optional[str] = None, pick_round_start: Optional[int] = None, pick_round_end: Optional[int] = None, traded: Optional[bool] = None, overall: Optional[int] = None, team_season: Optional[int] = None, overall_start: Optional[int] = None, overall_end: Optional[int] = None, return_type = 'json', csv: Optional[bool] = False): """ :param season: int :param owner_team_abbrev: string :param orig_team_abbrev: string :param pick_round_start: int :param pick_round_end: int :param traded: bool :param overall: int """ all_picks = DraftPick.select_season(season) if all_picks.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No picks found for season {season}') if owner_team_abbrev: if not team_season: team_season = season this_team = Team.get_season(owner_team_abbrev, team_season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {owner_team_abbrev} not found') all_picks = all_picks.where(DraftPick.owner == this_team) if all_picks.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for team {owner_team_abbrev}') if orig_team_abbrev: if not team_season: team_season = season this_team = Team.get_season(orig_team_abbrev, team_season) if not this_team: db.close() raise HTTPException(status_code=404, detail=f'Team {orig_team_abbrev} not found') all_picks = all_picks.where(DraftPick.origowner == this_team) if all_picks.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No output for team {orig_team_abbrev}') if pick_round_start and pick_round_end: if pick_round_start > pick_round_end: db.close() raise HTTPException(status_code=400, detail=f'Cannot search for pick with end round before start round') if pick_round_start: all_picks = all_picks.where(DraftPick.round >= pick_round_start) if all_picks.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No picks found beginning in round {pick_round_start}') if pick_round_end: all_picks = all_picks.where(DraftPick.round <= pick_round_end) if all_picks.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'No picks found ending with round {pick_round_end}') if traded: all_picks = all_picks.where(DraftPick.origowner != DraftPick.owner) if overall is not None: all_picks = all_picks.where(DraftPick.overall == overall) if overall_start: all_picks = all_picks.where(DraftPick.overall >= overall_start) if overall_end: all_picks = all_picks.where(DraftPick.overall <= overall_end) logging.info('Trying to spit out draft picks') if return_type == 'csv' or csv: logging.info('Working on csv') pick_list = [ ['season', 'overall', 'round', 'orig_owner', 'owner', 'player', 'swar'] ] logging.info(f'built the pick_list / len(all_picks): {len(all_picks)}') for line in all_picks: logging.info(f'line: {line}') pick_list.append( [line.season, line.overall, line.round, line.origowner.abbrev, line.owner.abbrev, f'{line.player.name if line.player else ""}', f'{line.player.wara if line.player else ""}'] ) logging.info('filled the pick_list') return_picks = DataFrame(pick_list).to_csv(header=False, index=False) db.close() return Response(content=return_picks, media_type='text/csv') else: return_picks = {} for line in all_picks: return_picks[f'{line.id}'] = model_to_dict(line) db.close() return return_picks @app.post('/api/v1/draftpicks') async def v1_draftpicks_post(picks: DraftPickModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post draft picks') all_picks = [] for x in picks.picks: this_origowner = None if x.origowner_id: try: this_origowner = Team.get_by_id(x.origowner_id) except: db.close() raise HTTPException(status_code=404, detail=f'No owner found with id {x.origowner_id}') this_owner = None if x.owner_id: try: this_owner = Team.get_by_id(x.owner_id) except: db.close() raise HTTPException(status_code=404, detail=f'No owner found with id {x.owner_id}') else: this_owner = this_origowner this_player = None if x.player_id: try: this_player = Player.get_by_id(x.player_id) except: db.close() raise HTTPException(status_code=404, detail=f'No player found with id {x.player_id}') this_pick = DraftPick( season=x.season, overall=x.overall, round=x.round, origowner=this_origowner, owner=this_owner, player=this_player ) all_picks.append(this_pick) with db.atomic(): DraftPick.bulk_create(all_picks, batch_size=15) db.close() raise HTTPException(status_code=200, detail=f'Created {len(all_picks)} draft picks') # player_id is not checked for [int] to enable False as a clear parameter @app.patch('/api/v1/draftpicks/{pick_id}') async def v1_draftpicks_patch( pick_id: int, overall: Optional[int] = None, round: Optional[int] = None, orig_owner_id: Optional[int] = None, owner_id: Optional[int] = None, season: Optional[int] = None, player_id=None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch draft picks') try: this_pick = DraftPick.get_by_id(pick_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {pick_id}') if overall: this_pick.overall = overall if season: this_pick.season = season if round: this_pick.round = round if orig_owner_id: try: orig_owner = Team.get_by_id(orig_owner_id) this_pick.origowner = orig_owner except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {orig_owner_id}') if owner_id: try: new_owner = Team.get_by_id(owner_id) this_pick.owner = new_owner except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No team found with id {owner_id}') if player_id is not None: if player_id.lower() == 'false': this_pick.player = None else: try: this_player = Player.get_by_id(player_id) this_pick.player = this_player except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'No player found with id {player_id}') this_pick.save() db.close() return model_to_dict(this_pick) @app.get('/api/v1/draftpicks/{pick_id}') async def v1_draftpicks_get_one(pick_id): try: this_pick = DraftPick.get_or_none(DraftPick.id == pick_id) except Exception as e: db.close() raise HTTPException(status_code=404, detail=f'Draft pick id {pick_id} not found') db.close() return model_to_dict(this_pick) @app.get('/api/v1/draftdata') async def v1_draftdata(): draft_data = DraftData.get_or_none() db.close() if not draft_data: db.close() raise HTTPException(status_code=404, detail=f'No draft data found') else: db.close() return model_to_dict(draft_data) @app.patch('/api/v1/draftdata') async def v1_draftdata_patch( currentpick: Optional[int] = None, timer: Optional[bool] = None, pick_deadline: Optional[datetime.datetime] = None, result_channel: Optional[int] = None, ping_channel: Optional[int] = None, pick_minutes: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch draftdata') draft_data = DraftData.get_or_none() if not draft_data: db.close() raise HTTPException(status_code=404, detail=f'No draft data found') if currentpick is not None: draft_data.currentpick = currentpick if timer is not None: draft_data.timer = timer if pick_deadline is not None: draft_data.pick_deadline = pick_deadline if result_channel is not None: draft_data.result_channel = result_channel if ping_channel is not None: draft_data.ping_channel = ping_channel if pick_minutes is not None: draft_data.pick_minutes = pick_minutes saved = draft_data.save() db.close() if saved == 1: return model_to_dict(draft_data) else: raise HTTPException(status_code=500, detail='Updating draft data failed') @app.get('/api/v1/leaders') async def v1_leaders( group: str = 'batting', season=SEASON_DEFAULT, team_abbrev: Optional[str] = None, league_abbrev: Optional[str] = None, division_abbrev: Optional[str] = None): current = Current.get_or_none(season=season) all_leaders = None if season == 1: min_ip = 68 min_pa = 204 min_ch_high = 34 min_ch_mid = 17 min_ch_low = 8 min_ch_pit = 4 elif season == 2: min_ip = 76 min_pa = 228 min_ch_high = 38 min_ch_mid = 19 min_ch_low = 9 min_ch_pit = 4 elif int(season) < SEASON_DEFAULT: min_ip = 88 min_pa = 264 min_ch_high = 44 min_ch_mid = 22 min_ch_low = 11 min_ch_pit = 5 else: min_ip = ((current.week - 1) * 4) if current.week > 5 else current.week * 2 min_pa = ((current.week - 1) * 12) if current.week > 5 else current.week * 6 min_ch_high = ((current.week - 1) * 2) if current.week > 5 else current.week min_ch_mid = (min_ch_high / 2) if (min_ch_high / 2) > 1 else 1 min_ch_low = (min_ch_high / 4) if (min_ch_high / 3) > 1 else 1 min_ch_pit = (min_ch_high / 8) if (min_ch_high / 6) > 1 else 1 if group == 'pitching': all_leaders = { 'Starter Wins': {'abbrev': 'W', 'leaders': []}, 'Wins': {'abbrev': 'W', 'leaders': []}, 'Earned Run Average': {'abbrev': 'ERA', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Innings Pitched': {'abbrev': 'IP', 'leaders': []}, 'Strikeouts per Nine': {'abbrev': 'K/9', 'leaders': []}, 'Walks + Hits / IP': {'abbrev': 'WHIP', 'leaders': []}, 'Saves': {'abbrev': 'SV', 'leaders': []}, 'Walks Allowed': {'abbrev': 'BB', 'leaders': []}, 'Runs Allowed': {'abbrev': 'R', 'leaders': []}, 'Earned Runs Allowed': {'abbrev': 'ER', 'leaders': []}, 'Blown Saves': {'abbrev': 'BSV', 'leaders': []}, 'Hit By Pitches Allowed': {'abbrev': 'HBP', 'leaders': []}, 'Hits Allowed': {'abbrev': 'H', 'leaders': []}, 'Home Runs Allowed': {'abbrev': 'HR', 'leaders': []}, 'Wild Pitches': {'abbrev': 'WP', 'leaders': []}, 'Holds': {'abbrev': 'HD', 'leaders': []}, 'Walks Per Nine': {'abbrev': 'BB/9', 'leaders': []}, 'Strikeouts Per Walk': {'abbrev': 'K/BB', 'leaders': []}, 'Losses': {'abbrev': 'L', 'leaders': []}, 'Inherited Runners': {'abbrev': 'IR', 'leaders': []}, 'Inherited Runners Scored': {'abbrev': 'IRS', 'leaders': []}, 'Runners Stranded %': {'abbrev': 'RS%', 'leaders': []}, } top_swin = (PitchingStat .select(PitchingStat.player, fn.COUNT(PitchingStat.win).alias('swin')) .where(PitchingStat.season == season, PitchingStat.gs == 1, PitchingStat.win == 1) .order_by(-fn.COUNT(PitchingStat.win), PitchingStat.player) .group_by(PitchingStat.player) .limit(10)) top_win = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.win) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.win, PitchingSeason.player) .limit(10)) top_ip = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.ip) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.ip, PitchingSeason.player) .limit(10)) top_so = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.so) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.so, PitchingSeason.player) .limit(10)) top_era = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.erun, PitchingSeason.ip) .where(PitchingSeason.season == season, PitchingSeason.ip >= min_ip) .order_by(((PitchingSeason.erun * 9) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_kpn = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.so, PitchingSeason.ip) .where(PitchingSeason.season == season, PitchingSeason.ip >= min_ip) .order_by(-((PitchingSeason.so * 9) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_whip = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb, PitchingSeason.hit, PitchingSeason.ip) .where(PitchingSeason.season == season, PitchingSeason.ip >= min_ip) .order_by(+((PitchingSeason.bb + PitchingSeason.hit) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_sv = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.sv) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.sv, PitchingSeason.player) .limit(10)) top_bb = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.bb, PitchingSeason.player) .limit(10)) top_run = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.run) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.run, PitchingSeason.player) .limit(10)) top_erun = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.erun) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.erun, PitchingSeason.player) .limit(10)) top_bsv = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bsv) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.bsv, PitchingSeason.player) .limit(10)) top_hbp = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hbp) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.hbp, PitchingSeason.player) .limit(10)) top_hit = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hit) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.hit, PitchingSeason.player) .limit(10)) top_hr = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hr) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.hr, PitchingSeason.player) .limit(10)) top_wp = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.wp) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.wp, PitchingSeason.player) .limit(10)) top_hd = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hold) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.hold, PitchingSeason.player) .limit(10)) top_bpn = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb, PitchingSeason.ip) .where(PitchingSeason.season == season, PitchingSeason.ip >= min_ip) .order_by(((PitchingSeason.bb * 9) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_kpw = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb, PitchingSeason.so) .where(PitchingSeason.season == season, PitchingSeason.ip >= min_ip) .order_by(-(PitchingSeason.so / PitchingSeason.bb), PitchingSeason.player) .limit(10)) top_los = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.loss) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.loss, PitchingSeason.player) .limit(10)) top_ir = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.ir) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.ir, PitchingSeason.player) .limit(10)) top_irs = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.irs) .where(PitchingSeason.season == season) .order_by(-PitchingSeason.irs, PitchingSeason.player) .limit(10)) top_irp = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.ir, PitchingSeason.irs) .where(PitchingSeason.season == season, PitchingSeason.ir >= current.week) .order_by(-((PitchingSeason.ir - PitchingSeason.irs) / PitchingSeason.ir), PitchingSeason.player) .limit(10)) db.close() for x in top_swin: all_leaders['Starter Wins']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.swin)} ) for x in top_win: all_leaders['Wins']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.win)} ) for x in top_ip: all_leaders['Innings Pitched']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{x.ip:.1f}'} ) for x in top_so: all_leaders['Strikeouts']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.so)} ) for x in top_era: all_leaders['Earned Run Average']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.erun * 9) / x.ip):.2f}'} ) for x in top_kpn: all_leaders['Strikeouts per Nine']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.so * 9) / x.ip):.2f}'} ) for x in top_whip: all_leaders['Walks + Hits / IP']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.bb + x.hit) / x.ip):.2f}'} ) for x in top_sv: all_leaders['Saves']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.sv)} ) for x in top_bb: all_leaders['Walks Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bb)} ) for x in top_run: all_leaders['Runs Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.run)} ) for x in top_erun: all_leaders['Earned Runs Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.erun)} ) for x in top_bsv: all_leaders['Blown Saves']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bsv)} ) for x in top_hbp: all_leaders['Hit By Pitches Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hbp)} ) for x in top_hit: all_leaders['Hits Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hit)} ) for x in top_hr: all_leaders['Home Runs Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hr)} ) for x in top_wp: all_leaders['Wild Pitches']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.wp)} ) for x in top_hd: all_leaders['Holds']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hold)} ) for x in top_bpn: all_leaders['Walks Per Nine']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.bb * 9) / x.ip):.2f}'} ) for x in top_kpw: all_leaders['Strikeouts Per Walk']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.so / x.bb):.2f}'} ) for x in top_los: all_leaders['Losses']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.loss)} ) for x in top_ir: all_leaders['Inherited Runners']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.ir)} ) for x in top_irs: all_leaders['Inherited Runners Scored']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.irs)} ) for x in top_irp: all_leaders['Runners Stranded %']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.ir - x.irs) / x.ir) * 100:.1f}'} ) elif group == 'fielding': all_leaders = { 'Fielding Chances': {'abbrev': 'X-Ch', 'leaders': []}, 'Weighted Fielding % (RF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (CF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (LF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (SS)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (3B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (2B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (1B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (C)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (P)': {'abbrev': 'wF%', 'leaders': []}, 'Errors': {'abbrev': 'E', 'leaders': []}, 'Hits Allowed': {'abbrev': 'X-Hit', 'leaders': []}, 'Passed Balls': {'abbrev': 'PB', 'leaders': []}, 'Steal Attempts Against': {'abbrev': 'SBa', 'leaders': []}, 'Runners Thrown Out (C)': {'abbrev': 'CSc', 'leaders': []}, 'Caught Stealing % (Catchers)': {'abbrev': 'CS%', 'leaders': []}, } top_xch = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.sbc) .where(FieldingSeason.season == season) .order_by(-(FieldingSeason.xch + FieldingSeason.sbc), FieldingSeason.player) .limit(10)) raw_ss = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'SS') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_high))) raw_cf = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'CF') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_mid))) raw_2b = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == '2B') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_high))) raw_3b = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == '3B') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_mid))) raw_1b = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == '1B') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_mid))) raw_lf = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'LF') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_low))) raw_rf = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'RF') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_low))) raw_ca = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'C') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_mid))) raw_pi = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'P') & (FieldingSeason.season == season) & (FieldingSeason.xch >= min_ch_pit))) top_err = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.error) .where(FieldingSeason.season == season) .order_by(-FieldingSeason.error, FieldingSeason.player) .limit(10)) top_hit = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xhit) .where(FieldingSeason.season == season) .order_by(-FieldingSeason.xhit, FieldingSeason.player) .limit(10)) top_sbc = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.sbc) .where((FieldingSeason.season == season) & (FieldingSeason.sbc > 0)) .order_by(-FieldingSeason.sbc, FieldingSeason.player) .limit(10)) top_csc = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.csc) .where((FieldingSeason.season == season) & (FieldingSeason.csc > 0)) .order_by(-FieldingSeason.csc, FieldingSeason.player) .limit(10)) top_csp = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.sbc, FieldingSeason.csc) .where((FieldingSeason.season == season) & (FieldingSeason.sbc >= min_ch_low)) .order_by(-(FieldingSeason.csc / FieldingSeason.sbc), FieldingSeason.player) .limit(10)) top_pb = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.pb) .where((FieldingSeason.season == season) & (FieldingSeason.pb > 0)) .order_by(-FieldingSeason.pb, FieldingSeason.player) .limit(10)) # Removed for season 5 # top_roba = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.roba) # .where((FieldingSeason.season == season) & (FieldingSeason.roba > 0)) # .order_by(-FieldingSeason.roba, FieldingSeason.player) # .limit(10)) # top_robs = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.robs) # .where((FieldingSeason.season == season) & (FieldingSeason.robs > 0)) # .order_by(-FieldingSeason.robs, FieldingSeason.player) # .limit(10)) # top_raa = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.raa) # .where((FieldingSeason.season == season) & (FieldingSeason.raa > 0)) # .order_by(-FieldingSeason.raa, FieldingSeason.player) # .limit(10)) # top_rto = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.rto) # .where((FieldingSeason.season == season) & (FieldingSeason.rto > 0)) # .order_by(-FieldingSeason.rto, FieldingSeason.player) # .limit(10)) db.close() for x in top_xch: all_leaders['Fielding Chances']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.xch + x.sbc} ) for x in top_err: all_leaders['Errors']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.error} ) for x in top_sbc: all_leaders['Steal Attempts Against']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.sbc} ) for x in top_csc: all_leaders['Runners Thrown Out (C)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.csc} ) for x in top_csp: all_leaders['Caught Stealing % (Catchers)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{x.csc * 100 / x.sbc:.1f}'} ) for x in top_hit: all_leaders['Hits Allowed']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.xhit} ) for x in top_pb: all_leaders['Passed Balls']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.pb} ) # for x in top_roba: # all_leaders['Rob Attempts']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.roba} # ) # for x in top_robs: # all_leaders['Rob Successes']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.robs} # ) # for x in top_raa: # all_leaders['Runner Advance Attempts']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.raa} # ) # for x in top_rto: # all_leaders['Runners Thrown Out (OF)']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': x.rto} # ) for x in raw_ss: all_leaders['Weighted Fielding % (SS)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_cf: all_leaders['Weighted Fielding % (CF)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_2b: all_leaders['Weighted Fielding % (2B)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_3b: all_leaders['Weighted Fielding % (3B)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_1b: all_leaders['Weighted Fielding % (1B)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_lf: all_leaders['Weighted Fielding % (LF)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_rf: all_leaders['Weighted Fielding % (RF)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_ca: all_leaders['Weighted Fielding % (C)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_pi: all_leaders['Weighted Fielding % (P)']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for stat in all_leaders: if 'Weighted Fielding' in stat: all_leaders[stat]['leaders'] = sorted( all_leaders[stat]['leaders'], key=lambda leader: leader['stat'], reverse=True ) all_leaders[stat]['leaders'] = all_leaders[stat]['leaders'][:10] else: # return batting leaders all_leaders = { 'Home Runs': {'abbrev': 'HR', 'leaders': []}, 'Batting Average': {'abbrev': 'AVG', 'leaders': []}, 'On Base Percentage': {'abbrev': 'OBP', 'leaders': []}, 'Slugging Percentage': {'abbrev': 'SLG', 'leaders': []}, 'On Base Plus Slugging': {'abbrev': 'OPS', 'leaders': []}, 'Weighted On Base Avg': {'abbrev': 'wOBA', 'leaders': []}, 'Avg on Balls in Play': {'abbrev': 'BABIP', 'leaders': []}, 'Runs Batted In': {'abbrev': 'RBI', 'leaders': []}, 'Doubles': {'abbrev': '2B', 'leaders': []}, 'Triples': {'abbrev': '3B', 'leaders': []}, 'Hits': {'abbrev': 'H', 'leaders': []}, 'Plate Appearances': {'abbrev': 'PA', 'leaders': []}, 'Ground Into Double Play': {'abbrev': 'GIDP', 'leaders': []}, 'Walks': {'abbrev': 'BB', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Hit By Pitch': {'abbrev': 'HBP', 'leaders': []}, 'Intentional Walks': {'abbrev': 'IBB', 'leaders': []}, 'Stolen Bases': {'abbrev': 'SB', 'leaders': []}, 'Caught Stealing': {'abbrev': 'CS', 'leaders': []}, 'Runs Scored': {'abbrev': 'R', 'leaders': []}, 'At Bats': {'abbrev': 'AB', 'leaders': []}, 'No-Doubt Home Runs': {'abbrev': 'NDHR', 'leaders': []}, 'Ballpark Home Runs': {'abbrev': 'BPHR', 'leaders': []}, 'Ballpark Flyouts': {'abbrev': 'BPFO', 'leaders': []}, 'Ballpark Singles': {'abbrev': 'BP1B', 'leaders': []}, 'Ballpark Lineouts': {'abbrev': 'BPLO', 'leaders': []}, } top_avg = (BattingSeason .select() .where((BattingSeason.pa >= min_pa) & (BattingSeason.season == season)) .order_by(-(BattingSeason.hit / BattingSeason.ab), BattingSeason.player) .limit(10)) top_hr = (BattingSeason .select(BattingSeason.player, BattingSeason.hr) .where(BattingSeason.season == season) .order_by(-BattingSeason.hr, BattingSeason.player) .limit(10)) top_obp = (BattingSeason .select() .where((BattingSeason.pa >= min_pa) & (BattingSeason.season == season)) .order_by( -((BattingSeason.hit + BattingSeason.bb + BattingSeason.hbp + BattingSeason.ibb) / BattingSeason.pa), BattingSeason.player) .limit(10)) top_slg = (BattingSeason .select() .where((BattingSeason.pa >= min_pa) & (BattingSeason.season == season)) .order_by(-(((BattingSeason.hr * 4) + (BattingSeason.triple * 3) + (BattingSeason.double * 2) + ( BattingSeason.hit - BattingSeason.hr - BattingSeason.triple - BattingSeason.double)) / BattingSeason.ab)) .limit(10)) top_ops = (BattingSeason .select() .where((BattingSeason.pa >= min_pa) & (BattingSeason.season == season)) .order_by(-((BattingSeason.ab * ( BattingSeason.hit + BattingSeason.bb + BattingSeason.ibb + BattingSeason.hbp) + ( (BattingSeason.hr * 4) + (BattingSeason.triple * 3) + ( BattingSeason.double * 2) + ( BattingSeason.hit - BattingSeason.double - BattingSeason.triple - BattingSeason.hr)) * ( BattingSeason.ab + BattingSeason.bb + BattingSeason.ibb + BattingSeason.sac + BattingSeason.hbp)) / (BattingSeason.ab * ( BattingSeason.ab + BattingSeason.bb + BattingSeason.ibb + BattingSeason.sac + BattingSeason.hbp)))) .limit(10)) top_wob = (BattingSeason .select() .where((BattingSeason.pa >= min_pa) & (BattingSeason.season == season)) .order_by(-(((BattingSeason.bb * .69) + (BattingSeason.hbp * .72) + (BattingSeason.hr * 2.1) + ( BattingSeason.triple * 1.62) + (BattingSeason.double * 1.27) + (( BattingSeason.hit - BattingSeason.double - BattingSeason.triple - BattingSeason.hr) * .89)) / ( BattingSeason.ab + BattingSeason.bb - BattingSeason.ibb + BattingSeason.sac + BattingSeason.hbp))) .limit(10)) top_bab = (BattingSeason .select() .where((BattingSeason.pa >= min_pa) & (BattingSeason.season == season)) .order_by(-((BattingSeason.hit - BattingSeason.hr) / (BattingSeason.ab - BattingSeason.so - BattingSeason.hr + BattingSeason.sac))) .limit(10)) top_rbi = (BattingSeason .select(BattingSeason.player, BattingSeason.rbi) .where(BattingSeason.season == season) .order_by(-BattingSeason.rbi, BattingSeason.player) .limit(10)) top_dbl = (BattingSeason .select(BattingSeason.player, BattingSeason.double) .where(BattingSeason.season == season) .order_by(-BattingSeason.double, BattingSeason.player) .limit(10)) top_trp = (BattingSeason .select(BattingSeason.player, BattingSeason.triple) .where(BattingSeason.season == season) .order_by(-BattingSeason.triple, BattingSeason.player) .limit(10)) top_hit = (BattingSeason .select(BattingSeason.player, BattingSeason.hit) .where(BattingSeason.season == season) .order_by(-BattingSeason.hit, BattingSeason.player) .limit(10)) top_pa = (BattingSeason .select(BattingSeason.player, BattingSeason.pa) .where(BattingSeason.season == season) .order_by(-BattingSeason.pa, BattingSeason.player) .limit(10)) top_gdp = (BattingSeason .select(BattingSeason.player, BattingSeason.gidp) .where(BattingSeason.season == season) .order_by(-BattingSeason.gidp, BattingSeason.player) .limit(10)) top_bb = (BattingSeason .select(BattingSeason.player, BattingSeason.bb) .where(BattingSeason.season == season) .order_by(-BattingSeason.bb, BattingSeason.player) .limit(10)) top_so = (BattingSeason .select(BattingSeason.player, BattingSeason.so) .where(BattingSeason.season == season) .order_by(-BattingSeason.so, BattingSeason.player) .limit(10)) top_hbp = (BattingSeason .select(BattingSeason.player, BattingSeason.hbp) .where(BattingSeason.season == season) .order_by(-BattingSeason.hbp, BattingSeason.player) .limit(10)) top_ibb = (BattingSeason .select(BattingSeason.player, BattingSeason.ibb) .where(BattingSeason.season == season) .order_by(-BattingSeason.ibb, BattingSeason.player) .limit(10)) top_sb = (BattingSeason .select(BattingSeason.player, BattingSeason.sb) .where(BattingSeason.season == season) .order_by(-BattingSeason.sb, BattingSeason.player) .limit(10)) top_cs = (BattingSeason .select(BattingSeason.player, BattingSeason.cs) .where(BattingSeason.season == season) .order_by(-BattingSeason.cs, BattingSeason.player) .limit(10)) top_run = (BattingSeason .select(BattingSeason.player, BattingSeason.run) .where(BattingSeason.season == season) .order_by(-BattingSeason.run, BattingSeason.player) .limit(10)) top_ab = (BattingSeason .select(BattingSeason.player, BattingSeason.ab) .where(BattingSeason.season == season) .order_by(-BattingSeason.ab, BattingSeason.player) .limit(10)) top_bphr = (BattingSeason .select(BattingSeason.player, BattingSeason.bphr) .where((BattingSeason.season == season) & (BattingSeason.bphr > 0)) .order_by(-BattingSeason.bphr, BattingSeason.player) .limit(10)) top_bpfo = (BattingSeason .select(BattingSeason.player, BattingSeason.bpfo) .where((BattingSeason.season == season) & (BattingSeason.bpfo > 0)) .order_by(-BattingSeason.bpfo, BattingSeason.player) .limit(10)) top_bp1b = (BattingSeason .select(BattingSeason.player, BattingSeason.bp1b) .where((BattingSeason.season == season) & (BattingSeason.bp1b > 0)) .order_by(-BattingSeason.bp1b, BattingSeason.player) .limit(10)) top_bplo = (BattingSeason .select(BattingSeason.player, BattingSeason.bplo) .where((BattingSeason.season == season) & (BattingSeason.bplo > 0)) .order_by(-BattingSeason.bplo, BattingSeason.player) .limit(10)) # Removed for season 5 # top_xba = (BattingSeason # .select(BattingSeason.player, BattingSeason.xba) # .where((BattingSeason.season == season) & (BattingSeason.xba > 0)) # .order_by(-BattingSeason.xba, BattingSeason.player) # .limit(10)) # top_xbt = (BattingSeason # .select(BattingSeason.player, BattingSeason.xbt) # .where((BattingSeason.season == season) & (BattingSeason.xbt > 0)) # .order_by(-BattingSeason.xbt, BattingSeason.player) # .limit(10)) top_ndhr = (BattingSeason .select(BattingSeason.player, BattingSeason.bphr, BattingSeason.hr) .where((BattingSeason.season == season) & (BattingSeason.hr > 0)) .order_by(-(BattingSeason.hr - BattingSeason.bphr), BattingSeason.player) .limit(10)) db.close() for x in top_avg: all_leaders['Batting Average']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{x.hit / x.ab:.3f}'} ) for x in top_hr: all_leaders['Home Runs']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hr)} ) for x in top_obp: all_leaders['On Base Percentage']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.hit + x.bb + x.hbp + x.ibb) / x.pa:.3f}'} ) for x in top_slg: all_leaders['Slugging Percentage']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.hr * 4) + (x.triple * 3) + (x.double * 2) + (x.hit - x.hr - x.triple - x.double)) / x.ab:.3f}'} ) for x in top_ops: all_leaders['On Base Plus Slugging']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(x.ab * (x.hit + x.bb + x.ibb + x.hbp) + ((x.hr * 4) + (x.triple * 3) + (x.double * 2) + (x.hit - x.double - x.triple - x.hr)) * (x.ab + x.bb + x.ibb + x.sac + x.hbp)) / (x.ab * (x.ab + x.bb + x.ibb + x.sac + x.hbp)):.3f}'} ) for x in top_wob: all_leaders['Weighted On Base Avg']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{(((x.bb * .69) + (x.hbp * .72) + (x.hr * 2.1) + (x.triple * 1.62) + (x.double * 1.27) + ((x.hit - x.double - x.triple - x.hr) * .89)) / (x.ab + x.bb - x.ibb + x.sac + x.hbp)):.3f}'} ) for x in top_bab: all_leaders['Avg on Balls in Play']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{((x.hit - x.hr) / (x.ab - x.so - x.hr + x.sac)):.3f}'} ) for x in top_rbi: all_leaders['Runs Batted In']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.rbi)} ) for x in top_dbl: all_leaders['Doubles']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.double)} ) for x in top_trp: all_leaders['Triples']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.triple)} ) for x in top_hit: all_leaders['Hits']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hit)} ) for x in top_pa: all_leaders['Plate Appearances']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.pa)} ) for x in top_gdp: all_leaders['Ground Into Double Play']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.gidp)} ) for x in top_bb: all_leaders['Walks']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bb)} ) for x in top_so: all_leaders['Strikeouts']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.so)} ) for x in top_hbp: all_leaders['Hit By Pitch']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.hbp)} ) for x in top_ibb: all_leaders['Intentional Walks']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.ibb)} ) for x in top_sb: all_leaders['Stolen Bases']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.sb)} ) for x in top_cs: all_leaders['Caught Stealing']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.cs)} ) for x in top_run: all_leaders['Runs Scored']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.run)} ) for x in top_ab: all_leaders['At Bats']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.ab)} ) for x in top_bphr: all_leaders['Ballpark Home Runs']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bphr)} ) for x in top_bpfo: all_leaders['Ballpark Flyouts']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bpfo)} ) for x in top_bp1b: all_leaders['Ballpark Singles']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bp1b)} ) for x in top_bplo: all_leaders['Ballpark Lineouts']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.bplo)} ) # for x in top_xba: # all_leaders['Extra Base Attempts']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.xba)} # ) # for x in top_xbt: # all_leaders['Extra Bases Taken']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.xbt)} # ) for x in top_ndhr: all_leaders['No-Doubt Home Runs']['leaders'].append( {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': f'{x.hr - x.bphr:.0f}'} ) db.close() return all_leaders @app.get('/api/v1/single-season-leaders') async def v1_single_season_leaders_get( group: str = 'batting', team_abbrev: Optional[str] = None, league_abbrev: Optional[str] = None, division_abbrev: Optional[str] = None): all_leaders = None min_ip = 76 min_pa = 228 min_ch_high = 38 min_ch_mid = 19 min_ch_low = 9 min_ch_pit = 5 weeks = 20 if group == 'pitching': all_leaders = { # 'Starter Wins': {'abbrev': 'W', 'leaders': []}, 'Wins': {'abbrev': 'W', 'leaders': []}, 'Earned Run Average': {'abbrev': 'ERA', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Innings Pitched': {'abbrev': 'IP', 'leaders': []}, 'Strikeouts per Nine': {'abbrev': 'K/9', 'leaders': []}, 'Walks + Hits / IP': {'abbrev': 'WHIP', 'leaders': []}, 'Saves': {'abbrev': 'SV', 'leaders': []}, 'Walks Allowed': {'abbrev': 'BB', 'leaders': []}, 'Runs Allowed': {'abbrev': 'R', 'leaders': []}, 'Earned Runs Allowed': {'abbrev': 'ER', 'leaders': []}, 'Blown Saves': {'abbrev': 'BSV', 'leaders': []}, 'Hit By Pitches Allowed': {'abbrev': 'HBP', 'leaders': []}, 'Hits Allowed': {'abbrev': 'H', 'leaders': []}, 'Home Runs Allowed': {'abbrev': 'HR', 'leaders': []}, 'Wild Pitches': {'abbrev': 'WP', 'leaders': []}, 'Holds': {'abbrev': 'HD', 'leaders': []}, 'Walks Per Nine': {'abbrev': 'BB/9', 'leaders': []}, 'Strikeouts Per Walk': {'abbrev': 'K/BB', 'leaders': []}, 'Losses': {'abbrev': 'L', 'leaders': []}, 'Inherited Runners': {'abbrev': 'IR', 'leaders': []}, 'Inherited Runners Scored': {'abbrev': 'IRS', 'leaders': []}, 'Runners Stranded %': {'abbrev': 'RS%', 'leaders': []}, } # top_swin = (PitchingStat # .select(PitchingStat.player, fn.COUNT(PitchingStat.win).alias('swin')) # .where(PitchingStat.gs == 1, PitchingStat.win == 1) # .order_by(-fn.COUNT(PitchingStat.win), PitchingStat.player) # .group_by(PitchingStat.player) # .limit(10)) top_win = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.win) .order_by(-PitchingSeason.win, PitchingSeason.player) .limit(10)) top_ip = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.ip) .order_by(-PitchingSeason.ip, PitchingSeason.player) .limit(10)) top_so = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.so) .order_by(-PitchingSeason.so, PitchingSeason.player) .limit(10)) top_era = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.erun, PitchingSeason.ip) .where(PitchingSeason.ip >= min_ip) .order_by(((PitchingSeason.erun * 9) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_kpn = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.so, PitchingSeason.ip) .where(PitchingSeason.ip >= min_ip) .order_by(-((PitchingSeason.so * 9) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_whip = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb, PitchingSeason.hit, PitchingSeason.ip) .where(PitchingSeason.ip >= min_ip) .order_by(+((PitchingSeason.bb + PitchingSeason.hit) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_sv = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.sv) .order_by(-PitchingSeason.sv, PitchingSeason.player) .limit(10)) top_bb = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb) .order_by(-PitchingSeason.bb, PitchingSeason.player) .limit(10)) top_run = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.run) .order_by(-PitchingSeason.run, PitchingSeason.player) .limit(10)) top_erun = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.erun) .order_by(-PitchingSeason.erun, PitchingSeason.player) .limit(10)) top_bsv = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bsv) .order_by(-PitchingSeason.bsv, PitchingSeason.player) .limit(10)) top_hbp = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hbp) .order_by(-PitchingSeason.hbp, PitchingSeason.player) .limit(10)) top_hit = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hit) .order_by(-PitchingSeason.hit, PitchingSeason.player) .limit(10)) top_hr = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hr) .order_by(-PitchingSeason.hr, PitchingSeason.player) .limit(10)) top_wp = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.wp) .order_by(-PitchingSeason.wp, PitchingSeason.player) .limit(10)) top_hd = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.hold) .order_by(-PitchingSeason.hold, PitchingSeason.player) .limit(10)) top_bpn = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb, PitchingSeason.ip) .where(PitchingSeason.ip >= min_ip) .order_by(((PitchingSeason.bb * 9) / PitchingSeason.ip), PitchingSeason.player) .limit(10)) top_kpw = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.bb, PitchingSeason.so) .where(PitchingSeason.ip >= min_ip) .order_by(-(PitchingSeason.so / PitchingSeason.bb), PitchingSeason.player) .limit(10)) top_los = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.loss) .order_by(-PitchingSeason.loss, PitchingSeason.player) .limit(10)) top_ir = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.ir) .order_by(-PitchingSeason.ir, PitchingSeason.player) .limit(10)) top_irs = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.irs) .order_by(-PitchingSeason.irs, PitchingSeason.player) .limit(10)) top_irp = (PitchingSeason .select(PitchingSeason.player, PitchingSeason.ir, PitchingSeason.irs) .where(PitchingSeason.ir >= weeks) .order_by(-((PitchingSeason.ir - PitchingSeason.irs) / PitchingSeason.ir), PitchingSeason.player) .limit(10)) db.close() # for x in top_swin: # all_leaders['Starter Wins']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.swin)} # ) for x in top_win: all_leaders['Wins']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.win)} ) for x in top_ip: all_leaders['Innings Pitched']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{x.ip:.1f}'} ) for x in top_so: all_leaders['Strikeouts']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.so)} ) for x in top_era: all_leaders['Earned Run Average']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.erun * 9) / x.ip):.2f}'} ) for x in top_kpn: all_leaders['Strikeouts per Nine']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.so * 9) / x.ip):.2f}'} ) for x in top_whip: all_leaders['Walks + Hits / IP']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.bb + x.hit) / x.ip):.2f}'} ) for x in top_sv: all_leaders['Saves']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.sv)} ) for x in top_bb: all_leaders['Walks Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bb)} ) for x in top_run: all_leaders['Runs Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.run)} ) for x in top_erun: all_leaders['Earned Runs Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.erun)} ) for x in top_bsv: all_leaders['Blown Saves']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bsv)} ) for x in top_hbp: all_leaders['Hit By Pitches Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hbp)} ) for x in top_hit: all_leaders['Hits Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hit)} ) for x in top_hr: all_leaders['Home Runs Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hr)} ) for x in top_wp: all_leaders['Wild Pitches']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.wp)} ) for x in top_hd: all_leaders['Holds']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hold)} ) for x in top_bpn: all_leaders['Walks Per Nine']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.bb * 9) / x.ip):.2f}'} ) for x in top_kpw: all_leaders['Strikeouts Per Walk']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.so / x.bb):.2f}'} ) for x in top_los: all_leaders['Losses']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.loss)} ) for x in top_ir: all_leaders['Inherited Runners']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.ir)} ) for x in top_irs: all_leaders['Inherited Runners Scored']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.irs)} ) for x in top_irp: all_leaders['Runners Stranded %']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.ir - x.irs) / x.ir) * 100:.1f}'} ) elif group == 'fielding': all_leaders = { 'Fielding Chances': {'abbrev': 'X-Ch', 'leaders': []}, 'Weighted Fielding % (RF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (CF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (LF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (SS)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (3B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (2B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (1B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (C)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (P)': {'abbrev': 'wF%', 'leaders': []}, 'Errors': {'abbrev': 'E', 'leaders': []}, 'Hits Allowed': {'abbrev': 'X-Hit', 'leaders': []}, 'Passed Balls': {'abbrev': 'PB', 'leaders': []}, 'Steal Attempts Against': {'abbrev': 'SBa', 'leaders': []}, 'Runners Thrown Out (C)': {'abbrev': 'CSc', 'leaders': []}, 'Caught Stealing % (Catchers)': {'abbrev': 'CS%', 'leaders': []}, # 'Rob Attempts': {'abbrev': 'RobA', 'leaders': []}, # 'Rob Successes': {'abbrev': 'RobS', 'leaders': []}, # 'Runner Advance Attempts': {'abbrev': 'RAA', 'leaders': []}, # 'Runners Thrown Out (OF)': {'abbrev': 'RTO', 'leaders': []}, } top_xch = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.sbc) .order_by(-(FieldingSeason.xch + FieldingSeason.sbc), FieldingSeason.player) .limit(10)) raw_ss = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'SS') & (FieldingSeason.xch >= min_ch_high))) raw_cf = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'CF') & (FieldingSeason.xch >= min_ch_mid))) raw_2b = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == '2B') & (FieldingSeason.xch >= min_ch_high))) raw_3b = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == '3B') & (FieldingSeason.xch >= min_ch_mid))) raw_1b = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == '1B') & (FieldingSeason.xch >= min_ch_mid))) raw_lf = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'LF') & (FieldingSeason.xch >= min_ch_low))) raw_rf = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'RF') & (FieldingSeason.xch >= min_ch_low))) raw_ca = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'C') & (FieldingSeason.xch >= min_ch_mid))) raw_pi = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xch, FieldingSeason.xhit, FieldingSeason.error) .where( (FieldingSeason.pos == 'P') & (FieldingSeason.xch >= min_ch_pit))) top_err = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.error) .order_by(-FieldingSeason.error, FieldingSeason.player) .limit(10)) top_hit = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.xhit) .order_by(-FieldingSeason.xhit, FieldingSeason.player) .limit(10)) top_sbc = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.sbc) .where((FieldingSeason.sbc > 0)) .order_by(-FieldingSeason.sbc, FieldingSeason.player) .limit(10)) top_csc = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.csc) .where((FieldingSeason.csc > 0)) .order_by(-FieldingSeason.csc, FieldingSeason.player) .limit(10)) top_csp = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.sbc, FieldingSeason.csc) .where((FieldingSeason.sbc >= min_ch_mid)) .order_by(-(FieldingSeason.csc / FieldingSeason.sbc), FieldingSeason.player) .limit(10)) top_pb = (FieldingSeason .select(FieldingSeason.player, FieldingSeason.pb) .where((FieldingSeason.pb > 0)) .order_by(-FieldingSeason.pb, FieldingSeason.player) .limit(10)) # Removed for season 5 # top_roba = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.roba) # .where((FieldingSeason.roba > 0)) # .order_by(-FieldingSeason.roba, FieldingSeason.player) # .limit(10)) # top_robs = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.robs) # .where((FieldingSeason.robs > 0)) # .order_by(-FieldingSeason.robs, FieldingSeason.player) # .limit(10)) # top_raa = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.raa) # .where((FieldingSeason.raa > 0)) # .order_by(-FieldingSeason.raa, FieldingSeason.player) # .limit(10)) # top_rto = (FieldingSeason # .select(FieldingSeason.player, FieldingSeason.rto) # .where((FieldingSeason.rto > 0)) # .order_by(-FieldingSeason.rto, FieldingSeason.player) # .limit(10)) db.close() for x in top_xch: all_leaders['Fielding Chances']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.xch + x.sbc} ) for x in top_err: all_leaders['Errors']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.error} ) for x in top_sbc: all_leaders['Steal Attempts Against']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.sbc} ) for x in top_csc: all_leaders['Runners Thrown Out (C)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.csc} ) for x in top_csp: all_leaders['Caught Stealing % (Catchers)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{x.csc * 100 / x.sbc:.1f}'} ) for x in top_hit: all_leaders['Hits Allowed']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.xhit} ) for x in top_pb: all_leaders['Passed Balls']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.pb} ) # for x in top_roba: # all_leaders['Rob Attempts']['leaders'].append( # {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.roba} # ) # for x in top_robs: # all_leaders['Rob Successes']['leaders'].append( # {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.robs} # ) # for x in top_raa: # all_leaders['Runner Advance Attempts']['leaders'].append( # {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.raa} # ) # for x in top_rto: # all_leaders['Runners Thrown Out (OF)']['leaders'].append( # {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': x.rto} # ) for x in raw_ss: all_leaders['Weighted Fielding % (SS)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_cf: all_leaders['Weighted Fielding % (CF)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_2b: all_leaders['Weighted Fielding % (2B)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_3b: all_leaders['Weighted Fielding % (3B)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_1b: all_leaders['Weighted Fielding % (1B)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_lf: all_leaders['Weighted Fielding % (LF)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_rf: all_leaders['Weighted Fielding % (RF)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_ca: all_leaders['Weighted Fielding % (C)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_pi: all_leaders['Weighted Fielding % (P)']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for stat in all_leaders: if 'Weighted Fielding' in stat: all_leaders[stat]['leaders'] = sorted( all_leaders[stat]['leaders'], key=lambda leader: leader['stat'], reverse=True ) all_leaders[stat]['leaders'] = all_leaders[stat]['leaders'][:10] else: # return batting leaders all_leaders = { 'Home Runs': {'abbrev': 'HR', 'leaders': []}, 'Batting Average': {'abbrev': 'AVG', 'leaders': []}, 'On Base Percentage': {'abbrev': 'OBP', 'leaders': []}, 'Slugging Percentage': {'abbrev': 'SLG', 'leaders': []}, 'On Base Plus Slugging': {'abbrev': 'OPS', 'leaders': []}, 'Weighted On Base Avg': {'abbrev': 'wOBA', 'leaders': []}, 'Avg on Balls in Play': {'abbrev': 'BABIP', 'leaders': []}, 'Runs Batted In': {'abbrev': 'RBI', 'leaders': []}, 'Doubles': {'abbrev': '2B', 'leaders': []}, 'Triples': {'abbrev': '3B', 'leaders': []}, 'Hits': {'abbrev': 'H', 'leaders': []}, 'Plate Appearances': {'abbrev': 'PA', 'leaders': []}, 'Ground Into Double Play': {'abbrev': 'GIDP', 'leaders': []}, 'Walks': {'abbrev': 'BB', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Hit By Pitch': {'abbrev': 'HBP', 'leaders': []}, 'Intentional Walks': {'abbrev': 'IBB', 'leaders': []}, 'Stolen Bases': {'abbrev': 'SB', 'leaders': []}, 'Caught Stealing': {'abbrev': 'CS', 'leaders': []}, 'Runs Scored': {'abbrev': 'R', 'leaders': []}, 'At Bats': {'abbrev': 'AB', 'leaders': []}, 'No-Doubt Home Runs': {'abbrev': 'NDHR', 'leaders': []}, 'Ballpark Home Runs': {'abbrev': 'BPHR', 'leaders': []}, 'Ballpark Flyouts': {'abbrev': 'BPFO', 'leaders': []}, 'Ballpark Singles': {'abbrev': 'BP1B', 'leaders': []}, 'Ballpark Lineouts': {'abbrev': 'BPLO', 'leaders': []}, # 'Extra Base Attempts': {'abbrev': 'XBA', 'leaders': []}, # 'Extra Bases Taken': {'abbrev': 'XBT', 'leaders': []}, } top_avg = (BattingSeason .select() .where((BattingSeason.pa >= min_pa)) .order_by(-(BattingSeason.hit / BattingSeason.ab), BattingSeason.player) .limit(10)) top_hr = (BattingSeason .select(BattingSeason.player, BattingSeason.hr) .order_by(-BattingSeason.hr, BattingSeason.player) .limit(10)) top_obp = (BattingSeason .select() .where(BattingSeason.pa >= min_pa) .order_by( -((BattingSeason.hit + BattingSeason.bb + BattingSeason.hbp + BattingSeason.ibb) / BattingSeason.pa), BattingSeason.player) .limit(10)) top_slg = (BattingSeason .select() .where(BattingSeason.pa >= min_pa) .order_by(-(((BattingSeason.hr * 4) + (BattingSeason.triple * 3) + (BattingSeason.double * 2) + ( BattingSeason.hit - BattingSeason.hr - BattingSeason.triple - BattingSeason.double)) / BattingSeason.ab)) .limit(10)) top_ops = (BattingSeason .select() .where(BattingSeason.pa >= min_pa) .order_by(-((BattingSeason.ab * ( BattingSeason.hit + BattingSeason.bb + BattingSeason.ibb + BattingSeason.hbp) + ( (BattingSeason.hr * 4) + (BattingSeason.triple * 3) + ( BattingSeason.double * 2) + ( BattingSeason.hit - BattingSeason.double - BattingSeason.triple - BattingSeason.hr)) * ( BattingSeason.ab + BattingSeason.bb + BattingSeason.ibb + BattingSeason.sac + BattingSeason.hbp)) / (BattingSeason.ab * ( BattingSeason.ab + BattingSeason.bb + BattingSeason.ibb + BattingSeason.sac + BattingSeason.hbp)))) .limit(10)) top_wob = (BattingSeason .select() .where(BattingSeason.pa >= min_pa) .order_by(-(((BattingSeason.bb * .69) + (BattingSeason.hbp * .72) + (BattingSeason.hr * 2.1) + ( BattingSeason.triple * 1.62) + (BattingSeason.double * 1.27) + (( BattingSeason.hit - BattingSeason.double - BattingSeason.triple - BattingSeason.hr) * .89)) / ( BattingSeason.ab + BattingSeason.bb - BattingSeason.ibb + BattingSeason.sac + BattingSeason.hbp))) .limit(10)) top_bab = (BattingSeason .select() .where(BattingSeason.pa >= min_pa) .order_by(-((BattingSeason.hit - BattingSeason.hr) / (BattingSeason.ab - BattingSeason.so - BattingSeason.hr + BattingSeason.sac))) .limit(10)) top_rbi = (BattingSeason .select(BattingSeason.player, BattingSeason.rbi) .order_by(-BattingSeason.rbi, BattingSeason.player) .limit(10)) top_dbl = (BattingSeason .select(BattingSeason.player, BattingSeason.double) .order_by(-BattingSeason.double, BattingSeason.player) .limit(10)) top_trp = (BattingSeason .select(BattingSeason.player, BattingSeason.triple) .order_by(-BattingSeason.triple, BattingSeason.player) .limit(10)) top_hit = (BattingSeason .select(BattingSeason.player, BattingSeason.hit) .order_by(-BattingSeason.hit, BattingSeason.player) .limit(10)) top_pa = (BattingSeason .select(BattingSeason.player, BattingSeason.pa) .order_by(-BattingSeason.pa, BattingSeason.player) .limit(10)) top_gdp = (BattingSeason .select(BattingSeason.player, BattingSeason.gidp) .order_by(-BattingSeason.gidp, BattingSeason.player) .limit(10)) top_bb = (BattingSeason .select(BattingSeason.player, BattingSeason.bb) .order_by(-BattingSeason.bb, BattingSeason.player) .limit(10)) top_so = (BattingSeason .select(BattingSeason.player, BattingSeason.so) .order_by(-BattingSeason.so, BattingSeason.player) .limit(10)) top_hbp = (BattingSeason .select(BattingSeason.player, BattingSeason.hbp) .order_by(-BattingSeason.hbp, BattingSeason.player) .limit(10)) top_ibb = (BattingSeason .select(BattingSeason.player, BattingSeason.ibb) .order_by(-BattingSeason.ibb, BattingSeason.player) .limit(10)) top_sb = (BattingSeason .select(BattingSeason.player, BattingSeason.sb) .order_by(-BattingSeason.sb, BattingSeason.player) .limit(10)) top_cs = (BattingSeason .select(BattingSeason.player, BattingSeason.cs) .order_by(-BattingSeason.cs, BattingSeason.player) .limit(10)) top_run = (BattingSeason .select(BattingSeason.player, BattingSeason.run) .order_by(-BattingSeason.run, BattingSeason.player) .limit(10)) top_ab = (BattingSeason .select(BattingSeason.player, BattingSeason.ab) .order_by(-BattingSeason.ab, BattingSeason.player) .limit(10)) top_bphr = (BattingSeason .select(BattingSeason.player, BattingSeason.bphr) .where(BattingSeason.bphr > 0) .order_by(-BattingSeason.bphr, BattingSeason.player) .limit(10)) top_bpfo = (BattingSeason .select(BattingSeason.player, BattingSeason.bpfo) .where(BattingSeason.bpfo > 0) .order_by(-BattingSeason.bpfo, BattingSeason.player) .limit(10)) top_bp1b = (BattingSeason .select(BattingSeason.player, BattingSeason.bp1b) .where(BattingSeason.bp1b > 0) .order_by(-BattingSeason.bp1b, BattingSeason.player) .limit(10)) top_bplo = (BattingSeason .select(BattingSeason.player, BattingSeason.bplo) .where(BattingSeason.bplo > 0) .order_by(-BattingSeason.bplo, BattingSeason.player) .limit(10)) # top_xba = (BattingSeason # .select(BattingSeason.player, BattingSeason.xba) # .where(BattingSeason.xba > 0) # .order_by(-BattingSeason.xba, BattingSeason.player) # .limit(10)) # top_xbt = (BattingSeason # .select(BattingSeason.player, BattingSeason.xbt) # .where(BattingSeason.xbt > 0) # .order_by(-BattingSeason.xbt, BattingSeason.player) # .limit(10)) top_ndhr = (BattingSeason .select(BattingSeason.player, BattingSeason.bphr, BattingSeason.hr) .where(BattingSeason.hr > 0) .order_by(-(BattingSeason.hr - BattingSeason.bphr), BattingSeason.player) .limit(10)) db.close() for x in top_avg: all_leaders['Batting Average']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{x.hit / x.ab:.3f}'} ) for x in top_hr: all_leaders['Home Runs']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hr)} ) for x in top_obp: all_leaders['On Base Percentage']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.hit + x.bb + x.hbp + x.ibb) / x.pa:.3f}'} ) for x in top_slg: all_leaders['Slugging Percentage']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.hr * 4) + (x.triple * 3) + (x.double * 2) + (x.hit - x.hr - x.triple - x.double)) / x.ab:.3f}'} ) for x in top_ops: all_leaders['On Base Plus Slugging']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(x.ab * (x.hit + x.bb + x.ibb + x.hbp) + ((x.hr * 4) + (x.triple * 3) + (x.double * 2) + (x.hit - x.double - x.triple - x.hr)) * (x.ab + x.bb + x.ibb + x.sac + x.hbp)) / (x.ab * (x.ab + x.bb + x.ibb + x.sac + x.hbp)):.3f}'} ) for x in top_wob: all_leaders['Weighted On Base Avg']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{(((x.bb * .69) + (x.hbp * .72) + (x.hr * 2.1) + (x.triple * 1.62) + (x.double * 1.27) + ((x.hit - x.double - x.triple - x.hr) * .89)) / (x.ab + x.bb - x.ibb + x.sac + x.hbp)):.3f}'} ) for x in top_bab: all_leaders['Avg on Balls in Play']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{((x.hit - x.hr) / (x.ab - x.so - x.hr + x.sac)):.3f}'} ) for x in top_rbi: all_leaders['Runs Batted In']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.rbi)} ) for x in top_dbl: all_leaders['Doubles']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.double)} ) for x in top_trp: all_leaders['Triples']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.triple)} ) for x in top_hit: all_leaders['Hits']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hit)} ) for x in top_pa: all_leaders['Plate Appearances']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.pa)} ) for x in top_gdp: all_leaders['Ground Into Double Play']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.gidp)} ) for x in top_bb: all_leaders['Walks']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bb)} ) for x in top_so: all_leaders['Strikeouts']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.so)} ) for x in top_hbp: all_leaders['Hit By Pitch']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.hbp)} ) for x in top_ibb: all_leaders['Intentional Walks']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.ibb)} ) for x in top_sb: all_leaders['Stolen Bases']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.sb)} ) for x in top_cs: all_leaders['Caught Stealing']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.cs)} ) for x in top_run: all_leaders['Runs Scored']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.run)} ) for x in top_ab: all_leaders['At Bats']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.ab)} ) for x in top_bphr: all_leaders['Ballpark Home Runs']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bphr)} ) for x in top_bpfo: all_leaders['Ballpark Flyouts']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bpfo)} ) for x in top_bp1b: all_leaders['Ballpark Singles']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bp1b)} ) for x in top_bplo: all_leaders['Ballpark Lineouts']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.bplo)} ) # for x in top_xba: # all_leaders['Extra Base Attempts']['leaders'].append( # {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.xba)} # ) # for x in top_xbt: # all_leaders['Extra Bases Taken']['leaders'].append( # {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': round(x.xbt)} # ) for x in top_ndhr: all_leaders['No-Doubt Home Runs']['leaders'].append( {'player': x.player.name, 'season': x.player.season, 'team': x.player.team.abbrev, 'stat': f'{x.hr - x.bphr:.0f}'} ) db.close() return all_leaders @app.get('/api/v1/career-leaders') async def v1_career_leaders_get(group: str = 'batting'): min_ip = 300 min_pa = 1000 min_ch_high = 200 min_ch_mid = 80 min_ch_low = 40 all_leaders = None if group == 'pitching': all_leaders = { # 'Starter Wins': {'abbrev': 'W', 'leaders': []}, 'Wins': {'abbrev': 'W', 'leaders': []}, 'Earned Run Average': {'abbrev': 'ERA', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Innings Pitched': {'abbrev': 'IP', 'leaders': []}, 'Strikeouts per Nine': {'abbrev': 'K/9', 'leaders': []}, 'Walks + Hits / IP': {'abbrev': 'WHIP', 'leaders': []}, 'Saves': {'abbrev': 'SV', 'leaders': []}, 'Walks Allowed': {'abbrev': 'BB', 'leaders': []}, 'Runs Allowed': {'abbrev': 'R', 'leaders': []}, 'Earned Runs Allowed': {'abbrev': 'ER', 'leaders': []}, 'Blown Saves': {'abbrev': 'BSV', 'leaders': []}, 'Hit By Pitches Allowed': {'abbrev': 'HBP', 'leaders': []}, 'Hits Allowed': {'abbrev': 'H', 'leaders': []}, 'Home Runs Allowed': {'abbrev': 'HR', 'leaders': []}, 'Wild Pitches': {'abbrev': 'WP', 'leaders': []}, 'Holds': {'abbrev': 'HD', 'leaders': []}, 'Walks Per Nine': {'abbrev': 'BB/9', 'leaders': []}, 'Strikeouts Per Walk': {'abbrev': 'K/BB', 'leaders': []}, 'Losses': {'abbrev': 'L', 'leaders': []}, } # top_swin = (PitchingStat # .select(PitchingStat.player, fn.COUNT(PitchingStat.win).alias('swin')) # .where(PitchingStat.gs == 1, PitchingStat.win == 1) # .order_by(-fn.COUNT(PitchingStat.win), PitchingStat.player) # .group_by(PitchingStat.player) # .limit(10)) top_win = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.win) .order_by(-PitchingCareer.win, PitchingCareer.name) .limit(10)) top_ip = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.ip) .order_by(-PitchingCareer.ip, PitchingCareer.name) .limit(10)) top_so = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.so) .order_by(-PitchingCareer.so, PitchingCareer.name) .limit(10)) top_era = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.erun, PitchingCareer.ip) .where(PitchingCareer.ip >= min_ip) .order_by(((PitchingCareer.erun * 9) / PitchingCareer.ip), PitchingCareer.name) .limit(10)) top_kpn = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.so, PitchingCareer.ip) .where(PitchingCareer.ip >= min_ip) .order_by(-((PitchingCareer.so * 9) / PitchingCareer.ip), PitchingCareer.name) .limit(10)) top_whip = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.bb, PitchingCareer.hit, PitchingCareer.ip) .where(PitchingCareer.ip >= min_ip) .order_by(+((PitchingCareer.bb + PitchingCareer.hit) / PitchingCareer.ip), PitchingCareer.name) .limit(10)) top_sv = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.sv) .order_by(-PitchingCareer.sv, PitchingCareer.name) .limit(10)) top_bb = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.bb) .order_by(-PitchingCareer.bb, PitchingCareer.name) .limit(10)) top_run = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.run) .order_by(-PitchingCareer.run, PitchingCareer.name) .limit(10)) top_erun = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.erun) .order_by(-PitchingCareer.erun, PitchingCareer.name) .limit(10)) top_bsv = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.bsv) .order_by(-PitchingCareer.bsv, PitchingCareer.name) .limit(10)) top_hbp = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.hbp) .order_by(-PitchingCareer.hbp, PitchingCareer.name) .limit(10)) top_hit = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.hit) .order_by(-PitchingCareer.hit, PitchingCareer.name) .limit(10)) top_hr = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.hr) .order_by(-PitchingCareer.hr, PitchingCareer.name) .limit(10)) top_wp = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.wp) .order_by(-PitchingCareer.wp, PitchingCareer.name) .limit(10)) top_hd = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.hold) .order_by(-PitchingCareer.hold, PitchingCareer.name) .limit(10)) top_bpn = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.bb, PitchingCareer.ip) .where(PitchingCareer.ip >= min_ip) .order_by(((PitchingCareer.bb * 9) / PitchingCareer.ip), PitchingCareer.name) .limit(10)) top_kpw = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.bb, PitchingCareer.so) .where(PitchingCareer.ip >= min_ip) .order_by(-(PitchingCareer.so / PitchingCareer.bb), PitchingCareer.name) .limit(10)) top_los = (PitchingCareer .select(PitchingCareer.name, PitchingCareer.loss) .order_by(-PitchingCareer.loss, PitchingCareer.name) .limit(10)) db.close() # for x in top_swin: # all_leaders['Starter Wins']['leaders'].append( # {'player': x.player.name, 'team': x.player.team.abbrev, 'stat': round(x.swin)} # ) for x in top_win: all_leaders['Wins']['leaders'].append( {'player': x.name, 'stat': round(x.win)} ) for x in top_ip: all_leaders['Innings Pitched']['leaders'].append( {'player': x.name, 'stat': f'{x.ip:.1f}'} ) for x in top_so: all_leaders['Strikeouts']['leaders'].append( {'player': x.name, 'stat': round(x.so)} ) for x in top_era: all_leaders['Earned Run Average']['leaders'].append( {'player': x.name, 'stat': f'{((x.erun * 9) / x.ip):.2f}'} ) for x in top_kpn: all_leaders['Strikeouts per Nine']['leaders'].append( {'player': x.name, 'stat': f'{((x.so * 9) / x.ip):.2f}'} ) for x in top_whip: all_leaders['Walks + Hits / IP']['leaders'].append( {'player': x.name, 'stat': f'{((x.bb + x.hit) / x.ip):.2f}'} ) for x in top_sv: all_leaders['Saves']['leaders'].append( {'player': x.name, 'stat': round(x.sv)} ) for x in top_bb: all_leaders['Walks Allowed']['leaders'].append( {'player': x.name, 'stat': round(x.bb)} ) for x in top_run: all_leaders['Runs Allowed']['leaders'].append( {'player': x.name, 'stat': round(x.run)} ) for x in top_erun: all_leaders['Earned Runs Allowed']['leaders'].append( {'player': x.name, 'stat': round(x.erun)} ) for x in top_bsv: all_leaders['Blown Saves']['leaders'].append( {'player': x.name, 'stat': round(x.bsv)} ) for x in top_hbp: all_leaders['Hit By Pitches Allowed']['leaders'].append( {'player': x.name, 'stat': round(x.hbp)} ) for x in top_hit: all_leaders['Hits Allowed']['leaders'].append( {'player': x.name, 'stat': round(x.hit)} ) for x in top_hr: all_leaders['Home Runs Allowed']['leaders'].append( {'player': x.name, 'stat': round(x.hr)} ) for x in top_wp: all_leaders['Wild Pitches']['leaders'].append( {'player': x.name, 'stat': round(x.wp)} ) for x in top_hd: all_leaders['Holds']['leaders'].append( {'player': x.name, 'stat': round(x.hold)} ) for x in top_bpn: all_leaders['Walks Per Nine']['leaders'].append( {'player': x.name, 'stat': f'{((x.bb * 9) / x.ip):.2f}'} ) for x in top_kpw: all_leaders['Strikeouts Per Walk']['leaders'].append( {'player': x.name, 'stat': f'{(x.so / x.bb):.2f}'} ) for x in top_los: all_leaders['Losses']['leaders'].append( {'player': x.name, 'stat': round(x.loss)} ) elif group == 'fielding': all_leaders = { 'Fielding Chances': {'abbrev': 'X-Ch', 'leaders': []}, 'Weighted Fielding % (RF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (CF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (LF)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (SS)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (3B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (2B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (1B)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (C)': {'abbrev': 'wF%', 'leaders': []}, 'Weighted Fielding % (P)': {'abbrev': 'wF%', 'leaders': []}, 'Errors': {'abbrev': 'E', 'leaders': []}, 'Hits Allowed': {'abbrev': 'X-Hit', 'leaders': []}, 'Passed Balls': {'abbrev': 'PB', 'leaders': []}, 'Steal Attempts Against': {'abbrev': 'SBa', 'leaders': []}, 'Runners Thrown Out': {'abbrev': 'CSc', 'leaders': []}, 'Caught Stealing % (Catchers)': {'abbrev': 'CS%', 'leaders': []}, } top_xch = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.sbc) .order_by(-(FieldingCareer.xch + FieldingCareer.sbc), FieldingCareer.name) .limit(10)) raw_ss = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == 'SS') & (FieldingCareer.xch >= min_ch_high))) raw_cf = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == 'CF') & (FieldingCareer.xch >= min_ch_mid))) raw_2b = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == '2B') & (FieldingCareer.xch >= min_ch_high))) raw_3b = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == '3B') & (FieldingCareer.xch >= min_ch_mid))) raw_1b = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == '1B') & (FieldingCareer.xch >= min_ch_mid))) raw_lf = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == 'LF') & (FieldingCareer.xch >= min_ch_low))) raw_rf = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == 'RF') & (FieldingCareer.xch >= min_ch_low))) raw_ca = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == 'C') & (FieldingCareer.xch >= min_ch_mid))) raw_pi = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xch, FieldingCareer.xhit, FieldingCareer.error) .where( (FieldingCareer.pos == 'P') & (FieldingCareer.xch >= (min_ch_low / 3)))) top_err = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.error) .order_by(-FieldingCareer.error, FieldingCareer.name) .limit(10)) top_hit = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.xhit) .order_by(-FieldingCareer.xhit, FieldingCareer.name) .limit(10)) top_sbc = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.sbc) .order_by(-FieldingCareer.sbc, FieldingCareer.name) .limit(10)) top_csc = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.csc) .order_by(-FieldingCareer.csc, FieldingCareer.name) .limit(10)) top_csp = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.sbc, FieldingCareer.csc) .where(FieldingCareer.sbc >= min_ch_mid) .order_by(-((FieldingCareer.csc * 100) / FieldingCareer.sbc), FieldingCareer.name) .limit(10)) top_pb = (FieldingCareer .select(FieldingCareer.name, FieldingCareer.pb) .where(FieldingCareer.pb > 0) .order_by(-FieldingCareer.pb, FieldingCareer.name) .limit(10)) db.close() for x in top_xch: all_leaders['Fielding Chances']['leaders'].append( {'player': x.name, 'stat': x.xch + x.sbc} ) for x in top_err: all_leaders['Errors']['leaders'].append( {'player': x.name, 'stat': x.error} ) for x in top_sbc: all_leaders['Steal Attempts Against']['leaders'].append( {'player': x.name, 'stat': x.sbc} ) for x in top_csc: all_leaders['Runners Thrown Out']['leaders'].append( {'player': x.name, 'stat': x.csc} ) for x in top_csp: all_leaders['Caught Stealing % (Catchers)']['leaders'].append( {'player': x.name, 'stat': f'{x.csc * 100 / x.sbc:.1f}'} ) for x in top_hit: all_leaders['Hits Allowed']['leaders'].append( {'player': x.name, 'stat': x.xhit} ) for x in top_pb: all_leaders['Passed Balls']['leaders'].append( {'player': x.name, 'stat': x.pb} ) for x in raw_ss: all_leaders['Weighted Fielding % (SS)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_cf: all_leaders['Weighted Fielding % (CF)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_2b: all_leaders['Weighted Fielding % (2B)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_3b: all_leaders['Weighted Fielding % (3B)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_1b: all_leaders['Weighted Fielding % (1B)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_lf: all_leaders['Weighted Fielding % (LF)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_rf: all_leaders['Weighted Fielding % (RF)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_ca: all_leaders['Weighted Fielding % (C)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for x in raw_pi: all_leaders['Weighted Fielding % (P)']['leaders'].append( {'player': x.name, 'stat': f'{(x.xch - (x.error * .5) - (x.xhit * .75)) / x.xch:.3f}'} ) for stat in all_leaders: if 'Weighted Fielding' in stat: all_leaders[stat]['leaders'] = sorted( all_leaders[stat]['leaders'], key=lambda leader: leader['stat'], reverse=True ) all_leaders[stat]['leaders'] = all_leaders[stat]['leaders'][:10] else: # return batting leaders all_leaders = { 'Home Runs': {'abbrev': 'HR', 'leaders': []}, 'Batting Average': {'abbrev': 'AVG', 'leaders': []}, 'On Base Percentage': {'abbrev': 'OBP', 'leaders': []}, 'Slugging Percentage': {'abbrev': 'SLG', 'leaders': []}, 'Runs Batted In': {'abbrev': 'RBI', 'leaders': []}, 'Doubles': {'abbrev': '2B', 'leaders': []}, 'Triples': {'abbrev': '3B', 'leaders': []}, 'Hits': {'abbrev': 'H', 'leaders': []}, 'Plate Appearances': {'abbrev': 'PA', 'leaders': []}, 'Ground Into Double Play': {'abbrev': 'GIDP', 'leaders': []}, 'Walks': {'abbrev': 'BB', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Hit By Pitch': {'abbrev': 'HBP', 'leaders': []}, 'Intentional Walks': {'abbrev': 'IBB', 'leaders': []}, 'Stolen Bases': {'abbrev': 'SB', 'leaders': []}, 'Caught Stealing': {'abbrev': 'CS', 'leaders': []}, 'Runs Scored': {'abbrev': 'R', 'leaders': []}, 'At Bats': {'abbrev': 'AB', 'leaders': []}, } top_avg = (BattingCareer .select() .where(BattingCareer.pa >= min_pa) .order_by(-(BattingCareer.hit / BattingCareer.ab), BattingCareer.name) .limit(10)) top_hr = (BattingCareer .select(BattingCareer.name, BattingCareer.hr) .order_by(-BattingCareer.hr, BattingCareer.name) .limit(10)) top_obp = (BattingCareer .select() .where(BattingCareer.pa >= min_pa) .order_by( -((BattingCareer.hit + BattingCareer.bb + BattingCareer.hbp + BattingCareer.ibb) / BattingCareer.pa), BattingCareer.name) .limit(10)) top_slg = (BattingCareer .select() .where(BattingCareer.pa >= min_pa) .order_by(-(((BattingCareer.hr * 4) + (BattingCareer.triple * 3) + (BattingCareer.double * 2) + ( BattingCareer.hit - BattingCareer.hr - BattingCareer.triple - BattingCareer.double)) / BattingCareer.ab)) .limit(10)) top_rbi = (BattingCareer .select(BattingCareer.name, BattingCareer.rbi) .order_by(-BattingCareer.rbi, BattingCareer.name) .limit(10)) top_dbl = (BattingCareer .select(BattingCareer.name, BattingCareer.double) .order_by(-BattingCareer.double, BattingCareer.name) .limit(10)) top_trp = (BattingCareer .select(BattingCareer.name, BattingCareer.triple) .order_by(-BattingCareer.triple, BattingCareer.name) .limit(10)) top_hit = (BattingCareer .select(BattingCareer.name, BattingCareer.hit) .order_by(-BattingCareer.hit, BattingCareer.name) .limit(10)) top_pa = (BattingCareer .select(BattingCareer.name, BattingCareer.pa) .order_by(-BattingCareer.pa, BattingCareer.name) .limit(10)) top_gdp = (BattingCareer .select(BattingCareer.name, BattingCareer.gidp) .order_by(-BattingCareer.gidp, BattingCareer.name) .limit(10)) top_bb = (BattingCareer .select(BattingCareer.name, BattingCareer.bb) .order_by(-BattingCareer.bb, BattingCareer.name) .limit(10)) top_so = (BattingCareer .select(BattingCareer.name, BattingCareer.so) .order_by(-BattingCareer.so, BattingCareer.name) .limit(10)) top_hbp = (BattingCareer .select(BattingCareer.name, BattingCareer.hbp) .order_by(-BattingCareer.hbp, BattingCareer.name) .limit(10)) top_ibb = (BattingCareer .select(BattingCareer.name, BattingCareer.ibb) .order_by(-BattingCareer.ibb, BattingCareer.name) .limit(10)) top_sb = (BattingCareer .select(BattingCareer.name, BattingCareer.sb) .order_by(-BattingCareer.sb, BattingCareer.name) .limit(10)) top_cs = (BattingCareer .select(BattingCareer.name, BattingCareer.cs) .order_by(-BattingCareer.cs, BattingCareer.name) .limit(10)) top_run = (BattingCareer .select(BattingCareer.name, BattingCareer.run) .order_by(-BattingCareer.run, BattingCareer.name) .limit(10)) top_ab = (BattingCareer .select(BattingCareer.name, BattingCareer.ab) .order_by(-BattingCareer.ab, BattingCareer.name) .limit(10)) db.close() for x in top_avg: all_leaders['Batting Average']['leaders'].append( {'player': x.name, 'stat': f'{x.hit / x.ab:.3f}'} ) for x in top_hr: all_leaders['Home Runs']['leaders'].append( {'player': x.name, 'stat': round(x.hr)} ) for x in top_obp: all_leaders['On Base Percentage']['leaders'].append( {'player': x.name, 'stat': f'{(x.hit + x.bb + x.hbp + x.ibb) / x.pa:.3f}'} ) for x in top_slg: all_leaders['Slugging Percentage']['leaders'].append( {'player': x.name, 'stat': f'{((x.hr * 4) + (x.triple * 3) + (x.double * 2) + (x.hit - x.hr - x.triple - x.double)) / x.ab:.3f}'} ) for x in top_rbi: all_leaders['Runs Batted In']['leaders'].append( {'player': x.name, 'stat': round(x.rbi)} ) for x in top_dbl: all_leaders['Doubles']['leaders'].append( {'player': x.name, 'stat': round(x.double)} ) for x in top_trp: all_leaders['Triples']['leaders'].append( {'player': x.name, 'stat': round(x.triple)} ) for x in top_hit: all_leaders['Hits']['leaders'].append( {'player': x.name, 'stat': round(x.hit)} ) for x in top_pa: all_leaders['Plate Appearances']['leaders'].append( {'player': x.name, 'stat': round(x.pa)} ) for x in top_gdp: all_leaders['Ground Into Double Play']['leaders'].append( {'player': x.name, 'stat': round(x.gidp)} ) for x in top_bb: all_leaders['Walks']['leaders'].append( {'player': x.name, 'stat': round(x.bb)} ) for x in top_so: all_leaders['Strikeouts']['leaders'].append( {'player': x.name, 'stat': round(x.so)} ) for x in top_hbp: all_leaders['Hit By Pitch']['leaders'].append( {'player': x.name, 'stat': round(x.hbp)} ) for x in top_ibb: all_leaders['Intentional Walks']['leaders'].append( {'player': x.name, 'stat': round(x.ibb)} ) for x in top_sb: all_leaders['Stolen Bases']['leaders'].append( {'player': x.name, 'stat': round(x.sb)} ) for x in top_cs: all_leaders['Caught Stealing']['leaders'].append( {'player': x.name, 'stat': round(x.cs)} ) for x in top_run: all_leaders['Runs Scored']['leaders'].append( {'player': x.name, 'stat': round(x.run)} ) for x in top_ab: all_leaders['At Bats']['leaders'].append( {'player': x.name, 'stat': round(x.ab)} ) db.close() return all_leaders @app.get('/api/v1/leaders/{stat}') # Not implemented async def v1_leaders_stat( stat: str, season: int = Current.get().season, team_abbrev: Optional[str] = None, league_abbrev: Optional[str] = None, division_abbrev: Optional[str] = None): db.close() raise HTTPException(501, detail='Function not implemented, yet') @app.get('/api/v1/single-game-leaders') async def v1_single_game_leaders_get( group: str = 'batting', season: Optional[int] = None, team_abbrev: Optional[str] = None): all_leaders = None if group == 'pitching': all_leaders = { 'Perfect Games': {'abbrev': 'PG', 'leaders': []}, 'Complete Games': {'abbrev': 'PG', 'leaders': []}, # 'Innings Pitched': {'abbrev': 'IP', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Scoreless Innings': {'abbrev': 'SI', 'leaders': []}, 'Zero Baserunners': {'abbrev': 'ZB', 'leaders': []}, 'Earned Runs Allowed': {'abbrev': 'ER', 'leaders': []}, 'Hit By Pitches Allowed': {'abbrev': 'HBP', 'leaders': []}, 'Hits Allowed': {'abbrev': 'H', 'leaders': []}, 'Home Runs Allowed': {'abbrev': 'HR', 'leaders': []}, 'Wild Pitches': {'abbrev': 'WP', 'leaders': []}, } all_stats = PitchingStat.select().join(Team).where( (PitchingStat.team.abbrev != 'SRS') & (PitchingStat.ip <= 10) ) if season: all_stats = all_stats.where(PitchingStat.season == season) if team_abbrev and season: this_team = Team.get_season(team_abbrev, season) if not this_team: raise HTTPException(404, f'Team {team_abbrev} not found in season {season}') all_stats = all_stats.where(PitchingStat.team == this_team) # top_ip = (all_stats # .order_by(-PitchingStat.ip, PitchingStat.season, PitchingStat.player) # .limit(10)) top_so = (all_stats .order_by(-PitchingStat.so, PitchingStat.season, PitchingStat.player) .limit(10)) top_si = (all_stats.where(PitchingStat.run == 0) .order_by(-PitchingStat.ip, PitchingStat.season, PitchingStat.player) .limit(10)) top_zb = (all_stats .where((PitchingStat.hit == 0) & (PitchingStat.bb == 0) & (PitchingStat.hbp == 0)) .order_by(-PitchingStat.ip, PitchingStat.season, PitchingStat.player) .limit(10)) top_erun = (all_stats .order_by(-PitchingStat.erun, PitchingStat.season, PitchingStat.player) .limit(10)) top_hbp = (all_stats .order_by(-PitchingStat.hbp, PitchingStat.season, PitchingStat.player) .limit(10)) top_hit = (all_stats .order_by(-PitchingStat.hit, PitchingStat.season, PitchingStat.player) .limit(10)) top_hr = (all_stats .order_by(-PitchingStat.hr, PitchingStat.season, PitchingStat.player) .limit(10)) top_wp = (all_stats .order_by(-PitchingStat.wp, PitchingStat.season, PitchingStat.player) .limit(10)) db.close() return all_leaders # for x in top_ip: # this_result = Result.select().where( # (Result.season == x.season) & (Result.week == x.week) & # ((Result.awayteam == x.team) | (Result.hometeam == x.team)) # ).limit(1) # # opponent = None # home_team = None # away_team = None # if this_result.count() > 0: # # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # # f'This Team: {x.player.team}') # home_team = this_result[0].hometeam # away_team = this_result[0].awayteam # if this_result[0].hometeam == x.player.team: # opponent = this_result[0].awayteam # else: # opponent = this_result[0].hometeam # # logging.info(f'Opponent: {opponent}') # # all_leaders['Innings Pitched']['leaders'].append( # { # 'player': x.player.name, # 'team': x.team.abbrev, # 'stat': f'{x.ip:.1f}', # 'season': x.player.season, # 'week': x.week, # 'game_num': x.game, # 'opponent': opponent.abbrev if opponent else '???', # 'home_team': home_team.abbrev if home_team else '???', # 'away_team': away_team.abbrev if away_team else '???' # } # ) for x in top_so: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Strikeouts']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': round(x.so), 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_si: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Scoreless Innings']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': f'{x.ip:.1f}', 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_zb: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Zero Baserunners']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': f'{x.ip:.1f}', 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_erun: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Earned Runs Allowed']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': round(x.erun), 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_hbp: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Hit By Pitches Allowed']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': round(x.hbp), 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_hit: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Hits Allowed']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': round(x.hit), 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_hr: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Home Runs Allowed']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': round(x.hr), 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_wp: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Wild Pitches']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': round(x.wp), 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) elif group == 'fielding': all_leaders = { 'Fielding Chances': {'abbrev': 'xch', 'leaders': []}, 'Errors': {'abbrev': 'E', 'leaders': []}, 'Hits Allowed': {'abbrev': 'H', 'leaders': []}, 'Passed Balls': {'abbrev': 'PB', 'leaders': []}, 'Steal Attempts Against': {'abbrev': 'SBa', 'leaders': []}, 'Runners Thrown Out (C)': {'abbrev': 'CSc', 'leaders': []}, # 'Rob Attempts': {'abbrev': 'ROBa', 'leaders': []}, # 'Rob Successes': {'abbrev': 'ROBs', 'leaders': []}, } all_stats = BattingStat.select().join(Team).where(BattingStat.team.abbrev != 'SRS') if season: all_stats = all_stats.where(BattingStat.season == season) if team_abbrev and season: this_team = Team.get_season(team_abbrev, season) if not this_team: raise HTTPException(404, f'Team {team_abbrev} not found in season {season}') all_stats = all_stats.where(BattingStat.team == this_team) top_xch = (all_stats .where(BattingStat.xch > 1) .order_by(-BattingStat.xch, BattingStat.season, BattingStat.week) .limit(10)) top_err = (all_stats .where(BattingStat.error > 1) .order_by(-BattingStat.error, BattingStat.season, BattingStat.week) .limit(10)) top_hit = (all_stats .where(BattingStat.hit > 1) .order_by(-BattingStat.xhit, BattingStat.season, BattingStat.week) .limit(10)) top_sbc = (all_stats .where(BattingStat.sbc > 1) .order_by(-BattingStat.sbc, BattingStat.season, BattingStat.week) .limit(10)) top_csc = (all_stats .where(BattingStat.csc > 1) .order_by(-BattingStat.csc, BattingStat.season, BattingStat.week) .limit(10)) top_pb = (all_stats .where(BattingStat.pb > 1) .order_by(-BattingStat.pb, BattingStat.season, BattingStat.week) .limit(10)) # top_roba = (all_stats # .where(BattingStat.roba > 1) # .order_by(-BattingStat.roba, BattingStat.season, BattingStat.week) # .limit(10)) # top_robs = (all_stats # .where(BattingStat.robs > 1) # .order_by(-BattingStat.robs, BattingStat.season, BattingStat.week) # .limit(10)) db.close() for x in top_xch: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Fielding Chances']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': x.xch, 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_err: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Errors']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': x.error, 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_sbc: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Steal Attempts Against']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': x.sbc, 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_csc: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Runners Thrown Out (C)']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': x.csc, 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_hit: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Hits Allowed']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': x.xhit, 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) for x in top_pb: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Passed Balls']['leaders'].append( { 'player': x.player.name, 'team': x.team.abbrev, 'stat': x.pb, 'season': x.player.season, 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???' } ) # for x in top_roba: # this_result = Result.select().where( # (Result.season == x.season) & (Result.week == x.week) & # ((Result.awayteam == x.team) | (Result.hometeam == x.team)) # ).limit(1) # # opponent = None # home_team = None # away_team = None # if this_result.count() > 0: # # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # # f'This Team: {x.player.team}') # home_team = this_result[0].hometeam # away_team = this_result[0].awayteam # if this_result[0].hometeam == x.player.team: # opponent = this_result[0].awayteam # else: # opponent = this_result[0].hometeam # # logging.info(f'Opponent: {opponent}') # # all_leaders['Rob Attempts']['leaders'].append( # { # 'player': x.player.name, # 'team': x.team.abbrev, # 'stat': x.roba, # 'season': x.player.season, # 'week': x.week, # 'game_num': x.game, # 'opponent': opponent.abbrev if opponent else '???', # 'home_team': home_team.abbrev if home_team else '???', # 'away_team': away_team.abbrev if away_team else '???' # } # ) # for x in top_robs: # this_result = Result.select().where( # (Result.season == x.season) & (Result.week == x.week) & # ((Result.awayteam == x.team) | (Result.hometeam == x.team)) # ).limit(1) # # opponent = None # home_team = None # away_team = None # if this_result.count() > 0: # # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # # f'This Team: {x.player.team}') # home_team = this_result[0].hometeam # away_team = this_result[0].awayteam # if this_result[0].hometeam == x.player.team: # opponent = this_result[0].awayteam # else: # opponent = this_result[0].hometeam # # logging.info(f'Opponent: {opponent}') # # all_leaders['Rob Successes']['leaders'].append( # { # 'player': x.player.name, # 'team': x.team.abbrev, # 'stat': x.robs, # 'season': x.player.season, # 'week': x.week, # 'game_num': x.game, # 'opponent': opponent.abbrev if opponent else '???', # 'home_team': home_team.abbrev if home_team else '???', # 'away_team': away_team.abbrev if away_team else '???' # } # ) else: all_leaders = { 'Home Runs': {'abbrev': 'HR', 'leaders': []}, 'Hits': {'abbrev': 'H', 'leaders': []}, 'RBI': {'abbrev': 'RBI', 'leaders': []}, 'Hit for Cycle': {'abbrev': 'H', 'leaders': []}, 'Stolen Bases': {'abbrev': 'SB', 'leaders': []}, 'Doubles': {'abbrev': '2B', 'leaders': []}, 'Triples': {'abbrev': '3B', 'leaders': []}, 'Walks': {'abbrev': 'BB', 'leaders': []}, # 'Extra Bases Taken': {'abbrev': 'XBT', 'leaders': []}, 'Strikeouts': {'abbrev': 'K', 'leaders': []}, 'Hit by Pitch': {'abbrev': 'HBP', 'leaders': []}, } all_stats = BattingStat.select().join(Team).where(BattingStat.team.abbrev != 'SRS') if season: all_stats = all_stats.where(BattingStat.season == season) if team_abbrev and season: this_team = Team.get_season(team_abbrev, season) if not this_team: raise HTTPException(404, f'Team {team_abbrev} not found in season {season}') all_stats = all_stats.where(BattingStat.team == this_team) top_hr = (all_stats.where(BattingStat.hr > 1).order_by(-BattingStat.hr, BattingStat.season).limit(10)) logging.info(f'top_hr: {top_hr}') top_hit = (all_stats.where(BattingStat.hit > 2).order_by( -BattingStat.hit, BattingStat.season, BattingStat.week ).limit(10)) top_rbi = (all_stats.where(BattingStat.rbi > 3).order_by( -BattingStat.rbi, BattingStat.season, BattingStat.week ).limit(10)) top_sb = (all_stats.where(BattingStat.sb > 1).order_by( -BattingStat.sb, BattingStat.season, BattingStat.week ).limit(10)) top_dbl = (all_stats.where(BattingStat.double > 1).order_by( -BattingStat.double, BattingStat.season, BattingStat.week ).limit(10)) top_tri = (all_stats.where(BattingStat.triple > 1).order_by( -BattingStat.triple, BattingStat.season, BattingStat.week ).limit(10)) top_bb = (all_stats.where(BattingStat.bb > 2).order_by( -BattingStat.bb, BattingStat.season, BattingStat.week ).limit(10)) # top_xbt = (all_stats.where(BattingStat.xbt > 1).order_by( # -BattingStat.xbt, BattingStat.season, BattingStat.week # ).limit(10)) top_k = (all_stats.where(BattingStat.so > 2).order_by( -BattingStat.so, BattingStat.season, BattingStat.week ).limit(10)) top_hbp = (all_stats.where(BattingStat.hbp > 1).order_by( -BattingStat.hbp, BattingStat.season, BattingStat.week ).limit(10)) top_ccl = (all_stats.where( (BattingStat.hr > 0) & (BattingStat.triple > 0) & (BattingStat.double > 0) & ((BattingStat.hit - BattingStat.double - BattingStat.triple - BattingStat.hr) > 0) ).order_by(-BattingStat.hit, BattingStat.season, BattingStat.week).limit(10)) for x in top_hr: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Home Runs']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.hr}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_hit: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Hits']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.hit}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_rbi: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['RBI']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.rbi}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_sb: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Stolen Bases']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.sb}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_dbl: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Doubles']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.double}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_tri: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Triples']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.triple}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_bb: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Walks']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.bb}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) # for x in top_xbt: # this_result = Result.select().where( # (Result.season == x.season) & (Result.week == x.week) & # ((Result.awayteam == x.team) | (Result.hometeam == x.team)) # ).limit(1) # # opponent = None # home_team = None # away_team = None # if this_result.count() > 0: # # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # # f'This Team: {x.player.team}') # home_team = this_result[0].hometeam # away_team = this_result[0].awayteam # if this_result[0].hometeam == x.player.team: # opponent = this_result[0].awayteam # else: # opponent = this_result[0].hometeam # # logging.info(f'Opponent: {opponent}') # # all_leaders['Extra Bases Taken']['leaders'].append( # { # 'player': x.player.name, # 'season': x.player.season, # 'team': x.team.abbrev, # 'stat': f'{x.xbt}', # 'week': x.week, # 'game_num': x.game, # 'opponent': opponent.abbrev if opponent else '???', # 'home_team': home_team.abbrev if home_team else '???', # 'away_team': away_team.abbrev if away_team else '???', # } # ) for x in top_k: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Strikeouts']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.so}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_hbp: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Hit by Pitch']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.hbp}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) for x in top_ccl: this_result = Result.select().where( (Result.season == x.season) & (Result.week == x.week) & ((Result.awayteam == x.team) | (Result.hometeam == x.team)) ).limit(1) opponent = None home_team = None away_team = None if this_result.count() > 0: # logging.info(f'Query: {this_result} / Result: {this_result[0]}') # logging.info(f'Home Team: {this_result[0].hometeam} / Away Team: {this_result[0].awayteam} / ' # f'This Team: {x.player.team}') home_team = this_result[0].hometeam away_team = this_result[0].awayteam if this_result[0].hometeam == x.player.team: opponent = this_result[0].awayteam else: opponent = this_result[0].hometeam # logging.info(f'Opponent: {opponent}') all_leaders['Hit for Cycle']['leaders'].append( { 'player': x.player.name, 'season': x.player.season, 'team': x.team.abbrev, 'stat': f'{x.hit}', 'week': x.week, 'game_num': x.game, 'opponent': opponent.abbrev if opponent else '???', 'home_team': home_team.abbrev if home_team else '???', 'away_team': away_team.abbrev if away_team else '???', } ) db.close() return all_leaders @app.get('/api/v1/teamstats') async def v1_teamstats( group: str = 'batting', season: int = SEASON_DEFAULT, team_abbrev: Optional[str] = None): team_stats = {} if team_abbrev: all_teams = Team.select_season(season).where(Team.abbrev == team_abbrev) else: all_teams = Team.select_season(season).where(Team.division.is_null(False)).order_by(Team.sname) if group == 'batting': for team in all_teams: if team.abbrev[:2] != 'FA': team_stats[team.abbrev] = { 'team': model_to_dict(team), 'stats': BattingStat.team_season(team, season) } elif group == 'pitching': for team in all_teams: if team.abbrev[:2] != 'FA': team_stats[team.abbrev] = { 'team': model_to_dict(team), 'stats': PitchingStat.team_season(team, season) } else: for team in all_teams: if team.abbrev[:2] != 'FA': team_stats[team.abbrev] = { 'team': model_to_dict(team), 'stats': BattingStat.team_fielding_season(team, season) } db.close() return team_stats @app.get('/api/v1/managers') async def v1_managers_get(): all_managers = Manager.select() return_managers = {} for x in all_managers: return_managers[f'{x.id}'] = model_to_dict(x) db.close() return return_managers @app.get('/api/v1/managers/{name_or_id}') async def v1_managers_get_one(name_or_id): try: this_manager = Manager.get_by_id(name_or_id) except: this_manager = Manager.get_or_none(fn.Lower(Manager.name) == name_or_id.lower()) if not this_manager: db.close() raise HTTPException(status_code=404, detail=f'Manager {name_or_id} not found') db.close() return model_to_dict(this_manager) @app.patch('/api/v1/managers/{name_or_id}') async def v1_managers_patch( name_or_id, image: Optional[str] = None, headline: Optional[str] = None, bio: Optional[str] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch managers') try: this_manager = Manager.get_by_id(name_or_id) except: this_manager = Manager.get_or_none(fn.Lower(Manager.name) == name_or_id.lower()) if not this_manager: db.close() raise HTTPException(status_code=404, detail=f'Manager {name_or_id} not found') if image: this_manager.image = image if headline: this_manager.headline = headline if bio: this_manager.bio = bio saved = this_manager.save() db.close() if saved == 1: return model_to_dict(this_manager) else: raise HTTPException(status_code=500, detail='Manager update has failed') @app.post('/api/v1/managers') async def v1_managers_post(manager: ManagerModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post managers') this_manager = Manager(name=manager.name) this_manager.save() if manager.image: this_manager.image = manager.image if manager.headline: this_manager.headline = manager.headline if manager.bio: this_manager.bio = manager.bio this_manager.save() db.close() return model_to_dict(this_manager) @app.get('/api/v1/awards') async def v1_awards_get( name: Optional[str] = None, season: Optional[int] = None, timing: Optional[str] = None, manager_id: Optional[int] = None, player_id: Optional[int] = None, team_id: Optional[int] = None, player_name: Optional[str] = None): all_awards = Award.select() if name: all_awards = all_awards.where(Award.name == name) if season: all_awards = all_awards.where(Award.season == season) if timing: all_awards = all_awards.where(Award.timing == timing) if manager_id: try: this_manager = Manager.get_by_id(manager_id) all_awards = all_awards.where( ((Award.manager1 == this_manager) | (Award.manager2 == this_manager)) ) except: db.close() raise HTTPException(status_code=404, detail=f'Manager id {manager_id} not found') if player_id or player_name: if player_id: try: this_player = Player.get_by_id(player_id) all_awards = all_awards.where(Award.player == this_player) except: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') else: these_players = Player.select().where(fn.Lower(Player.name) == player_name.lower()) if these_players.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'Player {player_name} not found') all_awards = all_awards.where(Award.player << these_players) if team_id: try: this_team = Team.get_by_id(team_id) all_awards = all_awards.where(Award.team == this_team) except: db.close() raise HTTPException(status_code=404, detail=f'Team id {team_id} not found') return_awards = {} for x in all_awards: return_awards[f'{x.id}'] = model_to_dict(x) db.close() return return_awards @app.get('/api/v1/awards/{award_id}') async def v1_awards_get_one(award_id): try: this_award = Award.get_by_id(award_id) except: db.close() raise HTTPException(status_code=404, detail=f'Award {award_id} not found') db.close() return model_to_dict(this_award) @app.patch('/api/v1/awards/{award_id}') async def v1_awards_patch( award_id, name: Optional[str] = None, season: Optional[int] = None, timing: Optional[str] = None, image: Optional[str] = None, manager1_id: Optional[int] = None, manager2_id: Optional[int] = None, player_id: Optional[int] = None, team_id: Optional[int] = None, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to patch awards') try: this_award = Award.get_by_id(award_id) except: db.close() raise HTTPException(status_code=404, detail=f'Award {award_id} not found') if name: this_award.name = name if image: this_award.image = image if timing: this_award.timing = timing if season: this_award.season = season if manager1_id: try: this_manager = Manager.get_by_id(manager1_id) this_award.manager1 = this_manager except: db.close() raise HTTPException(status_code=404, detail=f'Manager id {manager1_id} not found') if manager2_id: try: this_manager = Manager.get_by_id(manager2_id) this_award.manager2 = this_manager except: db.close() raise HTTPException(status_code=404, detail=f'Manager id {manager2_id} not found') if player_id: try: this_player = Player.get_by_id(player_id) this_award.player = this_player except: db.close() raise HTTPException(status_code=404, detail=f'Player id {player_id} not found') if team_id: try: this_team = Team.get_by_id(team_id) this_award.team = this_team except: db.close() raise HTTPException(status_code=404, detail=f'Team id {team_id} not found') saved = this_award.save() db.close() if saved == 1: return model_to_dict(this_award) else: raise HTTPException(status_code=500, detail='Award update has failed') @app.post('/api/v1/awards') async def v1_awards_post(awards: AwardModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post awards') all_awards = [] for award in awards.awards: this_award = Award( name=award.name, season=award.season ) if award.image: this_award.image = award.image if award.timing: this_award.timing = award.timing if award.manager1_id: try: this_manager = Manager.get_by_id(award.manager1_id) this_award.manager1 = this_manager except: db.close() raise HTTPException(status_code=404, detail=f'Manager id {award.manager1_id} not found') if award.manager2_id: try: this_manager = Manager.get_by_id(award.manager2_id) this_award.manager2 = this_manager except: db.close() raise HTTPException(status_code=404, detail=f'Manager id {award.manager2_id} not found') if award.player_id: try: this_player = Player.get_by_id(award.player_id) this_award.player = this_player except: db.close() raise HTTPException(status_code=404, detail=f'Player id {award.player_id} not found') if award.team_id: try: this_team = Team.get_by_id(award.team_id) this_award.team = this_team except: db.close() raise HTTPException(status_code=404, detail=f'Team id {award.team_id} not found') all_awards.append(this_award) with db.atomic(): Award.bulk_create(all_awards, batch_size=15) db.close() raise HTTPException(status_code=200, detail=f'Created {len(all_awards)} awards') @app.delete('/api/v1/awards/{id}') async def v1_awards_delete(id): try: this_award = Award.get_by_id(id) except: db.close() raise HTTPException(status_code=404, detail=f'Award {id} not found') count = this_award.delete_instance() db.close() if count == 1: raise HTTPException(status_code=200, detail=f'Award {id} has been deleted') else: raise HTTPException(status_code=500, detail=f'Award was not deleted') @app.get('/api/v1/dice') async def v1_dice_get( season: Optional[int] = None, week_start: Optional[int] = None, week_end: Optional[int] = None, team_id: Optional[int] = None, roller: Optional[int] = None): all_dice = DiceRoll.select() if season: all_dice = all_dice.where(DiceRoll.season == season) if (week_start and not week_end) or (week_end and not week_start): if week_start: all_dice = all_dice.where(DiceRoll.week >= week_start) else: all_dice = all_dice.where(DiceRoll.week <= week_start) if week_start and week_end: if week_end >= week_start: all_dice = all_dice.where((DiceRoll.week >= week_start) & (DiceRoll.week <= week_end)) else: db.close() raise HTTPException(status_code=400, detail='Week end must be greater than or equal to week start') if team_id: try: this_team = Team.get_by_id(team_id) all_dice = all_dice.where(DiceRoll.team == this_team) except: db.close() raise HTTPException(status_code=404, detail=f'Team ID {team_id} not found') if roller: all_dice = all_dice.where(DiceRoll.roller == roller) return_dice = {} for x in all_dice: return_dice[f'{x.id}'] = model_to_dict(x) db.close() return return_dice @app.post('/api/v1/dice') async def v1_dice_post(dice: DiceModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post dice rolls') all_dice = [] for x in dice.rolls: try: this_team = Team.get_by_id(x.team_id) this_die = DiceRoll( season=x.season, week=x.week, team=this_team, roller=x.roller, dsix=x.dsix, twodsix=x.twodsix, threedsix=x.threedsix, dtwenty=x.dtwenty ) all_dice.append(this_die) except: db.close() raise HTTPException(status_code=404, detail=f'Team ID {x.team_id} not found') with db.atomic(): DiceRoll.bulk_create(all_dice, batch_size=20) db.close() raise HTTPException(status_code=200, detail=f'Posted {len(all_dice)} dice rolls') @app.delete('/api/v1/dice') async def v1_dice_delete( season: int, week_start: Optional[int] = None, week_end: Optional[int] = None, team_id: Optional[int] = None, roller: Optional[int] = None): delete_query = DiceRoll.delete().where(DiceRoll.season == season) if (week_start and not week_end) or (week_end and not week_start): if week_start: delete_query = delete_query.where(DiceRoll.week >= week_start) else: delete_query = delete_query.where(DiceRoll.week <= week_start) if week_start and week_end: if week_end >= week_start: delete_query = delete_query.where((DiceRoll.week >= week_start) & (DiceRoll.week <= week_end)) else: db.close() raise HTTPException(status_code=400, detail='Week end must be greater than or equal to week start') if team_id: try: this_team = Team.get_by_id(team_id) delete_query = delete_query.where(DiceRoll.team == this_team) except: db.close() raise HTTPException(status_code=404, detail=f'Team ID {team_id} not found') if roller: delete_query = delete_query.where(DiceRoll.roller == roller) print(f'delete_query: {delete_query}') count = delete_query.execute() db.close() if count > 0: raise HTTPException(status_code=200, detail=f'Removed {count} batting stat lines') else: raise HTTPException(status_code=418, detail=f'Well slap my ass and call me a teapot; ' f'I did not delete any records') @app.post('/api/v1/draft-list') async def v1_draft_list_post(draft_list: DraftListModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post dice rolls') all_draft_list = [] try: this_team = Team.get_by_id(draft_list.draft_list[0].team_id) except: db.close() raise HTTPException(status_code=404, detail=f'Team ID {draft_list.draft_list[0].team_id} not found') old_list = DraftList.delete().where( DraftList.team == this_team ) old_list.execute() for x in draft_list.draft_list: try: this_player = Player.get_by_id(x.player_id) except: db.close() raise HTTPException(status_code=404, detail=f'Player ID {x.player_id} not found') this_list = DraftList( season=x.season, team=this_team, rank=x.rank, player=this_player ) all_draft_list.append(this_list) with db.atomic(): DraftList.bulk_create(all_draft_list, batch_size=20) db.close() raise HTTPException(status_code=200, detail=f'Posted {len(all_draft_list)} dice rolls') @app.get('/api/v1/draft-list/{team_id}') async def v1_draft_list_get( team_id, return_type: Optional[str] = 'json', csv: Optional[bool] = False, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException(status_code=401, detail='You are not authorized to post dice rolls') this_team = Team.get_by_id(team_id) team_list = DraftList.select().where(DraftList.team == this_team) if return_type == 'csv' or csv: return_list = [['season', 'team', 'rank', 'player']] for x in team_list: return_list.append([x.season, x.team.abbrev, x.rank, x.player.name]) else: return_list = {} for x in team_list: return_list[f'{x.id}'] = model_to_dict(x) db.close() return return_list