from typing import Any, List, Optional from fastapi import APIRouter, Depends, status from sqlalchemy.orm import Session from app.core.exceptions import TodoNotFoundException from app.db.crud import todo from app.db.session import get_db from app.schemas.todo import Todo, TodoCreate, TodoUpdate router = APIRouter() @router.get("/", response_model=List[Todo]) def read_todos( db: Session = Depends(get_db), skip: int = 0, limit: int = 100, completed: Optional[bool] = None, ) -> Any: """ Retrieve todos. - **skip**: Number of items to skip (for pagination) - **limit**: Maximum number of items to return - **completed**: Optional filter for todo completion status """ if completed is None: todos = todo.get_multi(db, skip=skip, limit=limit) elif completed: todos = todo.get_completed(db, skip=skip, limit=limit) else: todos = todo.get_uncompleted(db, skip=skip, limit=limit) return todos @router.post("/", response_model=Todo, status_code=status.HTTP_201_CREATED) def create_todo( *, db: Session = Depends(get_db), todo_in: TodoCreate, ) -> Any: """ Create new todo. - **title**: Required title for the todo - **description**: Optional detailed description - **completed**: Whether the todo is already completed (default: False) """ return todo.create(db, obj_in=todo_in) @router.get("/{todo_id}", response_model=Todo) def read_todo( *, db: Session = Depends(get_db), todo_id: int, ) -> Any: """ Get todo by ID. - **todo_id**: The ID of the todo to retrieve """ db_todo = todo.get(db, id=todo_id) if not db_todo: raise TodoNotFoundException(f"Todo with ID {todo_id} not found") return db_todo @router.put("/{todo_id}", response_model=Todo) def update_todo( *, db: Session = Depends(get_db), todo_id: int, todo_in: TodoUpdate, ) -> Any: """ Update a todo. - **todo_id**: The ID of the todo to update - **title**: New title (optional) - **description**: New description (optional) - **completed**: New completion status (optional) """ db_todo = todo.get(db, id=todo_id) if not db_todo: raise TodoNotFoundException(f"Todo with ID {todo_id} not found") db_todo = todo.update(db, db_obj=db_todo, obj_in=todo_in) return db_todo @router.delete("/{todo_id}", response_model=None, status_code=status.HTTP_204_NO_CONTENT) def delete_todo( *, db: Session = Depends(get_db), todo_id: int, ) -> None: """ Delete a todo. - **todo_id**: The ID of the todo to delete """ db_todo = todo.get(db, id=todo_id) if not db_todo: raise TodoNotFoundException(f"Todo with ID {todo_id} not found") todo.remove(db, id=todo_id) return None