gateway/routes/prompts.py
2025-04-21 20:04:22 +02:00

188 lines
No EOL
5.6 KiB
Python

from fastapi import APIRouter, HTTPException, Depends, Body, Query, Path
from typing import List, Dict, Any, Optional
from fastapi import status
from datetime import datetime
from dataclasses import dataclass
# Import auth module
from modules.auth import get_current_active_user, get_user_context
# Import interfaces
from modules.lucydom_interface import get_lucydom_interface
from modules.lucydom_model import Prompt
# Get all attributes of the model (except internal/special attributes)
def get_model_attributes(model_class):
return [attr for attr in dir(model_class)
if not callable(getattr(model_class, attr))
and not attr.startswith('_')
and attr != 'metadata'
and attr != 'query'
and attr != 'query_class'
and attr != 'label'
and attr != 'field_labels']
# Model attributes for Prompt
prompt_attributes = get_model_attributes(Prompt)
@dataclass
class AppContext:
"""Context object for all required connections and user information"""
mandate_id: int
user_id: int
interface_data: Any # LucyDOM Interface
async def get_context(current_user: Dict[str, Any]) -> AppContext:
"""
Creates a central context object with all required interfaces
Args:
current_user: Current user from authentication
Returns:
AppContext object with all required connections
"""
mandate_id, user_id = await get_user_context(current_user)
interface_data = get_lucydom_interface(mandate_id, user_id)
return AppContext(
mandate_id=mandate_id,
user_id=user_id,
interface_data=interface_data
)
# Create router for prompt endpoints
router = APIRouter(
prefix="/api/prompts",
tags=["Prompts"],
responses={404: {"description": "Not found"}}
)
@router.get("", response_model=List[Dict[str, Any]])
async def get_prompts(
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Get all prompts"""
context = await get_context(current_user)
# Retrieve prompts generically
return context.interface_data.get_all_prompts()
@router.post("", response_model=Dict[str, Any])
async def create_prompt(
prompt: Dict[str, Any] = Body(...),
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Create a new prompt"""
context = await get_context(current_user)
# Set attributes from the request dynamically
prompt_data = {}
for attr in prompt_attributes:
if attr in prompt:
prompt_data[attr] = prompt[attr]
# Required fields with default values
content = prompt.get("content", "")
name = prompt.get("name", "New Prompt")
# Create prompt
new_prompt = context.interface_data.create_prompt(
content=content,
name=name
)
# Set current time for created_at if it exists in the model
if "created_at" in prompt_attributes and hasattr(new_prompt, "created_at"):
new_prompt["created_at"] = datetime.now().isoformat()
return new_prompt
@router.get("/{prompt_id}", response_model=Dict[str, Any])
async def get_prompt(
prompt_id: int,
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Get a specific prompt"""
context = await get_context(current_user)
# Get prompt generically
prompt = context.interface_data.get_prompt(prompt_id)
if not prompt:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Prompt with ID {prompt_id} not found"
)
return prompt
@router.put("/{prompt_id}", response_model=Dict[str, Any])
async def update_prompt(
prompt_id: int,
prompt_data: Dict[str, Any] = Body(...),
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Update an existing prompt"""
context = await get_context(current_user)
# Check if the prompt exists
existing_prompt = context.interface_data.get_prompt(prompt_id)
if not existing_prompt:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Prompt with ID {prompt_id} not found"
)
# Filter attributes from the request dynamically
update_data = {}
for attr in prompt_attributes:
if attr in prompt_data:
update_data[attr] = prompt_data[attr]
# Standard fields for update
content = prompt_data.get("content")
name = prompt_data.get("name")
# Update prompt
updated_prompt = context.interface_data.update_prompt(
prompt_id=prompt_id,
content=content,
name=name
)
if not updated_prompt:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Error updating the prompt"
)
return updated_prompt
@router.delete("/{prompt_id}", response_model=Dict[str, Any])
async def delete_prompt(
prompt_id: int,
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Delete a prompt"""
context = await get_context(current_user)
# Check if the prompt exists
existing_prompt = context.interface_data.get_prompt(prompt_id)
if not existing_prompt:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Prompt with ID {prompt_id} not found"
)
success = context.interface_data.delete_prompt(prompt_id)
if not success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Error deleting the prompt"
)
return {"message": f"Prompt with ID {prompt_id} successfully deleted"}