Update caching rules & Add DELETE /draftlist

This commit is contained in:
Cal Corum 2025-10-25 20:15:56 -05:00
parent a3f84ac935
commit 7ce64a14ea
3 changed files with 52 additions and 21 deletions

View File

@ -94,3 +94,15 @@ async def post_draftlist(draft_list: DraftListList, token: str = Depends(oauth2_
db.close() db.close()
return f'Inserted {len(new_list)} list values' return f'Inserted {len(new_list)} list values'
@router.delete('/team/{team_id}', include_in_schema=PRIVATE_IN_SCHEMA)
@handle_db_errors
async def delete_draftlist(team_id: int, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logger.warning(f'delete_draftlist - Bad Token: {token}')
raise HTTPException(status_code=401, detail='Unauthorized')
count = DraftList.delete().where(DraftList.team_id == team_id).execute()
db.close()
return f'Deleted {count} list values'

View File

@ -50,6 +50,7 @@ class PlayerList(pydantic.BaseModel):
@router.get('') @router.get('')
@handle_db_errors @handle_db_errors
@add_cache_headers(max_age=30*60) # 30 minutes - safe with cache invalidation on writes @add_cache_headers(max_age=30*60) # 30 minutes - safe with cache invalidation on writes
@cache_result(ttl=30*60, key_prefix='players')
async def get_players( async def get_players(
season: Optional[int], name: Optional[str] = None, team_id: list = Query(default=None), season: Optional[int], name: Optional[str] = None, team_id: list = Query(default=None),
pos: list = Query(default=None), strat_code: list = Query(default=None), is_injured: Optional[bool] = None, pos: list = Query(default=None), strat_code: list = Query(default=None), is_injured: Optional[bool] = None,
@ -127,6 +128,7 @@ async def get_players(
@router.get('/search') @router.get('/search')
@handle_db_errors @handle_db_errors
@add_cache_headers(max_age=15*60) # 15 minutes - safe with cache invalidation on writes @add_cache_headers(max_age=15*60) # 15 minutes - safe with cache invalidation on writes
@cache_result(ttl=15*60, key_prefix='players-search')
async def search_players( async def search_players(
q: str = Query(..., description="Search query for player name"), q: str = Query(..., description="Search query for player name"),
season: Optional[int] = Query(default=None, description="Season to search in (defaults to current)"), season: Optional[int] = Query(default=None, description="Season to search in (defaults to current)"),
@ -178,6 +180,7 @@ async def search_players(
@router.get('/{player_id}') @router.get('/{player_id}')
@handle_db_errors @handle_db_errors
@add_cache_headers(max_age=30*60) # 30 minutes - safe with cache invalidation on writes @add_cache_headers(max_age=30*60) # 30 minutes - safe with cache invalidation on writes
@cache_result(ttl=30*60, key_prefix='player')
async def get_one_player(player_id: int, short_output: Optional[bool] = False): async def get_one_player(player_id: int, short_output: Optional[bool] = False):
this_player = Player.get_or_none(Player.id == player_id) this_player = Player.get_or_none(Player.id == player_id)
if this_player: if this_player:
@ -205,11 +208,11 @@ async def put_player(
db.close() db.close()
# Invalidate player-related cache entries # Invalidate player-related cache entries
invalidate_cache("api:get_players*") invalidate_cache("players*")
invalidate_cache("api:search_players*") invalidate_cache("players-search*")
invalidate_cache(f"api:get_one_player*{player_id}*") invalidate_cache(f"player*{player_id}*")
# Invalidate team roster cache (use wildcard since team may have changed) # Invalidate team roster cache (player data affects team rosters)
invalidate_cache("api:get_team_roster*") invalidate_cache("team-roster*")
return r_player return r_player
@ -293,11 +296,11 @@ async def patch_player(
db.close() db.close()
# Invalidate player-related cache entries # Invalidate player-related cache entries
invalidate_cache("api:get_players*") invalidate_cache("players*")
invalidate_cache("api:search_players*") invalidate_cache("players-search*")
invalidate_cache(f"api:get_one_player*{player_id}*") invalidate_cache(f"player*{player_id}*")
# Invalidate team roster cache (use wildcard since team may have changed) # Invalidate team roster cache (player data affects team rosters)
invalidate_cache("api:get_team_roster*") invalidate_cache("team-roster*")
return r_player return r_player
else: else:
@ -330,11 +333,11 @@ async def post_players(p_list: PlayerList, token: str = Depends(oauth2_scheme)):
db.close() db.close()
# Invalidate player-related cache entries # Invalidate player-related cache entries
invalidate_cache("api:get_players*") invalidate_cache("players*")
invalidate_cache("api:search_players*") invalidate_cache("players-search*")
invalidate_cache("api:get_one_player*") invalidate_cache("player*")
# Invalidate team roster cache (new players added to teams) # Invalidate team roster cache (new players added to teams)
invalidate_cache("api:get_team_roster*") invalidate_cache("team-roster*")
return f'Inserted {len(new_players)} players' return f'Inserted {len(new_players)} players'
@ -356,11 +359,11 @@ async def delete_player(player_id: int, token: str = Depends(oauth2_scheme)):
if count == 1: if count == 1:
# Invalidate player-related cache entries # Invalidate player-related cache entries
invalidate_cache("api:get_players*") invalidate_cache("players*")
invalidate_cache("api:search_players*") invalidate_cache("players-search*")
invalidate_cache(f"api:get_one_player*{player_id}*") invalidate_cache(f"player*{player_id}*")
# Invalidate team roster cache (player removed from team) # Invalidate team roster cache (player removed from team)
invalidate_cache("api:get_team_roster*") invalidate_cache("team-roster*")
return f'Player {player_id} has been deleted' return f'Player {player_id} has been deleted'
else: else:

View File

@ -5,7 +5,7 @@ import logging
import pydantic import pydantic
from ..db_engine import db, Team, Manager, Division, model_to_dict, chunked, fn, query_to_csv, Player from ..db_engine import db, Team, Manager, Division, model_to_dict, chunked, fn, query_to_csv, Player
from ..dependencies import add_cache_headers, cache_result, oauth2_scheme, valid_token, PRIVATE_IN_SCHEMA, handle_db_errors from ..dependencies import add_cache_headers, cache_result, oauth2_scheme, valid_token, PRIVATE_IN_SCHEMA, handle_db_errors, invalidate_cache
logger = logging.getLogger('discord_app') logger = logging.getLogger('discord_app')
@ -77,7 +77,7 @@ async def get_teams(
@router.get('/{team_id}') @router.get('/{team_id}')
@handle_db_errors @handle_db_errors
@add_cache_headers(max_age=60*60) # @add_cache_headers(max_age=60*60)
@cache_result(ttl=30*60, key_prefix='team') @cache_result(ttl=30*60, key_prefix='team')
async def get_one_team(team_id: int): async def get_one_team(team_id: int):
this_team = Team.get_or_none(Team.id == team_id) this_team = Team.get_or_none(Team.id == team_id)
@ -91,7 +91,7 @@ async def get_one_team(team_id: int):
@router.get('/{team_id}/roster/{which}', include_in_schema=PRIVATE_IN_SCHEMA) @router.get('/{team_id}/roster/{which}', include_in_schema=PRIVATE_IN_SCHEMA)
@handle_db_errors @handle_db_errors
@add_cache_headers(max_age=60*60) # @add_cache_headers(max_age=60*60)
@cache_result(ttl=30*60, key_prefix='team-roster') @cache_result(ttl=30*60, key_prefix='team-roster')
async def get_team_roster(team_id: int, which: Literal['current', 'next'], sort: Optional[str] = None): async def get_team_roster(team_id: int, which: Literal['current', 'next'], sort: Optional[str] = None):
try: try:
@ -201,6 +201,12 @@ async def patch_team(
if this_team.save(): if this_team.save():
r_team = model_to_dict(this_team) r_team = model_to_dict(this_team)
db.close() db.close()
# Invalidate team-related cache entries
invalidate_cache("teams*")
invalidate_cache(f"team*{team_id}*")
invalidate_cache("team-roster*")
return r_team return r_team
else: else:
db.close() db.close()
@ -242,6 +248,11 @@ async def post_team(team_list: TeamList, token: str = Depends(oauth2_scheme)):
Team.insert_many(batch).on_conflict_ignore().execute() Team.insert_many(batch).on_conflict_ignore().execute()
db.close() db.close()
# Invalidate team-related cache entries
invalidate_cache("teams*")
invalidate_cache("team*")
invalidate_cache("team-roster*")
return f'Inserted {len(new_teams)} teams' return f'Inserted {len(new_teams)} teams'
@ -261,6 +272,11 @@ async def delete_team(team_id: int, token: str = Depends(oauth2_scheme)):
db.close() db.close()
if count == 1: if count == 1:
# Invalidate team-related cache entries
invalidate_cache("teams*")
invalidate_cache(f"team*{team_id}*")
invalidate_cache("team-roster*")
return f'Team {team_id} has been deleted' return f'Team {team_id} has been deleted'
else: else:
raise HTTPException(status_code=500, detail=f'Team {team_id} could not be deleted') raise HTTPException(status_code=500, detail=f'Team {team_id} could not be deleted')