muhammadshaheryar commited on
Commit
8822d62
·
verified ·
1 Parent(s): a545e9b

Update src/main.py

Browse files
Files changed (1) hide show
  1. src/main.py +54 -34
src/main.py CHANGED
@@ -2,7 +2,6 @@
2
  import os
3
  import sys
4
  from pathlib import Path
5
- from contextlib import asynccontextmanager
6
  from datetime import datetime
7
  from typing import Optional
8
 
@@ -28,27 +27,21 @@ from api.chat_router import router as chat_router
28
  from api.task_router import router as task_router
29
  from middleware.auth import get_current_user
30
 
31
- @asynccontextmanager
32
- async def lifespan(app: FastAPI):
33
- # Startup logic
34
- Base.metadata.create_all(bind=engine)
35
- yield
36
- # Shutdown logic (if any) can go here
37
-
38
  app = FastAPI(
39
  title="Todo API",
40
  description="REST API for managing todo items with extended features",
41
- version="2.0.0",
42
- lifespan=lifespan
43
  )
44
 
45
- # FIXED CORS: Added GitHub Pages support
 
 
 
 
 
46
  app.add_middleware(
47
  CORSMiddleware,
48
- allow_origins=[
49
- "http://localhost:3000",
50
- "https://shaheryarshah.github.io", # <--- CHANGE THIS to your GitHub Pages URL
51
- ],
52
  allow_credentials=True,
53
  allow_methods=["*"],
54
  allow_headers=["*"],
@@ -60,26 +53,27 @@ app.include_router(chat_router)
60
  app.include_router(task_router, prefix="/api/v1")
61
 
62
  def _calculate_overdue(todo: Todo) -> bool:
 
63
  if todo.due_date is None or todo.completed:
64
  return False
65
  return todo.due_date < datetime.utcnow()
66
 
67
  def _todo_to_response(todo: Todo) -> TodoResponse:
68
- response_data = {
69
- "id": todo.id,
70
- "user_id": todo.user_id,
71
- "title": todo.title,
72
- "description": todo.description,
73
- "completed": todo.completed,
74
- "priority": todo.priority,
75
- "tags": todo.tags,
76
- "due_date": todo.due_date,
77
- "recurrence": todo.recurrence,
78
- "created_at": todo.created_at,
79
- "updated_at": todo.updated_at,
80
- "overdue": _calculate_overdue(todo)
81
- }
82
- return TodoResponse(**response_data)
83
 
84
  @app.get("/api/v1/todos", response_model=TodoListResponse)
85
  def get_todos(
@@ -103,10 +97,36 @@ def get_todos(
103
  todos_response = [_todo_to_response(todo) for todo in todos]
104
  return {"todos": todos_response, "count": len(todos_response), "has_more": False}
105
 
106
- # ... (Keep other routes as they are, but ensure regular spaces are used)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  if __name__ == "__main__":
109
  import uvicorn
110
- # Hugging Face uses PORT 7860 by default
111
- port = int(os.getenv("PORT", 7860))
112
- uvicorn.run(app, host="0.0.0.0", port=port)
 
2
  import os
3
  import sys
4
  from pathlib import Path
 
5
  from datetime import datetime
6
  from typing import Optional
7
 
 
27
  from api.task_router import router as task_router
28
  from middleware.auth import get_current_user
29
 
 
 
 
 
 
 
 
30
  app = FastAPI(
31
  title="Todo API",
32
  description="REST API for managing todo items with extended features",
33
+ version="2.0.0"
 
34
  )
35
 
36
+ # FIXED STARTUP: Using on_event to avoid the "async iterator" TypeError
37
+ @app.on_event("startup")
38
+ def startup_event():
39
+ Base.metadata.create_all(bind=engine)
40
+
41
+ # FIXED CORS: Using "*" allows your GitHub Pages site to connect without being blocked
42
  app.add_middleware(
43
  CORSMiddleware,
44
+ allow_origins=["*"],
 
 
 
45
  allow_credentials=True,
46
  allow_methods=["*"],
47
  allow_headers=["*"],
 
53
  app.include_router(task_router, prefix="/api/v1")
54
 
55
  def _calculate_overdue(todo: Todo) -> bool:
56
+ """Calculate if a todo is overdue."""
57
  if todo.due_date is None or todo.completed:
58
  return False
59
  return todo.due_date < datetime.utcnow()
60
 
61
  def _todo_to_response(todo: Todo) -> TodoResponse:
62
+ """Convert Todo model to TodoResponse schema."""
63
+ return TodoResponse(
64
+ id=todo.id,
65
+ user_id=todo.user_id,
66
+ title=todo.title,
67
+ description=todo.description,
68
+ completed=todo.completed,
69
+ priority=todo.priority,
70
+ tags=todo.tags,
71
+ due_date=todo.due_date,
72
+ recurrence=todo.recurrence,
73
+ created_at=todo.created_at,
74
+ updated_at=todo.updated_at,
75
+ overdue=_calculate_overdue(todo)
76
+ )
77
 
78
  @app.get("/api/v1/todos", response_model=TodoListResponse)
79
  def get_todos(
 
97
  todos_response = [_todo_to_response(todo) for todo in todos]
98
  return {"todos": todos_response, "count": len(todos_response), "has_more": False}
99
 
100
+ @app.post("/api/v1/todos", response_model=TodoResponse, status_code=201)
101
+ def create_todo(todo_data: TodoCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
102
+ service = TodoService(db, user_id=current_user.id)
103
+ todo = service.create(todo_data)
104
+ return _todo_to_response(todo)
105
+
106
+ @app.get("/api/v1/todos/{todo_id}", response_model=TodoResponse)
107
+ def get_todo(todo_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
108
+ service = TodoService(db, user_id=current_user.id)
109
+ todo = service.get_by_id(todo_id)
110
+ if not todo:
111
+ raise HTTPException(status_code=404, detail="Todo not found")
112
+ return _todo_to_response(todo)
113
+
114
+ @app.put("/api/v1/todos/{todo_id}", response_model=TodoResponse)
115
+ def update_todo(todo_id: int, todo_data: TodoUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
116
+ service = TodoService(db, user_id=current_user.id)
117
+ todo = service.update(todo_id, todo_data)
118
+ if not todo:
119
+ raise HTTPException(status_code=404, detail="Todo not found")
120
+ return _todo_to_response(todo)
121
+
122
+ @app.delete("/api/v1/todos/{todo_id}")
123
+ def delete_todo(todo_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
124
+ service = TodoService(db, user_id=current_user.id)
125
+ if not service.delete(todo_id):
126
+ raise HTTPException(status_code=404, detail="Todo not found")
127
+ return {"message": "Todo deleted successfully"}
128
 
129
  if __name__ == "__main__":
130
  import uvicorn
131
+ # PORT 7860 is required for Hugging Face Spaces
132
+ uvicorn.run(app, host="0.0.0.0", port=int(os.getenv("PORT", 7860)))