Automated Action 9c5b74200b Setup basic FastAPI project with Todo API
- Created requirements.txt with necessary dependencies
- Set up FastAPI application structure with main.py
- Added health endpoint
- Configured SQLAlchemy with SQLite database
- Initialized Alembic for database migrations
- Created Todo model and API endpoints
- Updated README with setup and usage instructions
- Linted code with Ruff
2025-05-29 02:07:19 +00:00

128 lines
3.6 KiB
Python

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
import uvicorn
from typing import List, Optional
from pydantic import BaseModel
from datetime import datetime
# Import database models and config
from app.database.config import get_db
from app.database.models import Todo as TodoModel
# Create tables if they don't exist
# In production, you should use Alembic migrations instead
# models.Base.metadata.create_all(bind=engine)
# Pydantic models for request and response
class TodoBase(BaseModel):
title: str
description: Optional[str] = None
completed: bool = False
class TodoCreate(TodoBase):
pass
class TodoResponse(TodoBase):
id: int
created_at: datetime
updated_at: Optional[datetime] = None
class Config:
orm_mode = True
# Create the FastAPI app
app = FastAPI(
title="Todo List API",
description="A simple Todo List API built with FastAPI",
version="0.1.0",
)
# Configure CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Health endpoint
@app.get("/health", tags=["Health"])
async def health_check():
"""
Health check endpoint to verify the API is running.
"""
return {"status": "healthy"}
# Root endpoint
@app.get("/", tags=["Root"])
async def root():
"""
Root endpoint that redirects to the API documentation.
"""
return {"message": "Welcome to Todo List API. Visit /docs for documentation."}
# Todo API endpoints
@app.post("/todos", response_model=TodoResponse, status_code=status.HTTP_201_CREATED, tags=["Todos"])
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
"""
Create a new todo item.
"""
db_todo = TodoModel(**todo.dict())
db.add(db_todo)
db.commit()
db.refresh(db_todo)
return db_todo
@app.get("/todos", response_model=List[TodoResponse], tags=["Todos"])
def read_todos(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
"""
Get all todo items with pagination.
"""
todos = db.query(TodoModel).offset(skip).limit(limit).all()
return todos
@app.get("/todos/{todo_id}", response_model=TodoResponse, tags=["Todos"])
def read_todo(todo_id: int, db: Session = Depends(get_db)):
"""
Get a specific todo item by ID.
"""
db_todo = db.query(TodoModel).filter(TodoModel.id == todo_id).first()
if db_todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
return db_todo
@app.put("/todos/{todo_id}", response_model=TodoResponse, tags=["Todos"])
def update_todo(todo_id: int, todo: TodoCreate, db: Session = Depends(get_db)):
"""
Update a todo item.
"""
db_todo = db.query(TodoModel).filter(TodoModel.id == todo_id).first()
if db_todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
# Update todo item fields
for key, value in todo.dict().items():
setattr(db_todo, key, value)
db.commit()
db.refresh(db_todo)
return db_todo
@app.delete("/todos/{todo_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None, tags=["Todos"])
def delete_todo(todo_id: int, db: Session = Depends(get_db)):
"""
Delete a todo item.
"""
db_todo = db.query(TodoModel).filter(TodoModel.id == todo_id).first()
if db_todo is None:
raise HTTPException(status_code=404, detail="Todo not found")
db.delete(db_todo)
db.commit()
return None
# For local development
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)