from typing import List
from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import JSONResponse
from core.config import settings
from db.models import Event, EventCreate, EventResponse
from db.repositories.events import EventRepository
router = APIRouter()
@router.get("/", response_model=EventResponse,status_code=200, operation_id="get_events")
async def get_events(
page: int = Query(1, ge=1, description="Page number"),
size: int = Query(settings.DEFAULT_PAGE_SIZE, ge=1, le=settings.MAX_PAGE_SIZE, description="Page size"),
repo: EventRepository = Depends()
):
"""
Get all events with pagination.
"""
limit = size
offset = (page - 1) * size
# Convert offset to last_evaluated_key (for real implementation)
# This is simplified - you'd need to handle this differently in production
last_key = None
result = await repo.get_all(limit=limit, last_evaluated_key=last_key)
return {
"items": result["items"],
"total": result["total"],
"page": page,
"size": size
}
@router.get("/{event_id}", response_model=Event,status_code=200, operation_id="get_event_by_id")
async def get_event(
event_id: str,
repo: EventRepository = Depends()
):
"""
Get a specific event by ID.
"""
event = await repo.get_by_id(event_id)
if not event:
raise HTTPException(status_code=404, detail="Event not found")
return event
@router.get("/year/{year}/month/{month}", response_model=List[Event],status_code=200, operation_id="get_events_by_month")
async def get_events_by_month(
year: int,
month: int,
repo: EventRepository = Depends()
):
"""
Get events for a specific year and month.
"""
try:
if not (1 <= month <= 12):
raise HTTPException(status_code=400, detail="Month must be between 1 and 12")
events = await repo.get_by_year_month(year, month)
# Even if no events are found, return an empty list (not an error)
return events
except HTTPException as he:
# Re-raise HTTP exceptions (like the 400 above)
raise he
except Exception as e:
# Log the error (in a production environment, you'd use a proper logger)
print(f"Error in get_events_by_month: {str(e)}")
# Return a proper error response
raise HTTPException(
status_code=500,
detail=f"An error occurred when retrieving events for {year}/{month}."
)
@router.get("/location/{location}", response_model=List[Event],status_code=200, operation_id="get_events_by_location")
async def get_events_by_location(
location: str,
repo: EventRepository = Depends()
):
"""
Get events by location.
"""
events = await repo.get_by_location(location)
return events
@router.get("/artist/{artist}", response_model=List[Event],status_code=200, operation_id="get_events_by_artist")
async def get_events_by_artist(
artist: str,
repo: EventRepository = Depends()
):
"""
Get events by artist.
"""
events = await repo.get_by_artist(artist)
return events
@router.post("/", response_model=Event, status_code=201, operation_id="create_event")
async def create_event(
event: EventCreate,
repo: EventRepository = Depends()
):
"""
Create a new event.
"""
return await repo.create(event)
@router.delete("/{event_id}", status_code=204, operation_id="delete_event")
async def delete_event(
event_id: str,
repo: EventRepository = Depends()
):
"""
Delete an event.
"""
success = await repo.delete(event_id)
if not success:
raise HTTPException(status_code=404, detail="Event not found")
return JSONResponse(status_code=204, content=None)