routers.leaderboard

Endpoints for leaderboard.

 1"""Endpoints for leaderboard."""
 2
 3from enum import Enum
 4
 5from fastapi import APIRouter, HTTPException, status
 6from internal.database.dependency import database_dependency
 7from internal.queries.user import AsyncQuerier as UserQuerier
 8
 9router = APIRouter(prefix="/leaderboard", tags=["leaderboard"])
10
11
12class LeaderboardTypes(Enum):
13    """Leaderboard types."""
14
15    RESERVATIONS = "reservations"
16    CARBON_DIOXIDE = "carbon_dioxide"
17
18
19@router.get(
20    path="/",
21    summary="Get leaderboard types",
22    description="Retrieves all available leaderboard types.",
23)
24async def get_leaderboard_types() -> list[str]:
25    """Get all leaderboard types.
26
27    Returns:
28        leaderboard types
29    """
30    return [leaderboard_type.value for leaderboard_type in LeaderboardTypes]
31
32
33@router.get(
34    path="/leaderboard/{leaderboard_type}",
35    summary="Get leaderboard",
36    description=(
37        "Retrieves the leaderboard for a specific type, "
38        "returning top users by reservation count or carbon dioxide saved."
39    ),
40)
41async def get_leaderboard(
42    leaderboard_type: LeaderboardTypes, limit: int, conn: database_dependency
43) -> list[tuple[str, int]]:
44    """Get leaderboard of a type.
45
46    Args:
47        leaderboard_type: leaderboard type
48        limit: how many users to show
49        conn: database connection
50
51    Returns:
52        leaderboard of users for a type
53
54    Raises:
55        HTTPException: if failed to get leaderboard
56    """
57    user_querier = UserQuerier(conn)
58    match leaderboard_type:
59        case LeaderboardTypes.RESERVATIONS:
60            if (
61                leaderboard_reservations := user_querier.leaderboard_reservations(
62                    limit=limit
63                )
64            ) is None:
65                raise HTTPException(
66                    status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get leaderboard"
67                )
68            return [
69                (user.username, user.reservation_count)
70                async for user in leaderboard_reservations
71            ]
72        case LeaderboardTypes.CARBON_DIOXIDE:
73            if (
74                leaderboard_carbon_dioxide := user_querier.leaderboard_carbon_dioxide(
75                    limit=limit
76                )
77            ) is None:
78                raise HTTPException(
79                    status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get leaderboard"
80                )
81            return [
82                (user.username, int(user.total_carbon_dioxide))
83                async for user in leaderboard_carbon_dioxide
84            ]
router = <fastapi.routing.APIRouter object>
class LeaderboardTypes(enum.Enum):
13class LeaderboardTypes(Enum):
14    """Leaderboard types."""
15
16    RESERVATIONS = "reservations"
17    CARBON_DIOXIDE = "carbon_dioxide"

Leaderboard types.

RESERVATIONS = <LeaderboardTypes.RESERVATIONS: 'reservations'>
CARBON_DIOXIDE = <LeaderboardTypes.CARBON_DIOXIDE: 'carbon_dioxide'>
@router.get(path='/', summary='Get leaderboard types', description='Retrieves all available leaderboard types.')
async def get_leaderboard_types() -> list[str]:
20@router.get(
21    path="/",
22    summary="Get leaderboard types",
23    description="Retrieves all available leaderboard types.",
24)
25async def get_leaderboard_types() -> list[str]:
26    """Get all leaderboard types.
27
28    Returns:
29        leaderboard types
30    """
31    return [leaderboard_type.value for leaderboard_type in LeaderboardTypes]

Get all leaderboard types.

Returns:

leaderboard types

@router.get(path='/leaderboard/{leaderboard_type}', summary='Get leaderboard', description='Retrieves the leaderboard for a specific type, returning top users by reservation count or carbon dioxide saved.')
async def get_leaderboard( leaderboard_type: LeaderboardTypes, limit: int, conn: Annotated[sqlalchemy.ext.asyncio.engine.AsyncConnection, Depends(dependency=<bound method DatabaseManager.get_connection of <internal.database.manager.DatabaseManager object>>, use_cache=True, scope=None)]) -> list[tuple[str, int]]:
34@router.get(
35    path="/leaderboard/{leaderboard_type}",
36    summary="Get leaderboard",
37    description=(
38        "Retrieves the leaderboard for a specific type, "
39        "returning top users by reservation count or carbon dioxide saved."
40    ),
41)
42async def get_leaderboard(
43    leaderboard_type: LeaderboardTypes, limit: int, conn: database_dependency
44) -> list[tuple[str, int]]:
45    """Get leaderboard of a type.
46
47    Args:
48        leaderboard_type: leaderboard type
49        limit: how many users to show
50        conn: database connection
51
52    Returns:
53        leaderboard of users for a type
54
55    Raises:
56        HTTPException: if failed to get leaderboard
57    """
58    user_querier = UserQuerier(conn)
59    match leaderboard_type:
60        case LeaderboardTypes.RESERVATIONS:
61            if (
62                leaderboard_reservations := user_querier.leaderboard_reservations(
63                    limit=limit
64                )
65            ) is None:
66                raise HTTPException(
67                    status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get leaderboard"
68                )
69            return [
70                (user.username, user.reservation_count)
71                async for user in leaderboard_reservations
72            ]
73        case LeaderboardTypes.CARBON_DIOXIDE:
74            if (
75                leaderboard_carbon_dioxide := user_querier.leaderboard_carbon_dioxide(
76                    limit=limit
77                )
78            ) is None:
79                raise HTTPException(
80                    status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get leaderboard"
81                )
82            return [
83                (user.username, int(user.total_carbon_dioxide))
84                async for user in leaderboard_carbon_dioxide
85            ]

Get leaderboard of a type.

Arguments:
  • leaderboard_type: leaderboard type
  • limit: how many users to show
  • conn: database connection
Returns:

leaderboard of users for a type

Raises:
  • HTTPException: if failed to get leaderboard