Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 58 additions & 131 deletions backend/src/modules/api_keys/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@

from typing import Any

from fastapi import APIRouter, HTTPException, Path, Query, status
from fastapi import APIRouter, Path, Query
from fastcrud import PaginatedListResponse, compute_offset, paginated_response

from ...infrastructure.dependencies import AsyncSessionDep, CurrentUserDep
from ..common.exceptions import (
PermissionDeniedError,
ResourceNotFoundError,
)
from ..common.utils.error_handler import handle_exception
from .dependencies import APIKeyServiceDep
from .schemas import (
APIKeyCreate,
Expand Down Expand Up @@ -54,17 +49,11 @@ async def create_api_key(
db: AsyncSessionDep,
) -> dict[str, Any]:
"""Create a new API key for the authenticated user."""
try:
return await api_key_service.create_api_key(
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
key_data=key_data,
db=db,
)
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
return await api_key_service.create_api_key(
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
key_data=key_data,
db=db,
)


@router.get(
Expand Down Expand Up @@ -96,25 +85,19 @@ async def get_user_api_keys(
items_per_page: int = Query(50, ge=1, le=100, description="Items per page"),
) -> dict[str, Any]:
"""Get all API keys for the authenticated user."""
try:
result = await api_key_service.get_user_api_keys(
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
active_only=active_only,
limit=items_per_page,
offset=compute_offset(page, items_per_page),
db=db,
)

return paginated_response(
crud_data=result,
page=page,
items_per_page=items_per_page,
)
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
result = await api_key_service.get_user_api_keys(
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
active_only=active_only,
limit=items_per_page,
offset=compute_offset(page, items_per_page),
db=db,
)

return paginated_response(
crud_data=result,
page=page,
items_per_page=items_per_page,
)


@router.get(
Expand Down Expand Up @@ -143,21 +126,11 @@ async def get_api_key(
key_id: int = Path(..., description="API key ID"),
) -> dict[str, Any]:
"""Get details for a specific API key."""
try:
return await api_key_service.get_api_key(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
db=db,
)
except ResourceNotFoundError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
except PermissionDeniedError as e:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
return await api_key_service.get_api_key(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
db=db,
)


@router.patch(
Expand Down Expand Up @@ -188,22 +161,12 @@ async def update_api_key(
key_id: int = Path(..., description="API key ID"),
) -> dict[str, Any]:
"""Update an existing API key."""
try:
return await api_key_service.update_api_key(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
update_data=update_data,
db=db,
)
except ResourceNotFoundError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
except PermissionDeniedError as e:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
return await api_key_service.update_api_key(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
update_data=update_data,
db=db,
)


@router.delete(
Expand Down Expand Up @@ -234,21 +197,11 @@ async def delete_api_key(
key_id: int = Path(..., description="API key ID"),
) -> None:
"""Delete (deactivate) an API key."""
try:
await api_key_service.delete_api_key(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
db=db,
)
except ResourceNotFoundError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
except PermissionDeniedError as e:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
await api_key_service.delete_api_key(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
db=db,
)


@router.get(
Expand Down Expand Up @@ -282,29 +235,19 @@ async def get_key_usage(
items_per_page: int = Query(100, ge=1, le=1000, description="Items per page"),
) -> dict[str, Any]:
"""Get usage history for an API key."""
try:
result = await api_key_service.get_key_usage(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
limit=items_per_page,
offset=compute_offset(page, items_per_page),
db=db,
)

return paginated_response(
crud_data=result,
page=page,
items_per_page=items_per_page,
)
except ResourceNotFoundError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
except PermissionDeniedError as e:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
result = await api_key_service.get_key_usage(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
limit=items_per_page,
offset=compute_offset(page, items_per_page),
db=db,
)

return paginated_response(
crud_data=result,
page=page,
items_per_page=items_per_page,
)


@router.get(
Expand Down Expand Up @@ -339,22 +282,12 @@ async def get_key_analytics(
days: int = Query(30, ge=1, le=365, description="Number of days to analyze"),
) -> dict[str, Any]:
"""Get usage analytics for an API key."""
try:
return await api_key_service.get_usage_analytics(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
days=days,
db=db,
)
except ResourceNotFoundError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
except PermissionDeniedError as e:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
return await api_key_service.get_usage_analytics(
key_id=key_id,
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
days=days,
db=db,
)


@router.get(
Expand Down Expand Up @@ -383,13 +316,7 @@ async def get_user_summary(
db: AsyncSessionDep,
) -> dict[str, Any]:
"""Get comprehensive API key summary for the authenticated user."""
try:
return await api_key_service.get_user_summary(
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
db=db,
)
except Exception as e:
http_exc = handle_exception(e)
if http_exc:
raise http_exc
raise HTTPException(status_code=500, detail="Internal server error")
return await api_key_service.get_user_summary(
user_id=current_user["id"] if isinstance(current_user, dict) else current_user.id,
db=db,
)
59 changes: 12 additions & 47 deletions backend/src/modules/rate_limit/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
from fastapi import APIRouter
from fastcrud import PaginatedListResponse, compute_offset, paginated_response

from ...infrastructure.auth.http_exceptions import DuplicateValueException, HTTPException, NotFoundException
from ...infrastructure.dependencies import AsyncSessionDep, CurrentSuperUserDep
from ..common.exceptions import ResourceExistsError, ResourceNotFoundError
from ..common.utils.error_handler import handle_exception
from .dependencies import RateLimitServiceDep
from .schemas import (
RateLimitRead,
Expand Down Expand Up @@ -45,19 +42,13 @@ async def get_rate_limits(
Get a paginated list of all rate limits.
This endpoint is available to all authenticated users.
"""
try:
rate_limits_data = await rate_limit_service.get_all(
db=db,
skip=compute_offset(page, items_per_page),
limit=items_per_page,
)
rate_limits_data = await rate_limit_service.get_all(
db=db,
skip=compute_offset(page, items_per_page),
limit=items_per_page,
)

return paginated_response(crud_data=rate_limits_data, page=page, items_per_page=items_per_page)
except Exception as e:
http_exception = handle_exception(e)
if http_exception:
raise http_exception
raise HTTPException(status_code=500, detail="An unexpected error occurred")
return paginated_response(crud_data=rate_limits_data, page=page, items_per_page=items_per_page)


@router.get(
Expand Down Expand Up @@ -88,16 +79,8 @@ async def get_rate_limit(
Get detailed information about a specific rate limit by name.
This endpoint is available to all authenticated users.
"""
try:
rate_limit = await rate_limit_service.get_by_name(name, db)
return rate_limit
except ResourceNotFoundError:
raise NotFoundException("Rate limit not found")
except Exception as e:
http_exception = handle_exception(e)
if http_exception:
raise http_exception
raise HTTPException(status_code=500, detail="An unexpected error occurred")
rate_limit = await rate_limit_service.get_by_name(name, db)
return rate_limit


@router.patch(
Expand Down Expand Up @@ -139,18 +122,8 @@ async def update_rate_limit(
Update an existing rate limit.
This endpoint is restricted to superusers only.
"""
try:
await rate_limit_service.update(name, values, db)
return {"message": "Rate limit updated"}
except ResourceNotFoundError:
raise NotFoundException("Rate limit not found")
except ResourceExistsError:
raise DuplicateValueException("Rate limit name already exists")
except Exception as e:
http_exception = handle_exception(e)
if http_exception:
raise http_exception
raise HTTPException(status_code=500, detail="An unexpected error occurred")
await rate_limit_service.update(name, values, db)
return {"message": "Rate limit updated"}


@router.delete(
Expand Down Expand Up @@ -188,13 +161,5 @@ async def delete_rate_limit(
Delete a rate limit.
This endpoint is restricted to superusers only.
"""
try:
await rate_limit_service.delete(name, db)
return {"message": "Rate limit deleted"}
except ResourceNotFoundError:
raise NotFoundException("Rate limit not found")
except Exception as e:
http_exception = handle_exception(e)
if http_exception:
raise http_exception
raise HTTPException(status_code=500, detail="An unexpected error occurred")
await rate_limit_service.delete(name, db)
return {"message": "Rate limit deleted"}
33 changes: 8 additions & 25 deletions backend/src/modules/tier/routes.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
from typing import Any

from fastapi import APIRouter, HTTPException
from fastapi import APIRouter
from fastcrud import PaginatedListResponse, compute_offset, paginated_response

from ...infrastructure.auth.http_exceptions import NotFoundException
from ...infrastructure.dependencies import AsyncSessionDep
from ..common.exceptions import TierNotFoundError
from ..common.utils.error_handler import handle_exception
from .dependencies import TierServiceDep
from .schemas import TierRead

Expand All @@ -21,18 +18,12 @@ async def get_tiers(
items_per_page: int = 10,
) -> dict:
"""Paginated list of tiers."""
try:
tiers_data = await tier_service.get_all(
db=db,
skip=compute_offset(page, items_per_page),
limit=items_per_page,
)
return paginated_response(crud_data=tiers_data, page=page, items_per_page=items_per_page)
except Exception as e:
http_exception = handle_exception(e)
if http_exception:
raise http_exception
raise HTTPException(status_code=500, detail="An unexpected error occurred")
tiers_data = await tier_service.get_all(
db=db,
skip=compute_offset(page, items_per_page),
limit=items_per_page,
)
return paginated_response(crud_data=tiers_data, page=page, items_per_page=items_per_page)


@router.get("/{name}", response_model=TierRead, summary="Get a tier by name")
Expand All @@ -42,12 +33,4 @@ async def get_tier_by_name(
tier_service: TierServiceDep,
) -> dict[str, Any]:
"""Get a tier by name."""
try:
return await tier_service.get_by_name(name, db)
except TierNotFoundError:
raise NotFoundException("Tier not found")
except Exception as e:
http_exception = handle_exception(e)
if http_exception:
raise http_exception
raise HTTPException(status_code=500, detail="An unexpected error occurred")
return await tier_service.get_by_name(name, db)
Loading
Loading