Documentation Index
Fetch the complete documentation index at: https://docs.pyleeai.com/llms.txt
Use this file to discover all available pages before exploring further.
Template Interpolation
Pylee’s template interpolation system provides powerful, flexible string templating capabilities for dynamic configuration generation. This system supports variable substitution, secret handling, and context-aware processing across different environments and use cases.
Overview
Template interpolation in Pylee allows you to:
- Dynamic value substitution: Replace placeholders with actual values at runtime
- Variable and secret integration: Seamlessly incorporate variables and secrets
- Context-aware processing: Different interpolation behavior based on usage context
- Multi-level precedence: Resolve values from organization, registry, and server levels
- Secure secret handling: Maintain security while enabling flexible configuration
Basic Syntax
Template strings use curly braces {} to denote placeholders:
{
"remoteUrl": "https://{HOST}:{PORT}/api/v1",
"environment": {
"API_ENDPOINT": "{PROTOCOL}://{HOST}/api",
"DATABASE_URL": "postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:5432/{DB_NAME}"
}
}
Simple Variable Substitution
{
"template": "Bearer {API_KEY}",
"context": { "API_KEY": "sk-1234567890" },
"result": "Bearer sk-1234567890"
}
Multiple Variables
{
"template": "http://{HOST}:{PORT}/api",
"context": { "HOST": "localhost", "PORT": "3000" },
"result": "http://localhost:3000/api"
}
Variable and Secret Prefixes
Variables
- Prefixed:
{var.VARIABLE_NAME} - Explicitly references a variable
- Unprefixed:
{VARIABLE_NAME} - References a variable or secret (with secrets taking precedence)
Secrets
- Prefixed:
{secret.SECRET_NAME} - Explicitly references a secret
- Unprefixed:
{SECRET_NAME} - References a variable or secret (with secrets taking precedence)
Prefix Examples
{
"templates": {
"explicit_variable": "Database host: {var.DB_HOST}",
"explicit_secret": "API key: {secret.API_KEY}",
"unprefixed": "Token: {AUTH_TOKEN}",
"mixed": "Connect to {var.HOST} with key {secret.API_KEY}"
}
}
Precedence Resolution
Precedence Order
Variables and secrets are resolved in the following order of precedence:
- Server level: Most specific configuration
- Registry level: Shared configuration across servers
- Organization level: Global organizational defaults
Precedence Example
{
"organization": {
"variables": { "API_URL": "https://org.api.com" },
"secrets": { "MASTER_KEY": "org-secret" }
},
"registry": {
"variables": { "API_URL": "https://registry.api.com" },
"secrets": { "SERVICE_KEY": "registry-secret" }
},
"server": {
"variables": { "DEBUG": "true" },
"secrets": { "API_KEY": "server-secret" }
}
}
Template {API_URL} resolves to "https://registry.api.com" (registry overrides organization).
Variable vs Secret Precedence
When both a variable and secret have the same name at the same level, secrets take precedence for unprefixed references:
{
"configuration": {
"variables": { "TOKEN": "var-token" },
"secrets": { "TOKEN": "secret-token" }
},
"templates": {
"unprefixed": "{TOKEN}",
"explicit_var": "{var.TOKEN}",
"explicit_secret": "{secret.TOKEN}"
},
"results": {
"unprefixed": "secret-token",
"explicit_var": "var-token",
"explicit_secret": "secret-token"
}
}
Advanced Features
Default Values
Provide fallback values when variables might be undefined:
{
"templates": {
"with_default": "Port: {PORT:-3000}",
"complex_default": "Database: {DB_URL:-postgresql://localhost:5432/default}"
}
}
Nested Interpolation
Variables can reference other variables:
{
"variables": {
"PROJECT_ROOT": "/opt/myapp",
"DATA_DIR": "{PROJECT_ROOT}/data",
"LOGS_DIR": "{PROJECT_ROOT}/logs"
},
"templates": {
"data_path": "Data stored in {DATA_DIR}",
"log_path": "Logs written to {LOGS_DIR}"
}
}
Complex Template Patterns
{
"templates": {
"api_endpoint": "{PROTOCOL}://{HOST}:{PORT}/api/{VERSION}",
"database_url": "postgresql://{DB_USER}:{secret.DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}",
"auth_header": "Bearer {secret.API_KEY}",
"service_config": "{var.SERVICE_NAME} running on {HOST}:{PORT} (debug: {var.DEBUG})"
}
}
Context-Aware Processing
Display Context
Templates processed for UI display with secrets masked:
{
"template": "API Key: {secret.API_KEY}",
"display_result": "API Key: [redacted]"
}
Copy Context
Templates processed for copying with full values:
{
"template": "export API_KEY={secret.API_KEY}",
"copy_result": "export API_KEY=sk-1234567890abcdef"
}
Execution Context
Templates processed for runtime execution:
{
"template": "docker run -e API_KEY={secret.API_KEY} myapp",
"execution_result": "docker run -e API_KEY=sk-1234567890abcdef myapp"
}
Usage Examples
Basic Configuration
{
"server": {
"variables": {
"HOST": "localhost",
"PORT": "3000",
"PROTOCOL": "http"
},
"secrets": {
"API_KEY": "sk-1234567890abcdef"
}
},
"templates": {
"endpoint": "{PROTOCOL}://{HOST}:{PORT}/api",
"auth": "Bearer {secret.API_KEY}"
},
"results": {
"endpoint": "http://localhost:3000/api",
"auth": "Bearer sk-1234567890abcdef"
}
}
Multi-Environment Configuration
{
"environments": {
"development": {
"variables": {
"HOST": "localhost",
"PORT": "3000",
"DEBUG": "true"
}
},
"production": {
"variables": {
"HOST": "api.production.com",
"PORT": "443",
"DEBUG": "false"
}
}
},
"templates": {
"api_url": "https://{HOST}:{PORT}/api",
"debug_mode": "Debug enabled: {DEBUG}"
}
}
Database Configuration
{
"database": {
"variables": {
"DB_HOST": "localhost",
"DB_PORT": "5432",
"DB_NAME": "myapp"
},
"secrets": {
"DB_USER": "admin",
"DB_PASSWORD": "secret123"
}
},
"templates": {
"connection_string": "postgresql://{secret.DB_USER}:{secret.DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}",
"host_info": "Database host: {DB_HOST}:{DB_PORT}"
}
}
Service Configuration
{
"service": {
"variables": {
"SERVICE_NAME": "user-service",
"VERSION": "v1.2.3",
"ENVIRONMENT": "production"
},
"secrets": {
"JWT_SECRET": "jwt-secret-key",
"DATABASE_URL": "postgresql://user:pass@host:5432/db"
}
},
"templates": {
"service_info": "{SERVICE_NAME} {VERSION} running in {ENVIRONMENT}",
"jwt_config": "JWT secret: {secret.JWT_SECRET}",
"database_config": "Database: {secret.DATABASE_URL}"
}
}
Integration with Pylee Components
The ConnectButton component uses template interpolation for dynamic configuration:
{
"connectButton": {
"remote": {
"url": "https://{HOST}:{PORT}/mcp",
"headers": {
"Authorization": "Bearer {secret.API_KEY}",
"X-Service-Version": "{var.VERSION}"
}
},
"package": {
"name": "{var.PACKAGE_NAME}",
"version": "{var.PACKAGE_VERSION}",
"args": ["--host", "{HOST}", "--port", "{PORT}"]
}
}
}
Environment Variable Generation
{
"environmentVariables": {
"API_ENDPOINT": "{PROTOCOL}://{HOST}:{PORT}/api",
"DATABASE_URL": "postgresql://{DB_USER}:{secret.DB_PASSWORD}@{DB_HOST}:5432/{DB_NAME}",
"SERVICE_NAME": "{var.SERVICE_NAME}",
"DEBUG_MODE": "{var.DEBUG}",
"SECRET_KEY": "{secret.APP_SECRET}"
}
}
Command Generation
{
"commands": {
"docker_run": "docker run -e API_KEY={secret.API_KEY} -e DEBUG={var.DEBUG} {var.IMAGE_NAME}",
"npm_start": "npm start -- --host {HOST} --port {PORT}",
"python_app": "python app.py --config {var.CONFIG_FILE} --env {var.ENVIRONMENT}"
}
}
Error Handling
Missing Variables
If a template variable is not found, the placeholder is left unchanged:
{
"template": "Bearer {UNKNOWN_KEY}",
"result": "Bearer {UNKNOWN_KEY}"
}
Malformed templates are left unchanged:
{
"templates": {
"malformed1": "{{VARIABLE}",
"malformed2": "{VARIABLE}}",
"malformed3": "{{VARIABLE}}"
},
"results": {
"malformed1": "{{VARIABLE}",
"malformed2": "{VARIABLE}}",
"malformed3": "{{VARIABLE}}"
}
}
Non-String Values
Non-string values are converted to strings:
{
"variables": {
"PORT": 3000,
"DEBUG": true,
"VERSION": 1.2
},
"templates": {
"port": "Port: {PORT}",
"debug": "Debug: {DEBUG}",
"version": "Version: {VERSION}"
},
"results": {
"port": "Port: 3000",
"debug": "Debug: true",
"version": "Version: 1.2"
}
}
Template Compilation
- Templates are compiled once and cached
- Use template caching for frequently used patterns
- Avoid complex nested interpolation chains
Memory Management
- Clean up unused template contexts
- Use weak references for large template sets
- Monitor memory usage with many templates
Optimization Strategies
{
"optimization": {
"caching": {
"enabled": true,
"maxCacheSize": 1000,
"ttl": 3600
},
"compilation": {
"precompile": true,
"validateOnCompile": true
}
}
}
Security Considerations
Secret Exposure Prevention
- Never log interpolated templates containing secrets
- Use context-appropriate secret handling
- Implement proper access controls
Template Injection Prevention
- Validate template syntax before processing
- Sanitize user-provided template strings
- Limit template complexity to prevent DoS
Secure Practices
{
"security": {
"templateValidation": {
"enabled": true,
"allowedPrefixes": ["var", "secret"],
"maxTemplateLength": 1000,
"maxNestingDepth": 5
},
"secretHandling": {
"maskInLogs": true,
"contextAware": true,
"auditAccess": true
}
}
}
Testing Templates
Unit Testing
{
"tests": [
{
"name": "basic_interpolation",
"template": "Hello {NAME}",
"context": { "NAME": "World" },
"expected": "Hello World"
},
{
"name": "secret_handling",
"template": "API Key: {secret.API_KEY}",
"context": { "secret.API_KEY": "sk-123" },
"expected": "API Key: sk-123"
},
{
"name": "precedence_test",
"template": "{VALUE}",
"context": {
"VALUE": "org-value",
"secret.VALUE": "secret-value"
},
"expected": "secret-value"
}
]
}
Integration Testing
{
"integrationTests": {
"connectButton": {
"template": "https://{HOST}/api?key={secret.API_KEY}",
"contexts": ["display", "copy", "execution"],
"expectations": {
"display": "https://localhost/api?key=[redacted]",
"copy": "https://localhost/api?key=sk-123",
"execution": "https://localhost/api?key=sk-123"
}
}
}
}
Migration Guide
From Legacy Template System
When migrating from older template systems:
{
"migration": {
"oldFormat": "${{ secrets.API_KEY }}",
"newFormat": "{secret.API_KEY}",
"steps": [
"Identify all template strings",
"Convert syntax to new format",
"Update variable/secret references",
"Test in all contexts",
"Validate security handling"
]
}
}
{
"migrationTool": {
"patterns": [
{
"from": "\\$\\{\\{\\s*secrets\\.([^}]+)\\s*\\}\\}",
"to": "{secret.$1}"
},
{
"from": "\\$\\{\\{\\s*vars\\.([^}]+)\\s*\\}\\}",
"to": "{var.$1}"
},
{
"from": "\\$\\{\\{\\s*([^}]+)\\s*\\}\\}",
"to": "{$1}"
}
]
}
}
Troubleshooting
Common Issues
Template Not Resolving
Template: "Bearer {API_KEY}"
Result: "Bearer {API_KEY}"
Solutions:
- Check variable exists in context
- Verify correct prefix usage
- Ensure proper precedence setup
Incorrect Precedence
Expected: "production-value"
Actual: "development-value"
Solutions:
- Review precedence configuration
- Check variable/secret levels
- Verify context processing
Secret Exposure
Display shows: "Bearer sk-1234567890abcdef"
Expected: "Bearer [redacted]"
Solutions:
- Check context configuration
- Verify secret handling rules
- Review component implementation
{
"debug": {
"templateInterpolation": {
"enabled": true,
"logResolution": true,
"logContext": true,
"logPrecedence": true
}
}
}
Best Practices
Template Design
- Use descriptive variable names
- Keep templates readable and maintainable
- Avoid overly complex nested interpolation
- Document template usage and dependencies
Variable Management
- Use consistent naming conventions
- Group related variables logically
- Implement proper validation
- Document variable purposes
Security
- Never expose secrets in display contexts
- Use appropriate prefixes for clarity
- Implement proper access controls
- Regular security audits
- Cache compiled templates
- Minimize template complexity
- Use efficient variable lookups
- Monitor performance metrics
Next Steps