from fastapi import FastAPI, HTTPException, Depends, Query from sqlalchemy.orm import Session from typing import List, Optional from datetime import datetime from models import Todo, SessionLocal from schemas import TodoCreate, TodoResponse app = FastAPI() # Dependency to get database session def get_db(): db = SessionLocal() try: yield db finally: db.close() @app.post("/todos", response_model=TodoResponse, status_code=201) async def create_todo(todo: TodoCreate, db: Session = Depends(get_db)): db_todo = Todo(**todo.model_dump()) db.add(db_todo) db.commit() db.refresh(db_todo) return db_todo @app.get("/todos", response_model=List[TodoResponse]) async def read_todos(status: Optional[str] = Query(None), db: Session = Depends(get_db)): if status: todos = db.query(Todo).filter(Todo.status == status).all() else: todos = db.query(Todo).all() return todos @app.get("/todos/{id}", response_model=TodoResponse) async def read_todo(id: int, db: Session = Depends(get_db)): todo = db.query(Todo).filter(Todo.id == id).first() if not todo: raise HTTPException(status_code=404, detail="Todo not found") return todo @app.put("/todos/{id}", response_model=TodoResponse) async def update_todo(id: int, todo: TodoCreate, db: Session = Depends(get_db)): db_todo = db.query(Todo).filter(Todo.id == id).first() if not db_todo: raise HTTPException(status_code=404, detail="Todo not found") for key, value in todo.model_dump().items(): setattr(db_todo, key, value) db.commit() db.refresh(db_todo) return db_todo @app.delete("/todos/{id}", status_code=204) async def delete_todo(id: int, db: Session = Depends(get_db)): db_todo = db.query(Todo).filter(Todo.id == id).first() if not db_todo: raise HTTPException(status_code=404, detail="Todo not found") db.delete(db_todo) db.commit() @app.patch("/todos/{id}/complete", status_code=204) async def complete_todo(id: int, db: Session = Depends(get_db)): db_todo = db.query(Todo).filter(Todo.id == id).first() if not db_todo: raise HTTPException(status_code=404, detail="Todo not found") db_todo.status = 'completed' db.commit() @app.get("/todos/count", response_model=int) async def get_todo_count(db: Session = Depends(get_db)): return db.query(Todo).count() @app.get("/todos/search?q={query}", response_model=List[TodoResponse]) async def search_todos(query: str, db: Session = Depends(get_db)): todos = db.query(Todo).filter(Todo.title.contains(query)).all() return todos