2025-05-17 16:27:27 +00:00

187 lines
5.2 KiB
Python

from typing import Any, List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from app import crud, schemas
from app.database.session import get_db
router = APIRouter()
@router.get(
"/",
response_model=List[schemas.Item],
status_code=status.HTTP_200_OK,
summary="Get all items",
description="Retrieve all items with pagination, filtering, and search options",
)
def read_items(
db: Session = Depends(get_db),
query: Optional[str] = Query(None, description="Search text in name and description"),
active: Optional[bool] = Query(None, description="Filter by active status"),
price_min: Optional[int] = Query(None, description="Minimum price in cents"),
price_max: Optional[int] = Query(None, description="Maximum price in cents"),
skip: int = Query(0, description="Number of records to skip"),
limit: int = Query(100, description="Maximum number of records to return"),
) -> Any:
"""
Retrieve items with support for:
- Text search in name and description
- Filtering by active status
- Price range filtering
- Pagination with skip and limit parameters
"""
# If search query or price filters are provided, use search method
if query is not None or price_min is not None or price_max is not None:
items = crud.item.search(
db,
query=query or "",
skip=skip,
limit=limit,
active=active,
price_min=price_min,
price_max=price_max
)
# Otherwise use existing methods
elif active is not None:
items = crud.item.get_multi_by_active(db, active=active, skip=skip, limit=limit)
else:
items = crud.item.get_multi(db, skip=skip, limit=limit)
return items
@router.get(
"/search",
response_model=List[schemas.Item],
status_code=status.HTTP_200_OK,
summary="Search items",
description="Search for items by query text in name and description with additional filters",
)
def search_items(
query: str = Query(..., description="Search text in name and description"),
db: Session = Depends(get_db),
active: Optional[bool] = Query(None, description="Filter by active status"),
price_min: Optional[int] = Query(None, description="Minimum price in cents"),
price_max: Optional[int] = Query(None, description="Maximum price in cents"),
skip: int = Query(0, description="Number of records to skip"),
limit: int = Query(100, description="Maximum number of records to return"),
) -> Any:
"""
Search for items with support for:
- Text search in name and description (required)
- Filtering by active status
- Price range filtering
- Pagination with skip and limit parameters
"""
items = crud.item.search(
db,
query=query,
skip=skip,
limit=limit,
active=active,
price_min=price_min,
price_max=price_max
)
return items
@router.get(
"/{item_id}",
response_model=schemas.Item,
status_code=status.HTTP_200_OK,
summary="Get an item by ID",
description="Get a specific item by its ID",
)
def read_item(
*,
db: Session = Depends(get_db),
item_id: int,
) -> Any:
"""
Get an item by ID.
"""
item = crud.item.get(db=db, id=item_id)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
return item
@router.post(
"/",
response_model=schemas.Item,
status_code=status.HTTP_201_CREATED,
summary="Create a new item",
description="Create a new item with the provided data",
)
def create_item(
*,
db: Session = Depends(get_db),
item_in: schemas.ItemCreate,
) -> Any:
"""
Create a new item.
"""
item = crud.item.get_by_name(db=db, name=item_in.name)
if item:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"An item with the name '{item_in.name}' already exists",
)
item = crud.item.create(db=db, obj_in=item_in)
return item
@router.put(
"/{item_id}",
response_model=schemas.Item,
status_code=status.HTTP_200_OK,
summary="Update an item",
description="Update an item with the provided data",
)
def update_item(
*,
db: Session = Depends(get_db),
item_id: int,
item_in: schemas.ItemUpdate,
) -> Any:
"""
Update an item.
"""
item = crud.item.get(db=db, id=item_id)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
item = crud.item.update(db=db, db_obj=item, obj_in=item_in)
return item
@router.delete(
"/{item_id}",
status_code=status.HTTP_204_NO_CONTENT,
response_model=None,
summary="Delete an item",
description="Delete an item by its ID",
)
def delete_item(
*,
db: Session = Depends(get_db),
item_id: int,
) -> None:
"""
Delete an item.
"""
item = crud.item.get(db=db, id=item_id)
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found",
)
crud.item.remove(db=db, id=item_id)
return None