or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assets.mdattachments.mdconfiguration.mdcore-notifications.mdindex.mdlocalization.mdplugin-system.mdstorage.md
tile.json

configuration.mddocs/

Configuration Management

Configuration loading and management from files, URLs, and various formats. AppriseConfig enables centralized configuration of notification services, supporting multiple configuration formats including YAML and text-based formats for flexible deployment scenarios.

Capabilities

AppriseConfig Class

Manages configuration loading from various sources including local files, remote URLs, and direct strings. Supports configuration caching, recursive includes, and multiple formats.

class AppriseConfig:
    def __init__(self, paths=None, asset=None, cache=True, recursion=0, insecure_includes=False, location=None):
        """
        Initialize configuration manager.
        
        Parameters:
        - paths (str|list, optional): Configuration file paths or URLs
        - asset (AppriseAsset, optional): Asset configuration
        - cache (bool): Enable configuration caching
        - recursion (int): Maximum recursion depth for includes
        - insecure_includes (bool): Allow insecure includes (http://)
        - location (str, optional): Base location for relative paths
        """

    def add(self, configs, asset=None, tag=None, cache=None, recursion=None, insecure_includes=None):
        """
        Add configuration source(s) to the manager.
        
        Parameters:
        - configs (str|list): Configuration paths, URLs, or strings
        - asset (AppriseAsset, optional): Asset configuration for loaded services
        - tag (str|list, optional): Tags to assign to loaded services
        - cache (bool, optional): Override default caching behavior
        - recursion (int, optional): Override recursion depth
        - insecure_includes (bool, optional): Override insecure includes setting
        
        Returns:
        bool: True if at least one configuration was successfully loaded
        """

    def clear(self):
        """
        Remove all loaded configurations.
        """

    def pop(self, index=-1):
        """
        Remove and return configuration by index.
        
        Parameters:
        - index (int): Index of configuration to remove (-1 for last)
        
        Returns:
        ConfigBase: Removed configuration object
        """

    def servers(self, tag=None):
        """
        Get notification servers from all loaded configurations.
        
        Parameters:
        - tag (str|list, optional): Filter servers by tags
        
        Returns:
        list: NotifyBase objects from all configurations
        """

    def urls(self, privacy=False, tag=None):
        """
        Get URLs for all configuration sources.
        
        Parameters:
        - privacy (bool): Mask sensitive information in URLs
        - tag (str|list, optional): Filter by tags
        
        Returns:
        list: List of configuration URLs
        """

    @property
    def configs(self):
        """
        List of loaded configuration objects.
        
        Returns:
        list: ConfigBase objects for all loaded configurations
        """

    @property
    def cache(self):
        """
        Configuration caching status.
        
        Returns:
        bool: True if caching is enabled
        """

ConfigBase Class

Base class for configuration loaders supporting different formats and sources.

class ConfigBase(URLBase):
    def read(self, fmt=ConfigFormat.TEXT, **kwargs):
        """
        Read configuration content.
        
        Parameters:
        - fmt (ConfigFormat): Configuration format (TEXT or YAML)
        - **kwargs: Format-specific options
        
        Returns:
        str: Configuration content
        """

    def parse_url(self, url, verify_host=True):
        """
        Parse configuration URL into components.
        
        Parameters:
        - url (str): Configuration URL to parse
        - verify_host (bool): Verify host accessibility
        
        Returns:
        dict: Parsed URL components
        """

    @property
    def config_format(self):
        """
        Configuration format for this loader.
        
        Returns:
        ConfigFormat: Format supported by this loader
        """

    @property
    def default_config_format(self):
        """
        Default configuration format.
        
        Returns:
        ConfigFormat: Default format for new configurations
        """

ConfigurationManager Class

Singleton manager for configuration plugin discovery and loading.

class ConfigurationManager:
    def load_modules(self, path=None, name=None):
        """
        Load configuration plugin modules.
        
        Parameters:
        - path (str, optional): Path to plugin directory
        - name (str, optional): Specific plugin name to load
        
        Returns:
        bool: True if modules were loaded successfully
        """

    def plugins(self):
        """
        Get available configuration plugins.
        
        Returns:
        dict: Available configuration plugin classes
        """

    def schemas(self):
        """
        Get supported configuration URL schemas.
        
        Returns:
        list: Supported URL schemas for configurations
        """

Configuration Formats

Text Format

Simple text format with one service URL per line, supporting comments and basic formatting.

# Email notifications
mailto://user:password@gmail.com

# Slack notifications  
slack://TokenA/TokenB/TokenC/Channel

# Discord webhook
discord://webhook_id/webhook_token

# SMS via Twilio
twilio://AccountSid:AuthToken@PhoneNo

YAML Format

Structured YAML format supporting complex configurations, includes, and metadata.

# apprise.yml
version: 1

# Global asset configuration
asset:
  app_id: MyApp
  app_desc: "My Application Notifications"

# URL definitions
urls:
  - mailto://user:password@gmail.com:
      - tag: email, admin
      - format: html

  - slack://TokenA/TokenB/TokenC/Channel:
      - tag: team, alerts

  - discord://webhook_id/webhook_token:
      - tag: alerts
      - format: markdown

# Include other configuration files
include:
  - /path/to/additional/config.yml
  - https://example.com/remote-config.yml

Usage Examples

Basic Configuration Loading

import apprise

# Load from file
config = apprise.AppriseConfig('/path/to/apprise.conf')

# Load from multiple sources
config = apprise.AppriseConfig([
    '/path/to/email.conf',
    '/path/to/slack.conf',
    'https://example.com/remote.yml'
])

# Get servers from configuration
servers = config.servers()
print(f"Loaded {len(servers)} notification services")

# Use with Apprise
apobj = apprise.Apprise()
apobj.add(servers)
apobj.notify('Configuration test message')

Dynamic Configuration Management

import apprise

# Start with empty configuration
config = apprise.AppriseConfig()

# Add configurations dynamically
config.add('/path/to/production.conf', tag='prod')
config.add('/path/to/testing.conf', tag='test')

# Add configuration from string
config_string = """
mailto://alerts@company.com
slack://token/channel
"""
config.add(config_string, tag='alerts')

# Get servers by tag
prod_servers = config.servers(tag='prod')
test_servers = config.servers(tag='test')
alert_servers = config.servers(tag='alerts')

print(f"Production servers: {len(prod_servers)}")
print(f"Testing servers: {len(test_servers)}")
print(f"Alert servers: {len(alert_servers)}")

Configuration with Apprise Integration

import apprise

# Load configuration and integrate with Apprise
config = apprise.AppriseConfig('/path/to/notifications.yml')
apobj = apprise.Apprise()

# Add all configured services
apobj.add(config.servers())

# Or add with additional tags
apobj.add(config.servers(), tag='from_config')

# Send notification
apobj.notify(
    body='Message from configured services',
    title='Configuration Test',
    notify_type=apprise.NotifyType.INFO
)

Advanced Configuration Features

import apprise

# Configuration with caching and recursion control
config = apprise.AppriseConfig(
    cache=True,           # Enable caching for performance
    recursion=3,          # Allow up to 3 levels of includes
    insecure_includes=False  # Require HTTPS for remote includes
)

# Add configuration with custom settings
config.add(
    'https://example.com/config.yml',
    cache=False,          # Disable caching for this config
    recursion=1,          # Limit recursion for this config
    tag='remote'
)

# Monitor configuration changes
initial_count = len(config.configs)
config.add('/path/to/new-config.conf')
final_count = len(config.configs)

print(f"Added {final_count - initial_count} new configurations")

# Get configuration URLs for debugging
urls = config.urls(privacy=True)
for url in urls:
    print(f"Config URL: {url}")

Configuration Management with Assets

import apprise

# Create custom asset configuration
asset = apprise.AppriseAsset(
    app_id='MyApp',
    app_desc='My Application',
    default_html_color='#3AA3E3'
)

# Load configuration with custom assets
config = apprise.AppriseConfig(
    '/path/to/config.yml',
    asset=asset
)

# All services loaded from config will use custom assets
servers = config.servers()

# Use with Apprise
apobj = apprise.Apprise(asset=asset)
apobj.add(servers)

apobj.notify(
    body='Message with custom branding',
    title='Custom App Notification'
)

Error Handling and Validation

import apprise

try:
    config = apprise.AppriseConfig()
    
    # Add configuration with error handling
    success = config.add('/path/to/config.yml')
    if not success:
        print("Failed to load configuration")
    
    # Validate loaded servers
    servers = config.servers()
    if not servers:
        print("No notification services found in configuration")
    else:
        print(f"Successfully loaded {len(servers)} services")
        
        # Test each server
        for server in servers:
            if hasattr(server, 'enabled') and not server.enabled:
                print(f"Warning: {server.service_name} is disabled")

except apprise.ConfigException as e:
    print(f"Configuration error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")