Media asset management for Python, with glue code for various web frameworks
The auto-rebuild system in webassets determines whether bundles need to be rebuilt by analyzing timestamps, bundle definitions, and dependencies. This system is optional and particularly useful during development and on small sites where rebuild checks on every request are acceptable.
Abstract base class for all updater implementations, using a registry pattern for automatic updater resolution.
class BaseUpdater:
def needs_rebuild(self, bundle, ctx):
"""
Returns True if the given bundle needs to be rebuilt, False otherwise.
Args:
bundle: Bundle instance to check
ctx: Build context containing cache, manifest, and environment info
Returns:
bool: True if rebuild needed, False otherwise
"""
def build_done(self, bundle, ctx):
"""
Called once a bundle has been successfully built.
Args:
bundle: Bundle instance that was built
ctx: Build context
"""Supports bundle definition cache update checks that detect when bundle configuration changes (source files added/removed, filters modified).
class BundleDefUpdater(BaseUpdater):
def check_bundle_definition(self, bundle, ctx):
"""
Check if the bundle definition has changed since last build.
Args:
bundle: Bundle to check
ctx: Build context
Returns:
bool: True if bundle definition changed
"""
def needs_rebuild(self, bundle, ctx):
"""Check if rebuild needed based on bundle definition changes."""
def build_done(self, bundle, ctx):
"""Cache current bundle definition hash."""Default updater that compares modification timestamps of source files, dependencies, and output files.
class TimestampUpdater(BundleDefUpdater):
id = 'timestamp'
def check_timestamps(self, bundle, ctx, o_modified=None):
"""
Compare timestamps of all source files and dependencies against output.
Args:
bundle: Bundle to check
ctx: Build context
o_modified: Output file modification time (auto-detected if None)
Returns:
bool or SKIP_CACHE: True if rebuild needed, SKIP_CACHE if dependencies changed
"""
def needs_rebuild(self, bundle, ctx):
"""Check if rebuild needed based on timestamps and bundle definition."""
def build_done(self, bundle, ctx):
"""Reset resolved dependencies cache and update bundle definition."""Forces rebuilds on every check, useful for development or testing scenarios.
class AlwaysUpdater(BaseUpdater):
id = 'always'
def needs_rebuild(self, bundle, ctx):
"""Always returns True to force rebuilds."""def get_updater(updater_id):
"""
Resolve updater by string identifier.
Args:
updater_id: String identifier ('timestamp', 'always') or updater instance
Returns:
BaseUpdater: Updater instance
"""SKIP_CACHE = object()Special return value indicating that cache should not be used for rebuild. Used when bundle dependencies have changed, which would not normally cause a different cache key.
The updater system handles multiple types of dependencies:
depends argumentDetects changes in bundle configuration by maintaining a hash-based cache:
The timestamp updater uses sophisticated logic:
SKIP_CACHE hint when dependencies changefrom webassets import Environment
from webassets.updater import TimestampUpdater
env = Environment('./static', '/static')
env.updater = TimestampUpdater()
# Bundle will be checked for rebuild automatically
bundle = env['my_bundle']
if env.updater.needs_rebuild(bundle, env):
bundle.build()from webassets.updater import BaseUpdater
class CustomUpdater(BaseUpdater):
id = 'custom'
def needs_rebuild(self, bundle, ctx):
# Custom rebuild logic
return self.custom_check(bundle)
def build_done(self, bundle, ctx):
# Post-build actions
self.log_build(bundle)
# Register and use
env.updater = 'custom' # Resolves to CustomUpdaterimport os
from webassets.updater import TimestampUpdater, AlwaysUpdater
if os.environ.get('DEBUG'):
env.updater = AlwaysUpdater() # Always rebuild in development
else:
env.updater = TimestampUpdater() # Smart rebuilds in productionInstall with Tessl CLI
npx tessl i tessl/pypi-webassets