CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-webassets

Media asset management for Python, with glue code for various web frameworks

Overview
Eval results
Files

configuration-loading.mddocs/

Configuration Loading

Flexible configuration loading from YAML files, Python modules, and programmatic sources to manage complex asset processing setups.

Capabilities

YAML Configuration Loading

Load environment and bundle configurations from YAML files for declarative asset management.

class YAMLLoader:
    def __init__(self, file_or_filename):
        """
        Create YAML configuration loader.
        
        Parameters:
        - file_or_filename: YAML file path or file object
        """
    
    def load_bundles(self):
        """
        Load bundle definitions from YAML.
        
        Returns:
        Dictionary of bundle name -> Bundle instance mappings
        """
    
    def load_environment(self):
        """
        Load complete environment configuration from YAML.
        
        Returns:
        Configured Environment instance
        """

Example YAML configuration:

# assets.yaml
directory: ./static
url: /static
debug: false
cache: filesystem
auto_build: true

bundles:
  js_all:
    contents:
      - js/jquery.js
      - js/app.js
      - js/utils.js
    filters: jsmin
    output: gen/app.js
    
  css_all:
    contents:
      - css/base.css
      - css/layout.css
    filters: 
      - sass
      - cssmin
    output: gen/style.css
    depends:
      - css/_variables.scss
      - css/_mixins.scss

Usage example:

from webassets.loaders import YAMLLoader

# Load from YAML file
loader = YAMLLoader('assets.yaml')

# Load environment and bundles
env = loader.load_environment()
bundles = loader.load_bundles()

# Register bundles
for name, bundle in bundles.items():
    env.register(name, bundle)

# Build all bundles
for bundle in bundles.values():
    bundle.build()

Python Module Loading

Load configurations from Python modules for dynamic and programmatic asset definitions.

class PythonLoader:
    def __init__(self, module_name):
        """
        Create Python module configuration loader.
        
        Parameters:
        - module_name: Python module name to import
        """
    
    def load_bundles(self):
        """Load bundles defined in Python module."""
    
    def load_environment(self):
        """Load environment configuration from Python module."""

Example Python configuration:

# assets.py
from webassets import Environment, Bundle

# Environment configuration
directory = './static'
url = '/static'
debug = False
cache = True

# Bundle definitions
bundles = {
    'js_all': Bundle(
        'jquery.js',
        'app.js',
        'utils.js',
        filters='jsmin',
        output='gen/app.js'
    ),
    
    'css_all': Bundle(
        'base.css',
        'layout.css',
        filters=['sass', 'cssmin'],
        output='gen/style.css'
    )
}

# Environment setup
def create_environment():
    env = Environment(directory, url, debug=debug, cache=cache)
    for name, bundle in bundles.items():
        env.register(name, bundle)
    return env

Usage example:

from webassets.loaders import PythonLoader

# Load from Python module
loader = PythonLoader('myapp.assets')
env = loader.load_environment()

# Environment is ready to use
js_urls = env['js_all'].urls()

Glob Pattern Loading

Load and organize assets using glob patterns for automatic file discovery.

class GlobLoader:
    def __init__(self, pattern, **bundle_options):
        """
        Create glob pattern loader.
        
        Parameters:
        - pattern: Glob pattern for file matching
        - **bundle_options: Options for created bundles
        """
    
    def load_bundles(self):
        """Load bundles from glob pattern matches."""

Example usage:

from webassets.loaders import GlobLoader

# Load all JavaScript files
js_loader = GlobLoader(
    'js/**/*.js',
    filters='jsmin',
    output='gen/all.js'
)

# Load all CSS files
css_loader = GlobLoader(
    'css/**/*.css',
    filters=['sass', 'cssmin'],
    output='gen/all.css'
)

js_bundles = js_loader.load_bundles()
css_bundles = css_loader.load_bundles()

Base Loader Class

Foundation class for creating custom configuration loaders.

class Loader:
    def load_bundles(self):
        """Override to load bundle definitions."""
        raise NotImplementedError()
    
    def load_environment(self):
        """Override to load environment configuration."""
        raise NotImplementedError()

Loader Exceptions

Exception handling for configuration loading errors.

class LoaderError(Exception):
    """Raised when loaders can't process a file."""

Advanced Configuration Examples

Complex YAML Configuration

# Full-featured assets.yaml
directory: ./src/assets
url: /assets
debug: false
cache: 
  type: filesystem
  directory: ./.webassets-cache
auto_build: false
versions: hash
manifest: json:manifest.json

load_path:
  - ./vendor
  - ./node_modules

url_mapping:
  /images: ./img
  /fonts: ./fonts

bundles:
  # Vendor JavaScript
  js_vendor:
    contents:
      - vendor/jquery/dist/jquery.min.js
      - vendor/bootstrap/dist/js/bootstrap.min.js
      - vendor/lodash/lodash.min.js
    output: gen/vendor-%(version)s.js
    
  # Application JavaScript  
  js_app:
    contents:
      - js/app.js
      - js/modules/*.js
      - js/utils.js
    filters:
      - babel
      - uglifyjs
    output: gen/app-%(version)s.js
    depends:
      - js/config.js
      
  # Vendor CSS
  css_vendor:
    contents:
      - vendor/bootstrap/dist/css/bootstrap.min.css
      - vendor/font-awesome/css/font-awesome.min.css
    output: gen/vendor-%(version)s.css
    
  # Application CSS
  css_app:
    contents:
      - scss/main.scss
    filters:
      - libsass
      - autoprefixer
      - cssmin
    output: gen/app-%(version)s.css
    depends:
      - scss/_variables.scss
      - scss/_mixins.scss
      - scss/components/*.scss

Dynamic Python Configuration

# Dynamic assets.py with environment detection
import os
from webassets import Environment, Bundle

# Detect environment
DEBUG = os.environ.get('DEBUG', 'false').lower() == 'true'
STATIC_ROOT = os.environ.get('STATIC_ROOT', './static')
STATIC_URL = os.environ.get('STATIC_URL', '/static')

# Environment configuration
directory = STATIC_ROOT
url = STATIC_URL
debug = DEBUG
cache = not DEBUG
auto_build = DEBUG

def create_js_bundle(debug=False):
    """Create JavaScript bundle based on environment."""
    filters = ['babel']
    if not debug:
        filters.append('uglifyjs')
    
    return Bundle(
        'js/app.js',
        'js/utils.js',
        'js/modules/*.js',
        filters=filters,
        output='gen/app.js'
    )

def create_css_bundle(debug=False):
    """Create CSS bundle based on environment."""
    filters = ['libsass', 'autoprefixer']
    if not debug:
        filters.append('cssmin')
    
    return Bundle(
        'scss/main.scss',
        filters=filters,
        output='gen/app.css'
    )

# Bundle definitions
bundles = {
    'js_app': create_js_bundle(debug),
    'css_app': create_css_bundle(debug)
}

# Add versioning in production
if not debug:
    for bundle in bundles.values():
        bundle.output = bundle.output.replace('.', '-%(version)s.')

def create_environment():
    env = Environment(
        directory=directory,
        url=url,
        debug=debug,
        cache=cache,
        auto_build=auto_build
    )
    
    if not debug:
        env.versions = 'hash'
        env.manifest = 'json:manifest.json'
    
    for name, bundle in bundles.items():
        env.register(name, bundle)
    
    return env

Custom Loader Implementation

from webassets.loaders import Loader, LoaderError
from webassets import Environment, Bundle
import json

class JSONLoader(Loader):
    """Load configuration from JSON files."""
    
    def __init__(self, filename):
        self.filename = filename
    
    def load_environment(self):
        try:
            with open(self.filename, 'r') as f:
                config = json.load(f)
        except (IOError, ValueError) as e:
            raise LoaderError(f"Failed to load {self.filename}: {e}")
        
        # Create environment
        env_config = config.get('environment', {})
        env = Environment(**env_config)
        
        # Load bundles
        bundles_config = config.get('bundles', {})
        for name, bundle_config in bundles_config.items():
            contents = bundle_config.pop('contents', [])
            bundle = Bundle(*contents, **bundle_config)
            env.register(name, bundle)
        
        return env
    
    def load_bundles(self):
        env = self.load_environment()
        return dict(env)

# Usage
loader = JSONLoader('assets.json')
env = loader.load_environment()

Multi-Source Configuration

def load_assets_config():
    """Load assets from multiple sources with precedence."""
    
    # Start with base configuration
    base_loader = YAMLLoader('assets.base.yaml')
    env = base_loader.load_environment()
    
    # Override with environment-specific config
    env_config = os.environ.get('ENVIRONMENT', 'development')
    env_file = f'assets.{env_config}.yaml'
    
    if os.path.exists(env_file):
        env_loader = YAMLLoader(env_file)
        env_bundles = env_loader.load_bundles()
        
        # Merge bundles
        for name, bundle in env_bundles.items():
            env.register(name, bundle)
    
    # Load additional bundles from Python if available
    try:
        python_loader = PythonLoader('local_assets')
        local_bundles = python_loader.load_bundles()
        
        for name, bundle in local_bundles.items():
            env.register(name, bundle)
    except ImportError:
        pass  # Local assets module not available
    
    return env

Configuration Validation

def validate_assets_config(config_file):
    """Validate assets configuration before loading."""
    
    try:
        loader = YAMLLoader(config_file)
        env = loader.load_environment()
        bundles = loader.load_bundles()
    except Exception as e:
        print(f"Configuration error: {e}")
        return False
    
    # Validate bundles
    for name, bundle in bundles.items():
        try:
            # Test bundle resolution
            bundle.resolve_contents()
            print(f"Bundle '{name}': OK")
        except Exception as e:
            print(f"Bundle '{name}': ERROR - {e}")
            return False
    
    print("Configuration validation passed")
    return True

# Usage
if validate_assets_config('assets.yaml'):
    loader = YAMLLoader('assets.yaml')
    env = loader.load_environment()

Install with Tessl CLI

npx tessl i tessl/pypi-webassets

docs

bundle-management.md

caching-versioning.md

command-line.md

configuration-loading.md

environment-configuration.md

filter-system.md

framework-integration.md

index.md

merge-system.md

updater-system.md

utilities.md

tile.json