gateway/modules/routes/routeDataPrompts.py
2026-01-11 15:12:16 +01:00

180 lines
No EOL
6.2 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
from fastapi import APIRouter, HTTPException, Depends, Body, Path, Request, Query
from typing import List, Dict, Any, Optional
from fastapi import status
import logging
import json
# Import auth module
from modules.auth import limiter, getCurrentUser
# Import interfaces
import modules.interfaces.interfaceDbComponentObjects as interfaceDbComponentObjects
from modules.datamodels.datamodelUtils import Prompt
from modules.datamodels.datamodelUam import User
from modules.datamodels.datamodelPagination import PaginationParams, PaginatedResponse, PaginationMetadata, normalize_pagination_dict
# Configure logger
logger = logging.getLogger(__name__)
# Create router for prompt endpoints
router = APIRouter(
prefix="/api/prompts",
tags=["Manage Prompts"],
responses={404: {"description": "Not found"}}
)
@router.get("", response_model=PaginatedResponse[Prompt])
@limiter.limit("30/minute")
async def get_prompts(
request: Request,
pagination: Optional[str] = Query(None, description="JSON-encoded PaginationParams object"),
currentUser: User = Depends(getCurrentUser)
) -> PaginatedResponse[Prompt]:
"""
Get prompts with optional pagination, sorting, and filtering.
Query Parameters:
- pagination: JSON-encoded PaginationParams object, or None for no pagination
Examples:
- GET /api/prompts (no pagination - returns all items)
- GET /api/prompts?pagination={"page":1,"pageSize":10,"sort":[]}
- GET /api/prompts?pagination={"page":2,"pageSize":20,"sort":[{"field":"name","direction":"asc"}]}
"""
# Parse pagination parameter
paginationParams = None
if pagination:
try:
paginationDict = json.loads(pagination)
if paginationDict:
# Normalize pagination dict (handles top-level "search" field)
paginationDict = normalize_pagination_dict(paginationDict)
paginationParams = PaginationParams(**paginationDict)
except (json.JSONDecodeError, ValueError) as e:
raise HTTPException(
status_code=400,
detail=f"Invalid pagination parameter: {str(e)}"
)
managementInterface = interfaceDbComponentObjects.getInterface(currentUser)
result = managementInterface.getAllPrompts(pagination=paginationParams)
# If pagination was requested, result is PaginatedResult
# If no pagination, result is List[Prompt]
if paginationParams:
return PaginatedResponse(
items=result.items,
pagination=PaginationMetadata(
currentPage=paginationParams.page,
pageSize=paginationParams.pageSize,
totalItems=result.totalItems,
totalPages=result.totalPages,
sort=paginationParams.sort,
filters=paginationParams.filters
)
)
else:
return PaginatedResponse(
items=result,
pagination=None
)
@router.post("", response_model=Prompt)
@limiter.limit("10/minute")
async def create_prompt(
request: Request,
prompt: Prompt,
currentUser: User = Depends(getCurrentUser)
) -> Prompt:
"""Create a new prompt"""
managementInterface = interfaceDbComponentObjects.getInterface(currentUser)
# Create prompt
newPrompt = managementInterface.createPrompt(prompt)
return Prompt(**newPrompt)
@router.get("/{promptId}", response_model=Prompt)
@limiter.limit("30/minute")
async def get_prompt(
request: Request,
promptId: str = Path(..., description="ID of the prompt"),
currentUser: User = Depends(getCurrentUser)
) -> Prompt:
"""Get a specific prompt"""
managementInterface = interfaceDbComponentObjects.getInterface(currentUser)
# Get prompt
prompt = managementInterface.getPrompt(promptId)
if not prompt:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Prompt with ID {promptId} not found"
)
return prompt
@router.put("/{promptId}", response_model=Prompt)
@limiter.limit("10/minute")
async def update_prompt(
request: Request,
promptId: str = Path(..., description="ID of the prompt to update"),
promptData: Prompt = Body(...),
currentUser: User = Depends(getCurrentUser)
) -> Prompt:
"""Update an existing prompt"""
managementInterface = interfaceDbComponentObjects.getInterface(currentUser)
# Check if the prompt exists
existingPrompt = managementInterface.getPrompt(promptId)
if not existingPrompt:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Prompt with ID {promptId} not found"
)
# Convert Prompt to dict for interface, excluding the id field
if hasattr(promptData, "model_dump"):
update_data = promptData.model_dump(exclude={"id"})
else:
update_data = promptData.model_dump(exclude={"id"})
# Update prompt
updatedPrompt = managementInterface.updatePrompt(promptId, update_data)
if not updatedPrompt:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Error updating the prompt"
)
return Prompt(**updatedPrompt)
@router.delete("/{promptId}", response_model=Dict[str, Any])
@limiter.limit("10/minute")
async def delete_prompt(
request: Request,
promptId: str = Path(..., description="ID of the prompt to delete"),
currentUser: User = Depends(getCurrentUser)
) -> Dict[str, Any]:
"""Delete a prompt"""
managementInterface = interfaceDbComponentObjects.getInterface(currentUser)
# Check if the prompt exists
existingPrompt = managementInterface.getPrompt(promptId)
if not existingPrompt:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Prompt with ID {promptId} not found"
)
success = managementInterface.deletePrompt(promptId)
if not success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Error deleting the prompt"
)
return {"message": f"Prompt with ID {promptId} successfully deleted"}