from fastapi import APIRouter, HTTPException, Depends, Path, Response from typing import List, Dict, Any from fastapi import status import inspect import importlib import os from pydantic import BaseModel import logging # Import auth module from modules.security.auth import limiter, getCurrentUser # Import the attribute definition and helper functions from modules.interfaces.serviceAppModel import AttributeDefinition from modules.shared.attributeUtils import getModelClasses # Configure logger logger = logging.getLogger(__name__) # Create a response model for better documentation class AttributeResponse(BaseModel): """Response model for entity attributes""" attributes: List[AttributeDefinition] class Config: schema_extra = { "example": { "attributes": [ { "name": "username", "label": "Username", "type": "string", "required": True, "placeholder": "Please enter username", "editable": True, "visible": True, "order": 0 } ] } } # Create a router for the attribute endpoints router = APIRouter( prefix="/api/attributes", tags=["Attributes"], responses={404: {"description": "Not found"}} ) @router.get("/{entityType}", response_model=AttributeResponse) @limiter.limit("30/minute") async def get_entity_attributes( entityType: str = Path(..., description="Type of entity (e.g. prompt)"), currentUser: Dict[str, Any] = Depends(getCurrentUser) ): """ Retrieves the attribute definitions for a specific entity. This can be used for dynamic form generation. Parameters: - entityType: The type of entity to get attributes for (e.g., 'user', 'prompt') Returns: - A list of attribute definitions that can be used to generate forms """ # Determine preferred language of the user userLanguage = currentUser.get("language", "en") # Get model classes dynamically modelClasses = getModelClasses() # Check if entity type is known if entityType not in modelClasses: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Entity type '{entityType}' not found." ) # Get model class and derive attributes from it modelClass = modelClasses[entityType] attributes = modelClass.getModelAttributeDefinitions() # Return only visible attributes return AttributeResponse(attributes=[attr for attr in attributes if attr.visible]) @router.options("/{entityType}") @limiter.limit("60/minute") async def options_entity_attributes( entityType: str = Path(..., description="Type of entity (e.g. prompt)") ): """Handle OPTIONS request for CORS preflight""" return Response(status_code=200)