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

187 lines
5.3 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),
filter: Optional[str] = Query(None, description="Filter text to match 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 filtering in name and description
- Filtering by active status
- Price range filtering
- Pagination with skip and limit parameters
"""
# If search filter or price filters are provided, use search method
if filter is not None or price_min is not None or price_max is not None:
items = crud.item.search(
db,
filter_text=filter 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 filter text in name and description with additional filters",
)
def search_items(
filter: str = Query(..., description="Filter text to match 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 filtering in name and description (required)
- Filtering by active status
- Price range filtering
- Pagination with skip and limit parameters
"""
items = crud.item.search(
db,
filter_text=filter,
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