from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from sqlalchemy import select from sqlalchemy.orm import Session from database import engine from models import Todo from sqlalchemy.exc import SQLAlchemyError app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) class todocreate(BaseModel): task: str class todoupdate(BaseModel): completion: bool | None = None task: str | None = None class todoresponse(BaseModel): id: int task: str completion: bool @app.get("/health") def health(): return {"status":"ok"} @app.get("/todos", response_model=list[todoresponse]) def todos_get(): with Session(engine) as session: statement = select(Todo) todos = session.scalars(statement).all() return todos @app.post("/todos", response_model=todoresponse) def todos_create(todo_data:todocreate): with Session(engine) as session: try: new_todo = Todo(task = todo_data.task) session.add(new_todo) session.commit() session.refresh(new_todo) return new_todo except SQLAlchemyError: session.rollback() raise @app.patch("/todos/{todo_id}", response_model=todoresponse) def todos_patch(todo_id:int, update_data:todoupdate): with Session(engine) as session: try: todo = session.get(Todo, todo_id) if todo is None: raise HTTPException(status_code = 404, detail = "Todo not found") if update_data.task is not None: todo.task = update_data.task if update_data.completion is not None: todo.completion = update_data.completion session.commit() session.refresh(todo) return todo except SQLAlchemyError: session.rollback() raise @app.delete("/todos/{todo_id}", response_model=todoresponse) def todos_delete(todo_id:int): with Session(engine) as session: try: todo = session.get(Todo, todo_id) if todo is None: raise HTTPException(status_code = 404, detail = "Todo not found") session.delete(todo) session.commit() return todo except SQLAlchemyError: session.rollback() raise