From 02e7a97d6da2517fa5d6c68c366173d0cec86d6d Mon Sep 17 00:00:00 2001 From: Cesar E Garza Date: Fri, 2 Jan 2026 22:34:31 -0600 Subject: [PATCH] Add tournament team route to sendou proxy This commit introduces a new endpoint to fetch tournament team data from sendou.ink, enhancing the API's capabilities. The new route proxies requests to the sendou.ink turbo-stream endpoint and returns the data in plain JSON format. Error handling has been implemented to manage HTTP and decoding issues, ensuring robust functionality. --- src/fast_api_app/routes/sendou_proxy.py | 49 +++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/fast_api_app/routes/sendou_proxy.py b/src/fast_api_app/routes/sendou_proxy.py index 725bcdb..1097b80 100644 --- a/src/fast_api_app/routes/sendou_proxy.py +++ b/src/fast_api_app/routes/sendou_proxy.py @@ -26,6 +26,7 @@ ROUTE_KEY_TOURNAMENT_MATCH = ( "features/tournament-bracket/routes/to.$id.matches.$mid" ) +ROUTE_KEY_TOURNAMENT_TEAM = "features/tournament/routes/to.$id.teams.$tid" async def _fetch_turbo_stream(url: str) -> bytes: @@ -105,3 +106,51 @@ async def get_tournament_match( ) return data + + +@router.get( + "/to/{tournament_id}/teams/{team_id}", + name="sendou-tournament-team", + summary="Get tournament team data from sendou.ink", + description=( + "Proxies the sendou.ink turbo-stream endpoint and returns plain JSON. " + "Equivalent to the legacy ?_data format." + ), +) +async def get_tournament_team( + tournament_id: int = Path(..., description="Tournament ID on sendou.ink"), + team_id: int = Path(..., description="Team ID within the tournament"), +) -> Dict[str, Any]: + """Fetch and decode tournament team data from sendou.ink.""" + url = f"{SENDOU_BASE_URL}/to/{tournament_id}/teams/{team_id}.data" + + try: + raw_data = await _fetch_turbo_stream(url) + except httpx.HTTPStatusError as e: + logger.warning( + "sendou.ink returned %s for tournament=%s team=%s", + e.response.status_code, + tournament_id, + team_id, + ) + raise HTTPException( + status_code=e.response.status_code, + detail=f"sendou.ink returned {e.response.status_code}", + ) + except httpx.RequestError as e: + logger.error("Failed to fetch from sendou.ink: %s", e) + raise HTTPException( + status_code=502, + detail="Failed to fetch from sendou.ink", + ) + + try: + data = _decode_and_extract(raw_data, ROUTE_KEY_TOURNAMENT_TEAM) + except ValueError as e: + logger.error("Failed to decode turbo-stream data: %s", e) + raise HTTPException( + status_code=502, + detail="Failed to decode sendou.ink response", + ) + + return data