Merge branch 'main' into issue/147-feat-add-limit-pagination-to-events-endpoint

This commit is contained in:
cal 2026-03-24 12:09:22 +00:00
commit c64f389d64
2 changed files with 64 additions and 42 deletions

View File

@ -8,10 +8,7 @@ from ..db_engine import GauntletRun, model_to_dict, DatabaseError, DoesNotExist
from ..dependencies import oauth2_scheme, valid_token from ..dependencies import oauth2_scheme, valid_token
router = APIRouter( router = APIRouter(prefix="/api/v2/gauntletruns", tags=["notifs"])
prefix='/api/v2/gauntletruns',
tags=['notifs']
)
class GauntletRunModel(pydantic.BaseModel): class GauntletRunModel(pydantic.BaseModel):
@ -24,13 +21,25 @@ class GauntletRunModel(pydantic.BaseModel):
ended: Optional[int] = None ended: Optional[int] = None
@router.get('') @router.get("")
async def get_gauntletruns( async def get_gauntletruns(
team_id: list = Query(default=None), wins: Optional[int] = None, wins_min: Optional[int] = None, team_id: list = Query(default=None),
wins_max: Optional[int] = None, losses: Optional[int] = None, losses_min: Optional[int] = None, wins: Optional[int] = None,
losses_max: Optional[int] = None, gsheet: Optional[str] = None, created_after: Optional[int] = None, wins_min: Optional[int] = None,
created_before: Optional[int] = None, ended_after: Optional[int] = None, ended_before: Optional[int] = None, wins_max: Optional[int] = None,
is_active: Optional[bool] = None, gauntlet_id: list = Query(default=None), season: list = Query(default=None)): losses: Optional[int] = None,
losses_min: Optional[int] = None,
losses_max: Optional[int] = None,
gsheet: Optional[str] = None,
created_after: Optional[int] = None,
created_before: Optional[int] = None,
ended_after: Optional[int] = None,
ended_before: Optional[int] = None,
is_active: Optional[bool] = None,
gauntlet_id: list = Query(default=None),
season: list = Query(default=None),
limit: int = 100,
):
all_gauntlets = GauntletRun.select().order_by(GauntletRun.id) all_gauntlets = GauntletRun.select().order_by(GauntletRun.id)
if team_id is not None: if team_id is not None:
@ -73,39 +82,48 @@ async def get_gauntletruns(
if season is not None: if season is not None:
all_gauntlets = all_gauntlets.where(GauntletRun.team.season << season) all_gauntlets = all_gauntlets.where(GauntletRun.team.season << season)
return_val = {'count': all_gauntlets.count(), 'runs': []} limit = max(0, min(limit, 500))
for x in all_gauntlets: return_val = {"count": all_gauntlets.count(), "runs": []}
return_val['runs'].append(model_to_dict(x)) for x in all_gauntlets.limit(limit):
return_val["runs"].append(model_to_dict(x))
return return_val return return_val
@router.get('/{gauntletrun_id}') @router.get("/{gauntletrun_id}")
async def get_one_gauntletrun(gauntletrun_id): async def get_one_gauntletrun(gauntletrun_id):
try: try:
this_gauntlet = GauntletRun.get_by_id(gauntletrun_id) this_gauntlet = GauntletRun.get_by_id(gauntletrun_id)
except DoesNotExist: except DoesNotExist:
raise HTTPException(status_code=404, detail=f'No gauntlet found with id {gauntletrun_id}') raise HTTPException(
status_code=404, detail=f"No gauntlet found with id {gauntletrun_id}"
)
return_val = model_to_dict(this_gauntlet) return_val = model_to_dict(this_gauntlet)
return return_val return return_val
@router.patch('/{gauntletrun_id}') @router.patch("/{gauntletrun_id}")
async def patch_gauntletrun( async def patch_gauntletrun(
gauntletrun_id, team_id: Optional[int] = None, wins: Optional[int] = None, losses: Optional[int] = None, gauntletrun_id,
gsheet: Optional[str] = None, created: Optional[bool] = None, ended: Optional[bool] = None, team_id: Optional[int] = None,
token: str = Depends(oauth2_scheme)): wins: Optional[int] = None,
losses: Optional[int] = None,
gsheet: Optional[str] = None,
created: Optional[bool] = None,
ended: Optional[bool] = None,
token: str = Depends(oauth2_scheme),
):
if not valid_token(token): if not valid_token(token):
logging.warning('Bad Token: [REDACTED]') logging.warning("Bad Token: [REDACTED]")
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail='You are not authorized to patch gauntlet runs. This event has been logged.' detail="You are not authorized to patch gauntlet runs. This event has been logged.",
) )
this_run = GauntletRun.get_or_none(GauntletRun.id == gauntletrun_id) this_run = GauntletRun.get_or_none(GauntletRun.id == gauntletrun_id)
if this_run is None: if this_run is None:
raise KeyError(f'Gauntlet Run ID {gauntletrun_id} not found') raise KeyError(f"Gauntlet Run ID {gauntletrun_id} not found")
if team_id is not None: if team_id is not None:
this_run.team_id = team_id this_run.team_id = team_id
@ -130,41 +148,42 @@ async def patch_gauntletrun(
r_curr = model_to_dict(this_run) r_curr = model_to_dict(this_run)
return r_curr return r_curr
else: else:
raise DatabaseError(f'Unable to patch gauntlet run {gauntletrun_id}') raise DatabaseError(f"Unable to patch gauntlet run {gauntletrun_id}")
@router.post('') @router.post("")
async def post_gauntletrun(gauntletrun: GauntletRunModel, token: str = Depends(oauth2_scheme)): async def post_gauntletrun(
gauntletrun: GauntletRunModel, token: str = Depends(oauth2_scheme)
):
if not valid_token(token): if not valid_token(token):
logging.warning('Bad Token: [REDACTED]') logging.warning("Bad Token: [REDACTED]")
raise HTTPException( raise HTTPException(
status_code=401, status_code=401,
detail='You are not authorized to post gauntlets. This event has been logged.' detail="You are not authorized to post gauntlets. This event has been logged.",
) )
run_data = gauntletrun.dict() run_data = gauntletrun.dict()
# Convert milliseconds timestamps to datetime for PostgreSQL # Convert milliseconds timestamps to datetime for PostgreSQL
if run_data.get('created'): if run_data.get("created"):
run_data['created'] = datetime.fromtimestamp(run_data['created'] / 1000) run_data["created"] = datetime.fromtimestamp(run_data["created"] / 1000)
else: else:
run_data['created'] = datetime.now() run_data["created"] = datetime.now()
if run_data.get('ended'): if run_data.get("ended"):
run_data['ended'] = datetime.fromtimestamp(run_data['ended'] / 1000) run_data["ended"] = datetime.fromtimestamp(run_data["ended"] / 1000)
else: else:
run_data['ended'] = None run_data["ended"] = None
this_run = GauntletRun(**run_data) this_run = GauntletRun(**run_data)
if this_run.save(): if this_run.save():
r_run = model_to_dict(this_run) r_run = model_to_dict(this_run)
return r_run return r_run
else: else:
raise DatabaseError(f'Unable to post gauntlet run') raise DatabaseError("Unable to post gauntlet run")
@router.delete('/{gauntletrun_id}') @router.delete("/{gauntletrun_id}")
async def delete_gauntletrun(gauntletrun_id): async def delete_gauntletrun(gauntletrun_id):
if GauntletRun.delete_by_id(gauntletrun_id) == 1: if GauntletRun.delete_by_id(gauntletrun_id) == 1:
return f'Deleted gauntlet run ID {gauntletrun_id}' return f"Deleted gauntlet run ID {gauntletrun_id}"
raise DatabaseError(f'Unable to delete gauntlet run {gauntletrun_id}')
raise DatabaseError(f"Unable to delete gauntlet run {gauntletrun_id}")

View File

@ -143,6 +143,7 @@ async def get_card_ratings(
short_output: bool = False, short_output: bool = False,
csv: bool = False, csv: bool = False,
cardset_id: list = Query(default=None), cardset_id: list = Query(default=None),
limit: int = 100,
token: str = Depends(oauth2_scheme), token: str = Depends(oauth2_scheme),
): ):
if not valid_token(token): if not valid_token(token):
@ -168,6 +169,8 @@ async def get_card_ratings(
) )
all_ratings = all_ratings.where(PitchingCardRatings.pitchingcard << set_cards) all_ratings = all_ratings.where(PitchingCardRatings.pitchingcard << set_cards)
all_ratings = all_ratings.limit(max(0, min(limit, 500)))
if csv: if csv:
return_val = query_to_csv(all_ratings) return_val = query_to_csv(all_ratings)
return Response(content=return_val, media_type="text/csv") return Response(content=return_val, media_type="text/csv")
@ -231,10 +234,10 @@ def get_scouting_dfs(cardset_id: list = None):
series_list = [ series_list = [
pd.Series( pd.Series(
dict([(x.player.player_id, x.range) for x in positions]), name=f"Range P" dict([(x.player.player_id, x.range) for x in positions]), name="Range P"
), ),
pd.Series( pd.Series(
dict([(x.player.player_id, x.error) for x in positions]), name=f"Error P" dict([(x.player.player_id, x.error) for x in positions]), name="Error P"
), ),
] ]
logging.debug(f"series_list: {series_list}") logging.debug(f"series_list: {series_list}")
@ -274,7 +277,7 @@ async def post_calc_scouting(token: str = Depends(oauth2_scheme)):
status_code=401, detail="You are not authorized to calculate card ratings." status_code=401, detail="You are not authorized to calculate card ratings."
) )
logging.warning(f"Re-calculating pitching ratings\n\n") logging.warning("Re-calculating pitching ratings\n\n")
output = get_scouting_dfs() output = get_scouting_dfs()
first = ["player_id", "player_name", "cardset_name", "rarity", "hand", "variant"] first = ["player_id", "player_name", "cardset_name", "rarity", "hand", "variant"]
@ -310,7 +313,7 @@ async def post_calc_basic(token: str = Depends(oauth2_scheme)):
status_code=401, detail="You are not authorized to calculate basic ratings." status_code=401, detail="You are not authorized to calculate basic ratings."
) )
logging.warning(f"Re-calculating basic pitching ratings\n\n") logging.warning("Re-calculating basic pitching ratings\n\n")
raw_data = get_scouting_dfs() raw_data = get_scouting_dfs()
logging.debug(f"output: {raw_data}") logging.debug(f"output: {raw_data}")