Add priority levels feature to Todo items

- Added priority field (low, medium, high) to Todo model
- Created migration for priority field addition
- Updated API schemas to include priority
- Added filtering by priority in GET todos endpoint
- Updated README to reflect new features
This commit is contained in:
Automated Action 2025-05-16 04:30:03 +00:00
parent 493998c372
commit a05d19017e
5 changed files with 84 additions and 10 deletions

View File

@ -5,6 +5,8 @@ A simple Todo API built with FastAPI and SQLite.
## Features ## Features
- Create, Read, Update, and Delete Todo items - Create, Read, Update, and Delete Todo items
- Priority levels (Low, Medium, High) for todo items
- Filter todo items by priority
- SQLite database with SQLAlchemy ORM - SQLite database with SQLAlchemy ORM
- Database migrations with Alembic - Database migrations with Alembic
- API documentation with Swagger UI and ReDoc - API documentation with Swagger UI and ReDoc
@ -32,10 +34,10 @@ A simple Todo API built with FastAPI and SQLite.
## API Endpoints ## API Endpoints
- `GET /api/todos`: Get all todo items - `GET /api/todos`: Get all todo items (optional query parameter `priority` to filter by priority)
- `POST /api/todos`: Create a new todo item - `POST /api/todos`: Create a new todo item with optional priority level
- `GET /api/todos/{todo_id}`: Get a specific todo item - `GET /api/todos/{todo_id}`: Get a specific todo item
- `PUT /api/todos/{todo_id}`: Update a todo item - `PUT /api/todos/{todo_id}`: Update a todo item (including its priority)
- `DELETE /api/todos/{todo_id}`: Delete a todo item - `DELETE /api/todos/{todo_id}`: Delete a todo item
- `GET /health`: Check application health - `GET /health`: Check application health

View File

@ -1,12 +1,20 @@
from pydantic import BaseModel from pydantic import BaseModel
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
from enum import Enum
class PriorityLevel(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class TodoBase(BaseModel): class TodoBase(BaseModel):
title: str title: str
description: Optional[str] = None description: Optional[str] = None
completed: bool = False completed: bool = False
priority: PriorityLevel = PriorityLevel.MEDIUM
class TodoCreate(TodoBase): class TodoCreate(TodoBase):
@ -17,6 +25,7 @@ class TodoUpdate(BaseModel):
title: Optional[str] = None title: Optional[str] = None
description: Optional[str] = None description: Optional[str] = None
completed: Optional[bool] = None completed: Optional[bool] = None
priority: Optional[PriorityLevel] = None
class TodoResponse(TodoBase): class TodoResponse(TodoBase):

View File

@ -1,8 +1,8 @@
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from typing import List from typing import List, Optional
from app.database.config import get_db from app.database.config import get_db
from app.models.todo import Todo from app.models.todo import Todo, PriorityLevel
from app.api.schemas import TodoCreate, TodoResponse, TodoUpdate from app.api.schemas import TodoCreate, TodoResponse, TodoUpdate
router = APIRouter() router = APIRouter()
@ -19,9 +19,27 @@ def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
@router.get("/", response_model=List[TodoResponse]) @router.get("/", response_model=List[TodoResponse])
def read_todos(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): def read_todos(
"""Get all todo items""" skip: int = 0,
todos = db.query(Todo).offset(skip).limit(limit).all() limit: int = 100,
priority: Optional[PriorityLevel] = Query(
None, description="Filter todos by priority level"
),
db: Session = Depends(get_db),
):
"""
Get all todo items with optional filtering by priority
- **skip**: Number of records to skip
- **limit**: Maximum number of records to return
- **priority**: Optional filter by priority level (low, medium, high)
"""
query = db.query(Todo)
if priority:
query = query.filter(Todo.priority == priority)
todos = query.offset(skip).limit(limit).all()
return todos return todos

View File

@ -1,8 +1,15 @@
from sqlalchemy import Column, Integer, String, Boolean, DateTime from sqlalchemy import Column, Integer, String, Boolean, DateTime, Enum
from sqlalchemy.sql import func from sqlalchemy.sql import func
import enum
from app.database.config import Base from app.database.config import Base
class PriorityLevel(str, enum.Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class Todo(Base): class Todo(Base):
__tablename__ = "todos" __tablename__ = "todos"
@ -10,5 +17,6 @@ class Todo(Base):
title = Column(String, index=True) title = Column(String, index=True)
description = Column(String, nullable=True) description = Column(String, nullable=True)
completed = Column(Boolean, default=False) completed = Column(Boolean, default=False)
priority = Column(Enum(PriorityLevel), default=PriorityLevel.MEDIUM, nullable=False)
created_at = Column(DateTime, default=func.now()) created_at = Column(DateTime, default=func.now())
updated_at = Column(DateTime, default=func.now(), onupdate=func.now()) updated_at = Column(DateTime, default=func.now(), onupdate=func.now())

View File

@ -0,0 +1,37 @@
"""add priority field to todos
Revision ID: 002
Revises: 001
Create Date: 2023-08-21
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "002"
down_revision = "001"
branch_labels = None
depends_on = None
def upgrade():
# Create priority_level enum type
priority_type = sa.Enum("low", "medium", "high", name="prioritylevel")
priority_type.create(op.get_bind())
# Add priority column to todos table with default value of 'medium'
op.add_column(
"todos",
sa.Column("priority", priority_type, nullable=False, server_default="medium"),
)
def downgrade():
# Drop priority column
op.drop_column("todos", "priority")
# Drop the enum type
sa.Enum(name="prioritylevel").drop(op.get_bind())