diff --git a/spoolman/api/v1/other.py b/spoolman/api/v1/other.py new file mode 100644 index 0000000..b0bdb84 --- /dev/null +++ b/spoolman/api/v1/other.py @@ -0,0 +1,125 @@ +"""Filament related endpoints.""" + +import logging +from typing import Annotated + +from fastapi import APIRouter, Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from spoolman.database import filament, spool +from spoolman.database.database import get_db_session + +logger = logging.getLogger(__name__) + +router = APIRouter( + prefix="", + tags=["other"], +) + +# ruff: noqa: D103, B008 + + +@router.get( + "/material", + name="Find materials", + description="Get a list of all filament materials.", + response_model_exclude_none=True, + responses={ + 200: { + "description": "A list of all filament materials.", + "content": { + "application/json": { + "example": [ + "PLA", + "ABS", + "PETG", + ], + }, + }, + }, + }, +) +async def find_materials( + *, + db: Annotated[AsyncSession, Depends(get_db_session)], +) -> list[str]: + return await filament.find_materials(db=db) + + +@router.get( + "/article-number", + name="Find article numbers", + description="Get a list of all article numbers.", + response_model_exclude_none=True, + responses={ + 200: { + "description": "A list of all article numbers.", + "content": { + "application/json": { + "example": [ + "123456", + "987654", + ], + }, + }, + }, + }, +) +async def find_article_numbers( + *, + db: Annotated[AsyncSession, Depends(get_db_session)], +) -> list[str]: + return await filament.find_article_numbers(db=db) + + +@router.get( + "/lot-number", + name="Find lot numbers", + description="Get a list of all lot numbers.", + response_model_exclude_none=True, + responses={ + 200: { + "description": "A list of all lot numbers.", + "content": { + "application/json": { + "example": [ + "123456", + "987654", + ], + }, + }, + }, + }, +) +async def find_lot_numbers( + *, + db: Annotated[AsyncSession, Depends(get_db_session)], +) -> list[str]: + return await spool.find_lot_numbers(db=db) + + +@router.get( + "/locations", + name="Find locations", + description="Get a list of all spool locations.", + response_model_exclude_none=True, + responses={ + 200: { + "description": "A list of all spool locations.", + "content": { + "application/json": { + "example": [ + "Printer 1", + "Printer 2", + "Storage Shelf A", + ], + }, + }, + }, + }, +) +async def find_locations( + *, + db: Annotated[AsyncSession, Depends(get_db_session)], +) -> list[str]: + return await spool.find_locations(db=db) diff --git a/spoolman/api/v1/router.py b/spoolman/api/v1/router.py index cbeeb8c..00e8f05 100644 --- a/spoolman/api/v1/router.py +++ b/spoolman/api/v1/router.py @@ -13,14 +13,13 @@ from spoolman import env from spoolman.database.database import backup_global_db from spoolman.exceptions import ItemNotFoundError -from . import filament, models, spool, vendor +from . import filament, models, other, spool, vendor logger = logging.getLogger(__name__) app = FastAPI( title="Spoolman REST API v1", version="1.0.0", - root_path_in_servers=False, ) @@ -76,3 +75,4 @@ async def backup(): # noqa: ANN201 app.include_router(filament.router) app.include_router(spool.router) app.include_router(vendor.router) +app.include_router(other.router) diff --git a/spoolman/database/filament.py b/spoolman/database/filament.py index 0376b28..0f6b1e6 100644 --- a/spoolman/database/filament.py +++ b/spoolman/database/filament.py @@ -1,5 +1,6 @@ """Helper functions for interacting with filament database objects.""" +import logging from typing import Optional from sqlalchemy import select @@ -143,3 +144,26 @@ async def delete(db: AsyncSession, filament_id: int) -> None: except IntegrityError as exc: await db.rollback() raise ItemDeleteError("Failed to delete filament.") from exc + + +logger = logging.getLogger(__name__) + + +async def find_materials( + *, + db: AsyncSession, +) -> list[str]: + """Find a list of filament materials by searching for distinct values in the filament table.""" + stmt = select(models.Filament.material).distinct() + rows = await db.execute(stmt) + return [row[0] for row in rows.all() if row[0] is not None] + + +async def find_article_numbers( + *, + db: AsyncSession, +) -> list[str]: + """Find a list of filament article numbers by searching for distinct values in the filament table.""" + stmt = select(models.Filament.article_number).distinct() + rows = await db.execute(stmt) + return [row[0] for row in rows.all() if row[0] is not None] diff --git a/spoolman/database/spool.py b/spoolman/database/spool.py index ab14a04..2d5fbd2 100644 --- a/spoolman/database/spool.py +++ b/spoolman/database/spool.py @@ -257,3 +257,23 @@ async def use_length(db: AsyncSession, spool_id: int, length: float) -> models.S await db.commit() return spool + + +async def find_locations( + *, + db: AsyncSession, +) -> list[str]: + """Find a list of spool locations by searching for distinct values in the spool table.""" + stmt = sqlalchemy.select(models.Spool.location).distinct() + rows = await db.execute(stmt) + return [row[0] for row in rows.all() if row[0] is not None] + + +async def find_lot_numbers( + *, + db: AsyncSession, +) -> list[str]: + """Find a list of spool lot numbers by searching for distinct values in the spool table.""" + stmt = sqlalchemy.select(models.Spool.lot_nr).distinct() + rows = await db.execute(stmt) + return [row[0] for row in rows.all() if row[0] is not None]