6.5 KiB
Frontend Options Usage Guide
Overview
The frontend_options attribute in Pydantic Field definitions supports two formats for providing options to frontend select/multiselect fields:
- Static List: Predefined list of options
- String Reference: Dynamic options fetched from the Options API
Type System
The type system is defined in gateway/modules/shared/frontendOptionsTypes.py:
from modules.shared.frontendOptionsTypes import FrontendOptions, OptionItem
# FrontendOptions is Union[List[OptionItem], str]
# OptionItem is Dict[str, Any] with "value" and "label" keys
Format 1: Static List
Use static lists for fixed, predefined options that don't change based on user context.
Example
from pydantic import Field
from typing import List
language: str = Field(
default="en",
description="Preferred language",
json_schema_extra={
"frontend_type": "select",
"frontend_readonly": False,
"frontend_required": True,
"frontend_options": [
{"value": "en", "label": {"en": "English", "fr": "Anglais"}},
{"value": "fr", "label": {"en": "Français", "fr": "Français"}},
{"value": "de", "label": {"en": "Deutsch", "fr": "Allemand"}},
]
}
)
When to Use Static Lists
- Options are fixed constants (e.g., enum values)
- Options don't require database queries
- Options are the same for all users
- Options are simple and don't change frequently
Format 2: String Reference
Use string references for dynamic options that come from the database or are context-aware.
Example
from pydantic import Field
from typing import List
roleLabels: List[str] = Field(
default_factory=list,
description="List of role labels",
json_schema_extra={
"frontend_type": "multiselect",
"frontend_readonly": False,
"frontend_required": True,
"frontend_options": "user.role" # String reference
}
)
When to Use String References
- Options come from the database (e.g., user connections)
- Options are context-aware (filtered by current user's permissions)
- Options need centralized management
- Options may change frequently
- Options depend on user context or permissions
Frontend Integration
When the frontend encounters a string reference:
- Detect: Check if
frontend_optionsis a string (not a list) - Fetch: Call
GET /api/options/{optionsName}(e.g.,/api/options/user.role) - Use: Use the returned options for the select/multiselect field
Example Frontend Code:
// Pseudocode
if (typeof field.frontend_options === 'string') {
// Dynamic options - fetch from API
const options = await fetch(`/api/options/${field.frontend_options}`);
return options;
} else {
// Static options - use directly
return field.frontend_options;
}
Available Option Names
| Option Name | Description | Context-Aware |
|---|---|---|
user.role |
Standard role options (sysadmin, admin, user, viewer) | No |
auth.authority |
Authentication authority options (local, google, msft) | No |
connection.status |
Connection status options (active, inactive, expired, error) | No |
user.connection |
User's connections (fetched from database) | Yes (requires currentUser) |
Utility Functions
The frontendOptionsTypes module provides utility functions:
from modules.shared.frontendOptionsTypes import (
isStringReference,
isStaticList,
validateFrontendOptions,
getOptionsName,
getStaticOptions
)
# Check format
if isStringReference(frontend_options):
optionsName = getOptionsName(frontend_options)
# Fetch from API: /api/options/{optionsName}
elif isStaticList(frontend_options):
options = getStaticOptions(frontend_options)
# Use directly
# Validate format
if not validateFrontendOptions(frontend_options):
raise ValueError("Invalid frontend_options format")
Validation
The validateFrontendOptions() function ensures:
- String References: Non-empty string
- Static Lists:
- List of dictionaries
- Each dictionary has
"value"and"label"keys "label"is a dictionary (multilingual labels)
Examples in Codebase
Static List Example
# datamodelUam.py - Language field
language: str = Field(
default="en",
json_schema_extra={
"frontend_options": [
{"value": "en", "label": {"en": "English", "fr": "Anglais"}},
{"value": "fr", "label": {"en": "Français", "fr": "Français"}},
]
}
)
String Reference Example
# datamodelUam.py - Role labels field
roleLabels: List[str] = Field(
default_factory=list,
json_schema_extra={
"frontend_options": "user.role" # Dynamic - fetched from API
}
)
Mixed Example
# datamodelRbac.py - AccessRule model
roleLabel: str = Field(
json_schema_extra={
"frontend_options": "user.role" # String reference
}
)
context: AccessRuleContext = Field(
json_schema_extra={
"frontend_options": [ # Static list
{"value": "DATA", "label": {"en": "Data", "fr": "Données"}},
{"value": "UI", "label": {"en": "UI", "fr": "Interface"}},
{"value": "RESOURCE", "label": {"en": "Resource", "fr": "Ressource"}}
]
}
)
Best Practices
-
Use Static Lists for:
- Enum values
- Fixed constants
- Simple options that don't change
-
Use String References for:
- Database-driven options
- Context-aware options
- Options that need centralized management
-
Always validate frontend_options format when processing
-
Document which format is used and why in field descriptions
-
Frontend: Always check the type before using options
Migration Guide
If you have existing static lists that should become dynamic:
- Create Options Provider: Add option logic to
gateway/modules/features/options/mainOptions.py - Register Option Name: Add to
getAvailableOptionsNames()function - Update Field: Change
frontend_optionsfrom list to string reference - Update Frontend: Ensure frontend handles string references correctly
See Also
gateway/modules/shared/frontendOptionsTypes.py- Type definitions and utilitiesgateway/modules/features/options/mainOptions.py- Options API implementationgateway/modules/routes/routeOptions.py- Options API endpointswiki/appdoc/doc_security_role_based_access.md- RBAC documentation with frontend_options examples