gateway/modules/def_attributes.py

123 lines
No EOL
4.4 KiB
Python

from pydantic import BaseModel, Field
from typing import List, Dict, Any, Optional
# Define the model for attribute definitions
class AttributeDefinition(BaseModel):
name: str
label: str
type: str
required: bool = False
placeholder: Optional[str] = None
default_value: Optional[Any] = None
options: Optional[List[Dict[str, Any]]] = None
editable: bool = True
visible: bool = True
order: int = 0
validation: Optional[Dict[str, Any]] = None
help_text: Optional[str] = None
# Helper classes for type mapping
type_mappings = {
"int": "number",
"str": "string",
"float": "number",
"bool": "boolean",
"List[int]": "array",
"List[str]": "array",
"Dict[str, Any]": "object",
"Optional[str]": "string",
"Optional[int]": "number",
"Optional[Dict[str, Any]]": "object"
}
# Special field types based on naming conventions
special_field_types = {
"content": "textarea",
"description": "textarea",
"instructions": "textarea",
"password": "password",
"email": "email",
"workspace_id": "select",
"agent_id": "select",
"type": "select"
}
# Function to convert a Pydantic model into attribute definitions
def get_model_attributes(model_class, user_language="de"):
"""
Converts a Pydantic model into a list of AttributeDefinition objects
"""
attributes = []
# Go through all fields in the model
for i, (field_name, field) in enumerate(model_class.__fields__.items()):
# Skip internal fields
if field_name.startswith('_') or field_name in ["label", "field_labels"]:
continue
# Determine the field type
field_type = type_mappings.get(str(field.type_), "string")
# Check for special field types
if field_name in special_field_types:
field_type = special_field_types[field_name]
# Get the label (if available)
field_label = field_name.replace('_', ' ').capitalize()
if hasattr(model_class, 'field_labels') and field_name in model_class.field_labels:
label_obj = model_class.field_labels[field_name]
field_label = label_obj.get_label(user_language)
# Determine default values and required status
required = field.required
default_value = field.default if not field.required else None
# Check for validation rules
validation = None
if field.validators:
validation = {"has_validators": True}
# Placeholder text
placeholder = f"Please enter {field_label}"
# Special options for Select fields
options = None
if field_type == "select":
if field_name == "type" and model_class.__name__ == "Agent":
options = [
{"value": "Analysis", "label": "Analysis"},
{"value": "Transformation", "label": "Transformation"},
{"value": "Generation", "label": "Generation"},
{"value": "Classification", "label": "Classification"},
{"value": "Custom", "label": "Custom"}
]
# Extract description from Field object
description = None
# Try to get description from various possible sources
if hasattr(field, 'field_info') and hasattr(field.field_info, 'description'):
description = field.field_info.description
elif hasattr(field, 'description'):
description = field.description
elif hasattr(field, 'schema') and hasattr(field.schema, 'description'):
description = field.schema.description
# Create attribute definition
attr_def = AttributeDefinition(
name=field_name,
label=field_label,
type=field_type,
required=required,
placeholder=placeholder,
default_value=default_value,
options=options,
editable=field_name not in ["id", "mandate_id", "user_id", "created_at", "upload_date"],
visible=field_name not in ["hashed_password", "mandate_id", "user_id"],
order=i,
validation=validation,
help_text=description or "" # Set empty string as default value if no description found
)
attributes.append(attr_def)
return attributes