Add search feature for todos

- Add /api/todos/search endpoint with text search capability
- Implement filtering by completed status
- Include pagination and result count
- Update documentation with new endpoint details

generated with BackendIM... (backend.im)
This commit is contained in:
Automated Action 2025-05-13 00:55:47 +00:00
parent 262bc6c71d
commit 76dc7f1991
3 changed files with 66 additions and 6 deletions

View File

@ -5,6 +5,7 @@ This is a FastAPI application that implements a simple Todo API.
## Features
- Create, read, update, and delete todo items
- Search todos by text query with optional filtering
- Health check endpoint
- SQLite database for data storage
- FastAPI automatic documentation
@ -41,8 +42,23 @@ The server will start at http://localhost:8000
## API Endpoints
- `GET /api/todos`: List all todos
- `GET /api/todos/search`: Search todos by text query
- `POST /api/todos`: Create a new todo
- `GET /api/todos/{todo_id}`: Get a specific todo
- `PUT /api/todos/{todo_id}`: Update a todo
- `DELETE /api/todos/{todo_id}`: Delete a todo
- `GET /health`: Check application health
### Search Endpoint
The search endpoint allows searching todos by text query with additional filters:
```
GET /api/todos/search?q=search_term&completed=true&skip=0&limit=10
```
Parameters:
- `q`: (required) Search text to match in title or description
- `completed`: (optional) Filter by completion status (true/false)
- `skip`: (optional) Number of records to skip for pagination
- `limit`: (optional) Maximum number of records to return

View File

@ -1,10 +1,11 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import List
from typing import List, Optional
from sqlalchemy import or_
from app.database import get_db
from app.models.todo import Todo as TodoModel
from app.schemas.todo import Todo, TodoCreate, TodoUpdate
from app.schemas.todo import Todo, TodoCreate, TodoUpdate, TodoSearchResults
router = APIRouter()
@ -13,6 +14,42 @@ def get_todos(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
todos = db.query(TodoModel).offset(skip).limit(limit).all()
return todos
@router.get("/search", response_model=TodoSearchResults)
def search_todos(
q: str = Query(..., description="Search query string"),
completed: Optional[bool] = Query(None, description="Filter by completion status"),
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db)
):
query = db.query(TodoModel)
# Apply search filter (search in title and description)
query = query.filter(
or_(
TodoModel.title.contains(q),
TodoModel.description.contains(q)
)
)
# Apply completion status filter if provided
if completed is not None:
query = query.filter(TodoModel.completed == completed)
# Count total results
total = query.count()
# Apply pagination
todos = query.offset(skip).limit(limit).all()
return {
"todos": todos,
"total": total,
"skip": skip,
"limit": limit,
"query": q
}
@router.post("/", response_model=Todo, status_code=status.HTTP_201_CREATED)
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
db_todo = TodoModel(**todo.dict())

View File

@ -1,6 +1,6 @@
from pydantic import BaseModel
from datetime import datetime
from typing import Optional
from typing import Optional, List
class TodoBase(BaseModel):
title: str
@ -22,3 +22,10 @@ class Todo(TodoBase):
class Config:
orm_mode = True
class TodoSearchResults(BaseModel):
todos: List[Todo]
total: int
skip: int
limit: int
query: str