Added custom extra fields to backend

No integration tests yet, TBD
This commit is contained in:
Donkie
2024-01-06 16:22:35 +01:00
parent 71c29d2467
commit 77ac9d6a5c
14 changed files with 556 additions and 25 deletions

98
spoolman/api/v1/field.py Normal file
View File

@@ -0,0 +1,98 @@
"""Vendor related endpoints."""
import logging
from typing import Annotated, Union
from fastapi import APIRouter, Depends, Path
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession
from spoolman.api.v1.models import Message
from spoolman.database.database import get_db_session
from spoolman.exceptions import ItemNotFoundError
from spoolman.extra_fields import (
EntityType,
ExtraField,
ExtraFieldParameters,
add_or_update_extra_field,
delete_extra_field,
get_extra_fields,
)
router = APIRouter(
prefix="/field",
tags=["field"],
)
# ruff: noqa: D103,B008
logger = logging.getLogger(__name__)
@router.get(
"/{entity_type}",
name="Get extra fields",
description="Get all extra fields for a specific entity type.",
response_model_exclude_none=True,
)
async def get(
db: Annotated[AsyncSession, Depends(get_db_session)],
entity_type: Annotated[EntityType, Path(description="Entity type this field is for")],
) -> list[ExtraField]:
return await get_extra_fields(db, entity_type)
@router.post(
"/{entity_type}/{key}",
name="Add or update extra field",
description=(
"Add or update an extra field for a specific entity type. "
"Returns the full list of extra fields for the entity type."
),
response_model_exclude_none=True,
response_model=list[ExtraField],
responses={400: {"model": Message}},
)
async def update(
db: Annotated[AsyncSession, Depends(get_db_session)],
entity_type: Annotated[EntityType, Path(description="Entity type this field is for")],
key: Annotated[str, Path(min_length=1, max_length=64, regex="^[a-z0-9_]+$")],
body: ExtraFieldParameters,
) -> Union[list[ExtraField], JSONResponse]:
body_with_key = ExtraField.parse_obj(body.copy(update={"key": key}))
try:
await add_or_update_extra_field(db, entity_type, body_with_key)
except ValueError as e:
return JSONResponse(status_code=400, content=Message(message=str(e)).dict())
return await get_extra_fields(db, entity_type)
@router.delete(
"/{entity_type}/{key}",
name="Delete extra field",
description=(
"Delete an extra field for a specific entity type. "
"Returns the full list of extra fields for the entity type."
),
response_model_exclude_none=True,
response_model=list[ExtraField],
responses={404: {"model": Message}},
)
async def delete(
db: Annotated[AsyncSession, Depends(get_db_session)],
entity_type: Annotated[EntityType, Path(description="Entity type this field is for")],
key: Annotated[str, Path(min_length=1, max_length=64, regex="^[a-z0-9_]+$")],
) -> Union[list[ExtraField], JSONResponse]:
try:
await delete_extra_field(db, entity_type, key)
except ItemNotFoundError:
return JSONResponse(
status_code=404,
content=Message(
message=f"Extra field with key {key} does not exist for entity type {entity_type.name}",
).dict(),
)
return await get_extra_fields(db, entity_type)