H2P3B / src /main.py
muhammadshaheryar's picture
Update src/main.py
d93340c verified
import os
from datetime import datetime
from typing import Optional
from fastapi import FastAPI, Depends, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
# These imports now work because of the path fix in the root main.py
from database import get_db, engine, Base
from models.todo import Todo
from models.user import User
from schemas.todo import TodoCreate, TodoUpdate, TodoResponse, TodoListResponse
from services.todo_service import TodoService
from api.routes.auth import router as auth_router
from api.chat_router import router as chat_router
from api.task_router import router as task_router
from middleware.auth import get_current_user
app = FastAPI(
title="Todo API",
description="REST API for managing todo items",
version="2.0.0"
)
# FIX: Use on_event to avoid 'generator object is not an async iterator' error
@app.on_event("startup")
def startup_event():
print("Backend starting... Creating database tables.")
Base.metadata.create_all(bind=engine)
# FIX: Allow GitHub Pages to connect
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include All Routers
app.include_router(auth_router, prefix="/api/v1")
app.include_router(chat_router)
app.include_router(task_router, prefix="/api/v1")
@app.get("/")
def health():
return {"status": "online", "server": "Hugging Face Spaces"}
# --- COMPLETE TODO ROUTES ---
@app.get("/api/v1/todos", response_model=TodoListResponse)
def get_todos(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
search: Optional[str] = Query(None),
status: Optional[str] = Query(None),
priority: Optional[str] = Query(None),
sort_by: Optional[str] = Query("created_at"),
sort_order: Optional[str] = Query("desc"),
):
service = TodoService(db, user_id=current_user.id)
todos = service.get_all(search=search, status=status, priority=priority, sort_by=sort_by, sort_order=sort_order)
# Helper to convert models to response
def _todo_to_response(todo):
return TodoResponse(
id=todo.id, user_id=todo.user_id, title=todo.title,
description=todo.description, completed=todo.completed,
priority=todo.priority, tags=todo.tags, due_date=todo.due_date,
recurrence=todo.recurrence, created_at=todo.created_at, updated_at=todo.updated_at,
overdue=False if todo.due_date is None or todo.completed else todo.due_date < datetime.utcnow()
)
todos_response = [_todo_to_response(t) for t in todos]
return {"todos": todos_response, "count": len(todos_response), "has_more": False}
@app.post("/api/v1/todos", response_model=TodoResponse, status_code=201)
def create_todo(todo_data: TodoCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
service = TodoService(db, user_id=current_user.id)
todo = service.create(todo_data)
# Re-using logic to return response
return TodoResponse(
id=todo.id, user_id=todo.user_id, title=todo.title,
description=todo.description, completed=todo.completed,
priority=todo.priority, created_at=todo.created_at, updated_at=todo.updated_at
)
@app.delete("/api/v1/todos/{todo_id}")
def delete_todo(todo_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
service = TodoService(db, user_id=current_user.id)
if not service.delete(todo_id):
raise HTTPException(status_code=404, detail="Todo not found")
return {"message": "Todo deleted successfully"}