Merge branch 'main' into issue/145-feat-add-limit-pagination-to-gauntletrewards-endpo

This commit is contained in:
cal 2026-03-24 12:12:07 +00:00
commit ff132564c2
3 changed files with 179 additions and 79 deletions

View File

@ -26,7 +26,7 @@ class EventModel(pydantic.BaseModel):
@router.get('')
async def v1_events_get(
name: Optional[str] = None, in_desc: Optional[str] = None, active: Optional[bool] = None,
csv: Optional[bool] = None):
csv: Optional[bool] = None, limit: Optional[int] = 100):
all_events = Event.select().order_by(Event.id)
if name is not None:
@ -39,6 +39,8 @@ async def v1_events_get(
if active is not None:
all_events = all_events.where(Event.active == active)
all_events = all_events.limit(max(0, min(limit, 500)))
if csv:
data_list = [['id', 'name', 'short_desc', 'long_desc', 'url', 'thumbnail', 'active']]
for line in all_events:

View File

@ -5,14 +5,19 @@ import logging
import pydantic
from pandas import DataFrame
from ..db_engine import db, PitchingStat, model_to_dict, Card, Player, Current, DoesNotExist
from ..db_engine import (
db,
PitchingStat,
model_to_dict,
Card,
Player,
Current,
DoesNotExist,
)
from ..dependencies import oauth2_scheme, valid_token
router = APIRouter(
prefix='/api/v2/pitstats',
tags=['pitstats']
)
router = APIRouter(prefix="/api/v2/pitstats", tags=["pitstats"])
class PitStat(pydantic.BaseModel):
@ -40,7 +45,7 @@ class PitStat(pydantic.BaseModel):
bsv: Optional[int] = 0
week: int
season: int
created: Optional[int] = int(datetime.timestamp(datetime.now())*1000)
created: Optional[int] = int(datetime.timestamp(datetime.now()) * 1000)
game_id: int
@ -48,13 +53,23 @@ class PitchingStatModel(pydantic.BaseModel):
stats: List[PitStat]
@router.get('')
@router.get("")
async def get_pit_stats(
card_id: int = None, player_id: int = None, team_id: int = None, vs_team_id: int = None, week: int = None,
season: int = None, week_start: int = None, week_end: int = None, created: int = None, gs: bool = None,
csv: bool = None):
card_id: int = None,
player_id: int = None,
team_id: int = None,
vs_team_id: int = None,
week: int = None,
season: int = None,
week_start: int = None,
week_end: int = None,
created: int = None,
gs: bool = None,
csv: bool = None,
limit: Optional[int] = 100,
):
all_stats = PitchingStat.select().join(Card).join(Player).order_by(PitchingStat.id)
logging.debug(f'pit query:\n\n{all_stats}')
logging.debug(f"pit query:\n\n{all_stats}")
if season is not None:
all_stats = all_stats.where(PitchingStat.season == season)
@ -83,43 +98,99 @@ async def get_pit_stats(
if gs is not None:
all_stats = all_stats.where(PitchingStat.gs == 1 if gs else 0)
all_stats = all_stats.limit(max(0, min(limit, 500)))
# if all_stats.count() == 0:
# db.close()
# raise HTTPException(status_code=404, detail=f'No pitching stats found')
if csv:
data_list = [['id', 'card_id', 'player_id', 'cardset', 'team', 'vs_team', 'ip', 'hit', 'run', 'erun', 'so', 'bb', 'hbp',
'wp', 'balk', 'hr', 'ir', 'irs', 'gs', 'win', 'loss', 'hold', 'sv', 'bsv', 'week', 'season',
'created', 'game_id', 'roster_num']]
data_list = [
[
"id",
"card_id",
"player_id",
"cardset",
"team",
"vs_team",
"ip",
"hit",
"run",
"erun",
"so",
"bb",
"hbp",
"wp",
"balk",
"hr",
"ir",
"irs",
"gs",
"win",
"loss",
"hold",
"sv",
"bsv",
"week",
"season",
"created",
"game_id",
"roster_num",
]
]
for line in all_stats:
data_list.append(
[
line.id, line.card.id, line.card.player.player_id, line.card.player.cardset.name, line.team.abbrev,
line.vs_team.abbrev, 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.week, line.season, line.created,
line.game_id, line.roster_num
line.id,
line.card.id,
line.card.player.player_id,
line.card.player.cardset.name,
line.team.abbrev,
line.vs_team.abbrev,
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.week,
line.season,
line.created,
line.game_id,
line.roster_num,
]
)
return_val = DataFrame(data_list).to_csv(header=False, index=False)
return Response(content=return_val, media_type='text/csv')
return Response(content=return_val, media_type="text/csv")
else:
return_val = {'count': all_stats.count(), 'stats': []}
return_val = {"count": all_stats.count(), "stats": []}
for x in all_stats:
return_val['stats'].append(model_to_dict(x, recurse=False))
return_val["stats"].append(model_to_dict(x, recurse=False))
return return_val
@router.post('')
@router.post("")
async def post_pitstat(stats: PitchingStatModel, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning('Bad Token: [REDACTED]')
logging.warning("Bad Token: [REDACTED]")
raise HTTPException(
status_code=401,
detail='You are not authorized to post stats. This event has been logged.'
detail="You are not authorized to post stats. This event has been logged.",
)
new_stats = []
@ -149,33 +220,37 @@ async def post_pitstat(stats: PitchingStatModel, token: str = Depends(oauth2_sch
bsv=x.bsv,
week=x.week,
season=x.season,
created=datetime.fromtimestamp(x.created / 1000) if x.created else datetime.now(),
game_id=x.game_id
created=datetime.fromtimestamp(x.created / 1000)
if x.created
else datetime.now(),
game_id=x.game_id,
)
new_stats.append(this_stat)
with db.atomic():
PitchingStat.bulk_create(new_stats, batch_size=15)
raise HTTPException(status_code=200, detail=f'{len(new_stats)} pitching lines have been added')
raise HTTPException(
status_code=200, detail=f"{len(new_stats)} pitching lines have been added"
)
@router.delete('/{stat_id}')
@router.delete("/{stat_id}")
async def delete_pitstat(stat_id, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning('Bad Token: [REDACTED]')
logging.warning("Bad Token: [REDACTED]")
raise HTTPException(
status_code=401,
detail='You are not authorized to delete stats. This event has been logged.'
detail="You are not authorized to delete stats. This event has been logged.",
)
try:
this_stat = PitchingStat.get_by_id(stat_id)
except DoesNotExist:
raise HTTPException(status_code=404, detail=f'No stat found with id {stat_id}')
raise HTTPException(status_code=404, detail=f"No stat found with id {stat_id}")
count = this_stat.delete_instance()
if count == 1:
raise HTTPException(status_code=200, detail=f'Stat {stat_id} has been deleted')
raise HTTPException(status_code=200, detail=f"Stat {stat_id} has been deleted")
else:
raise HTTPException(status_code=500, detail=f'Stat {stat_id} was not deleted')
raise HTTPException(status_code=500, detail=f"Stat {stat_id} was not deleted")

View File

@ -9,10 +9,7 @@ from ..db_engine import Reward, model_to_dict, fn, DoesNotExist
from ..dependencies import oauth2_scheme, valid_token
router = APIRouter(
prefix='/api/v2/rewards',
tags=['rewards']
)
router = APIRouter(prefix="/api/v2/rewards", tags=["rewards"])
class RewardModel(pydantic.BaseModel):
@ -20,18 +17,25 @@ class RewardModel(pydantic.BaseModel):
season: int
week: int
team_id: int
created: Optional[int] = int(datetime.timestamp(datetime.now())*1000)
created: Optional[int] = int(datetime.timestamp(datetime.now()) * 1000)
@router.get('')
@router.get("")
async def get_rewards(
name: Optional[str] = None, in_name: Optional[str] = None, team_id: Optional[int] = None,
season: Optional[int] = None, week: Optional[int] = None, created_after: Optional[int] = None,
flat: Optional[bool] = False, csv: Optional[bool] = None):
name: Optional[str] = None,
in_name: Optional[str] = None,
team_id: Optional[int] = None,
season: Optional[int] = None,
week: Optional[int] = None,
created_after: Optional[int] = None,
flat: Optional[bool] = False,
csv: Optional[bool] = None,
limit: Optional[int] = 100,
):
all_rewards = Reward.select().order_by(Reward.id)
if all_rewards.count() == 0:
raise HTTPException(status_code=404, detail=f'There are no rewards to filter')
raise HTTPException(status_code=404, detail="There are no rewards to filter")
if name is not None:
all_rewards = all_rewards.where(fn.Lower(Reward.name) == name.lower())
@ -49,62 +53,71 @@ async def get_rewards(
all_rewards = all_rewards.where(Reward.week == week)
if all_rewards.count() == 0:
raise HTTPException(status_code=404, detail=f'No rewards found')
raise HTTPException(status_code=404, detail="No rewards found")
limit = max(0, min(limit, 500))
all_rewards = all_rewards.limit(limit)
if csv:
data_list = [['id', 'name', 'team', 'daily', 'created']]
data_list = [["id", "name", "team", "daily", "created"]]
for line in all_rewards:
data_list.append(
[
line.id, line.name, line.team.id, line.daily, line.created
]
[line.id, line.name, line.team.id, line.daily, line.created]
)
return_val = DataFrame(data_list).to_csv(header=False, index=False)
return Response(content=return_val, media_type='text/csv')
return Response(content=return_val, media_type="text/csv")
else:
return_val = {'count': all_rewards.count(), 'rewards': []}
return_val = {"count": all_rewards.count(), "rewards": []}
for x in all_rewards:
return_val['rewards'].append(model_to_dict(x, recurse=not flat))
return_val["rewards"].append(model_to_dict(x, recurse=not flat))
return return_val
@router.get('/{reward_id}')
@router.get("/{reward_id}")
async def get_one_reward(reward_id, csv: Optional[bool] = False):
try:
this_reward = Reward.get_by_id(reward_id)
except DoesNotExist:
raise HTTPException(status_code=404, detail=f'No reward found with id {reward_id}')
raise HTTPException(
status_code=404, detail=f"No reward found with id {reward_id}"
)
if csv:
data_list = [
['id', 'name', 'card_count', 'description'],
[this_reward.id, this_reward.name, this_reward.team.id, this_reward.daily, this_reward.created]
["id", "name", "card_count", "description"],
[
this_reward.id,
this_reward.name,
this_reward.team.id,
this_reward.daily,
this_reward.created,
],
]
return_val = DataFrame(data_list).to_csv(header=False, index=False)
return Response(content=return_val, media_type='text/csv')
return Response(content=return_val, media_type="text/csv")
else:
return_val = model_to_dict(this_reward)
return return_val
@router.post('')
@router.post("")
async def post_rewards(reward: RewardModel, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning('Bad Token: [REDACTED]')
logging.warning("Bad Token: [REDACTED]")
raise HTTPException(
status_code=401,
detail='You are not authorized to post rewards. This event has been logged.'
detail="You are not authorized to post rewards. This event has been logged.",
)
reward_data = reward.dict()
# Convert milliseconds timestamp to datetime for PostgreSQL
if reward_data.get('created'):
reward_data['created'] = datetime.fromtimestamp(reward_data['created'] / 1000)
if reward_data.get("created"):
reward_data["created"] = datetime.fromtimestamp(reward_data["created"] / 1000)
this_reward = Reward(**reward_data)
saved = this_reward.save()
@ -114,24 +127,30 @@ async def post_rewards(reward: RewardModel, token: str = Depends(oauth2_scheme))
else:
raise HTTPException(
status_code=418,
detail='Well slap my ass and call me a teapot; I could not save that cardset'
detail="Well slap my ass and call me a teapot; I could not save that cardset",
)
@router.patch('/{reward_id}')
@router.patch("/{reward_id}")
async def patch_reward(
reward_id, name: Optional[str] = None, team_id: Optional[int] = None, created: Optional[int] = None,
token: str = Depends(oauth2_scheme)):
reward_id,
name: Optional[str] = None,
team_id: Optional[int] = None,
created: Optional[int] = None,
token: str = Depends(oauth2_scheme),
):
if not valid_token(token):
logging.warning('Bad Token: [REDACTED]')
logging.warning("Bad Token: [REDACTED]")
raise HTTPException(
status_code=401,
detail='You are not authorized to patch rewards. This event has been logged.'
detail="You are not authorized to patch rewards. This event has been logged.",
)
try:
this_reward = Reward.get_by_id(reward_id)
except DoesNotExist:
raise HTTPException(status_code=404, detail=f'No reward found with id {reward_id}')
raise HTTPException(
status_code=404, detail=f"No reward found with id {reward_id}"
)
if name is not None:
this_reward.name = name
@ -147,28 +166,32 @@ async def patch_reward(
else:
raise HTTPException(
status_code=418,
detail='Well slap my ass and call me a teapot; I could not save that rarity'
detail="Well slap my ass and call me a teapot; I could not save that rarity",
)
@router.delete('/{reward_id}')
@router.delete("/{reward_id}")
async def delete_reward(reward_id, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning('Bad Token: [REDACTED]')
logging.warning("Bad Token: [REDACTED]")
raise HTTPException(
status_code=401,
detail='You are not authorized to delete rewards. This event has been logged.'
detail="You are not authorized to delete rewards. This event has been logged.",
)
try:
this_reward = Reward.get_by_id(reward_id)
except DoesNotExist:
raise HTTPException(status_code=404, detail=f'No reward found with id {reward_id}')
raise HTTPException(
status_code=404, detail=f"No reward found with id {reward_id}"
)
count = this_reward.delete_instance()
if count == 1:
raise HTTPException(status_code=200, detail=f'Reward {reward_id} has been deleted')
raise HTTPException(
status_code=200, detail=f"Reward {reward_id} has been deleted"
)
else:
raise HTTPException(status_code=500, detail=f'Reward {reward_id} was not deleted')
raise HTTPException(
status_code=500, detail=f"Reward {reward_id} was not deleted"
)