0
# Environment Configuration
1
2
Environment management for configuring asset processing, including directory paths, URL mapping, caching, version management, and bundle registration.
3
4
## Capabilities
5
6
### Environment Creation and Setup
7
8
Create and configure environments to manage asset processing settings and bundle collections.
9
10
```python { .api }
11
class Environment:
12
def __init__(self, directory=None, url=None, **more_config):
13
"""
14
Create a new asset environment.
15
16
Parameters:
17
- directory: Base directory for asset files (filesystem path)
18
- url: Base URL for serving assets (web path)
19
- **more_config: Additional configuration options:
20
- debug: Debug mode setting (bool)
21
- cache: Cache configuration (str/bool/Cache instance)
22
- auto_build: Automatically build bundles when accessed (bool)
23
- load_path: Additional search paths (list)
24
- url_mapping: URL path mappings (dict)
25
- versions: Versioning strategy (str/Version instance)
26
- manifest: Manifest configuration (str/Manifest instance)
27
- updater: Update checking strategy (str/Updater instance)
28
"""
29
```
30
31
Example usage:
32
```python
33
from webassets import Environment
34
35
# Basic environment
36
env = Environment('./static', '/static')
37
38
# Environment with configuration
39
env = Environment(
40
directory='./assets',
41
url='/assets',
42
debug=False,
43
cache=True,
44
auto_build=True,
45
versions='hash'
46
)
47
48
# Environment with advanced settings
49
env = Environment(
50
'./static',
51
'/static',
52
load_path=['./vendor', './themes'],
53
url_mapping={'/images': './img'},
54
cache='filesystem',
55
manifest='json:manifest.json'
56
)
57
```
58
59
### Bundle Registration and Management
60
61
Register and manage bundles within the environment for organized asset processing.
62
63
```python { .api }
64
def register(self, name, *args, **kwargs):
65
"""
66
Register a bundle with the environment.
67
68
Parameters:
69
- name: Bundle name for later reference
70
- *args: Bundle arguments (files, nested bundles)
71
- **kwargs: Bundle options (filters, output, etc.)
72
73
Returns:
74
The created Bundle instance
75
"""
76
77
def add(self, *bundles):
78
"""
79
Add anonymous bundles to the environment.
80
81
Parameters:
82
- *bundles: Bundle instances to add
83
"""
84
85
def append_path(self, path, url=None):
86
"""
87
Add a directory to the load path.
88
89
Parameters:
90
- path: Directory path to add
91
- url: Optional URL mapping for the path
92
"""
93
```
94
95
Example usage:
96
```python
97
# Register named bundles
98
js_bundle = env.register('js_all',
99
'jquery.js',
100
'app.js',
101
filters='jsmin',
102
output='gen/app.js'
103
)
104
105
css_bundle = env.register('css_all',
106
'style.css',
107
'layout.css',
108
filters='cssmin',
109
output='gen/style.css'
110
)
111
112
# Add anonymous bundles
113
from webassets import Bundle
114
vendor_bundle = Bundle('vendor/lib.js', output='gen/vendor.js')
115
env.add(vendor_bundle)
116
117
# Add to load path
118
env.append_path('./vendor')
119
env.append_path('./themes', '/themes')
120
121
# Access registered bundles
122
js_urls = env['js_all'].urls()
123
css_urls = env['css_all'].urls()
124
```
125
126
### Bundle Registry
127
128
Registry for managing named and anonymous bundles within an environment.
129
130
```python { .api }
131
class BundleRegistry:
132
def register(self, name, *args, **kwargs):
133
"""Register a bundle with a name."""
134
135
def add(self, *bundles):
136
"""Add anonymous bundles."""
137
138
def __getitem__(self, name):
139
"""Get bundle by name."""
140
141
def __contains__(self, name):
142
"""Check if bundle exists."""
143
144
def __iter__(self):
145
"""Iterate over all bundles."""
146
147
def __len__(self):
148
"""Get total number of registered bundles."""
149
150
def __bool__(self):
151
"""Check if registry contains any bundles."""
152
153
def decompose_bundle(self, name, bundle):
154
"""Decompose bundle with merge=False into individual file bundles."""
155
156
def register_decomposed(self, name, bundle, abspath):
157
"""Register single decomposed bundle for specific file."""
158
```
159
160
### Path and URL Resolution
161
162
Resolve file paths and URLs for assets within the environment configuration.
163
164
```python { .api }
165
class Resolver:
166
def search_for_source(self, ctx, item):
167
"""
168
Find source file in load paths.
169
170
Parameters:
171
- ctx: Search context
172
- item: File or pattern to find
173
174
Returns:
175
Found file path or None
176
"""
177
178
def resolve_source(self, ctx, item):
179
"""
180
Resolve source to filesystem path.
181
182
Parameters:
183
- ctx: Resolution context
184
- item: Source specification
185
186
Returns:
187
Absolute filesystem path
188
"""
189
190
def resolve_source_to_url(self, ctx, filepath, item):
191
"""
192
Resolve source to web URL.
193
194
Parameters:
195
- ctx: Resolution context
196
- filepath: Source file path
197
- item: Source item
198
199
Returns:
200
Web-accessible URL
201
"""
202
203
def resolve_output_to_path(self, ctx, target, bundle):
204
"""
205
Resolve output to filesystem path.
206
207
Parameters:
208
- ctx: Resolution context
209
- target: Output target
210
- bundle: Source bundle
211
212
Returns:
213
Output filesystem path
214
"""
215
216
def resolve_output_to_url(self, ctx, target):
217
"""
218
Resolve output to web URL.
219
220
Parameters:
221
- ctx: Resolution context
222
- target: Output target
223
224
Returns:
225
Output web URL
226
"""
227
228
def glob(self, basedir, expr):
229
"""
230
Evaluate glob expression and return sorted absolute filenames.
231
232
Parameters:
233
- basedir: Base directory for glob evaluation
234
- expr: Glob expression pattern
235
236
Returns:
237
Sorted list of absolute filenames matching pattern
238
"""
239
240
def consider_single_directory(self, directory, item):
241
"""
242
Search for item within specific directory, handling glob patterns.
243
244
Parameters:
245
- directory: Directory to search in
246
- item: File or pattern to find
247
248
Returns:
249
File path or list of paths if glob pattern
250
"""
251
252
def search_env_directory(self, ctx, item):
253
"""
254
Search for source in environment's base directory.
255
256
Parameters:
257
- ctx: Resolution context
258
- item: Source item to find
259
260
Returns:
261
Found file path or list of paths
262
"""
263
264
def search_load_path(self, ctx, item):
265
"""
266
Search for source files in configured load paths.
267
268
Parameters:
269
- ctx: Resolution context with load_path
270
- item: Source item to find
271
272
Returns:
273
Found file path or None if not found
274
"""
275
276
def search_for_source(self, ctx, item):
277
"""
278
Perform comprehensive search for source item.
279
280
Parameters:
281
- ctx: Resolution context
282
- item: Source item to find
283
284
Returns:
285
Found file path(s) or raises error if not found
286
"""
287
288
def query_url_mapping(self, ctx, item):
289
"""
290
Query URL mapping configuration for source item.
291
292
Parameters:
293
- ctx: Resolution context with url_mapping
294
- item: Source item to look up
295
296
Returns:
297
Mapped URL or None if no mapping found
298
"""
299
300
def query_url_mapping(self, ctx, filepath):
301
"""
302
Find correct URL for filesystem path using URL mappings.
303
304
Parameters:
305
- ctx: Resolution context
306
- filepath: Absolute filesystem path
307
308
Returns:
309
Web-accessible URL for the file
310
"""
311
```
312
313
### Bundle Registry
314
315
Registry for managing bundle collections with decomposition support for merge=False bundles.
316
317
```python { .api }
318
class BundleRegistry:
319
def __init__(self, env):
320
"""Initialize bundle registry for environment."""
321
322
def __len__(self):
323
"""Return number of registered bundles."""
324
325
def __bool__(self):
326
"""Return True if registry contains bundles."""
327
328
def __getitem__(self, name):
329
"""Get bundle by name."""
330
331
def __setitem__(self, name, bundle):
332
"""Register bundle with name."""
333
334
def __delitem__(self, name):
335
"""Remove bundle from registry."""
336
337
def __contains__(self, name):
338
"""Check if bundle name is registered."""
339
340
def __iter__(self):
341
"""Iterate over bundle names."""
342
343
def decompose_bundle(self, bundle):
344
"""
345
Handle bundles with merge=False by decomposing into individual files.
346
347
Parameters:
348
- bundle: Bundle to decompose
349
350
Returns:
351
List of individual file bundles or original bundle
352
"""
353
354
def register_decomposed(self, name, bundle):
355
"""
356
Register bundle with decomposition handling.
357
358
Parameters:
359
- name: Bundle name
360
- bundle: Bundle to register (may be decomposed)
361
"""
362
```
363
364
### Configuration Storage
365
366
Backend for environment configuration with case-insensitive key handling.
367
368
```python { .api }
369
class ConfigStorage:
370
def __init__(self, env):
371
"""Initialize configuration storage for environment."""
372
373
def get(self, key, default=None):
374
"""Get configuration value with default."""
375
376
def __getitem__(self, key):
377
"""Get configuration value."""
378
379
def __setitem__(self, key, value):
380
"""Set configuration value."""
381
382
def __delitem__(self, key):
383
"""Delete configuration value."""
384
385
def __contains__(self, key):
386
"""Check if configuration key exists."""
387
388
def update(self, d):
389
"""Update configuration with values from dictionary."""
390
391
def setdefault(self, key, value):
392
"""Set configuration key to value if key doesn't exist."""
393
```
394
395
### Environment Properties
396
397
Access environment configuration and state through properties.
398
399
```python { .api }
400
# Core properties
401
@property
402
def directory(self):
403
"""Asset base directory"""
404
405
@property
406
def url(self):
407
"""Asset base URL"""
408
409
@property
410
def debug(self):
411
"""Debug mode setting"""
412
413
@property
414
def cache(self):
415
"""Caching configuration"""
416
417
@property
418
def auto_build(self):
419
"""Automatic building setting"""
420
421
@property
422
def load_path(self):
423
"""Additional search paths"""
424
425
@property
426
def url_mapping(self):
427
"""URL path mappings"""
428
429
@property
430
def resolver(self):
431
"""Path resolver instance"""
432
433
@property
434
def updater(self):
435
"""Update checker instance"""
436
437
@property
438
def versions(self):
439
"""Versioning configuration"""
440
441
@property
442
def manifest(self):
443
"""Manifest configuration"""
444
445
@property
446
def cache_file_mode(self):
447
"""File permissions for cached files (octal)"""
448
449
@property
450
def url_expire(self):
451
"""URL expiration setting for cache headers"""
452
453
@property
454
def config(self):
455
"""Configuration storage instance"""
456
457
@property
458
def cache_file_mode(self):
459
"""Cache file creation mode (octal)"""
460
```
461
462
### Utility Functions
463
464
Helper functions for configuration value parsing and validation.
465
466
```python { .api }
467
def parse_debug_value(value):
468
"""
469
Parse string value to debug option setting.
470
471
Parameters:
472
- value: String value to parse ('true', 'false', 'merge', etc.)
473
474
Returns:
475
Parsed debug setting (bool or string)
476
"""
477
```
478
479
Example usage:
480
```python
481
# Parse debug values
482
debug_setting = parse_debug_value('merge') # Returns 'merge'
483
debug_setting = parse_debug_value('true') # Returns True
484
debug_setting = parse_debug_value('false') # Returns False
485
```
486
487
## Advanced Configuration Examples
488
489
### Multi-Environment Setup
490
491
```python
492
# Development environment
493
dev_env = Environment(
494
'./src/assets',
495
'/static',
496
debug=True,
497
auto_build=True,
498
cache=False
499
)
500
501
# Production environment
502
prod_env = Environment(
503
'./static',
504
'/static',
505
debug=False,
506
cache='filesystem',
507
versions='hash',
508
manifest='json:manifest.json'
509
)
510
511
# Register same bundles in both
512
for env in [dev_env, prod_env]:
513
env.register('js_app',
514
'app.js',
515
'utils.js',
516
filters='jsmin' if not env.debug else None,
517
output='gen/app.js'
518
)
519
```
520
521
### Complex Path Configuration
522
523
```python
524
env = Environment('./static', '/static')
525
526
# Add multiple search paths
527
env.append_path('./vendor/css', '/vendor/css')
528
env.append_path('./themes', '/themes')
529
env.append_path('./node_modules', '/npm')
530
531
# URL mappings for different asset types
532
env.url_mapping = {
533
'/images': './img',
534
'/fonts': './fonts',
535
'/icons': './icons'
536
}
537
```
538
539
### Dynamic Environment Configuration
540
541
```python
542
def create_environment(mode='development'):
543
config = {
544
'directory': './static',
545
'url': '/static',
546
'debug': mode == 'development',
547
'auto_build': mode == 'development',
548
'cache': mode != 'development'
549
}
550
551
if mode == 'production':
552
config.update({
553
'versions': 'hash',
554
'manifest': 'json:assets.json'
555
})
556
557
return Environment(**config)
558
559
# Create environment based on mode
560
env = create_environment('production')
561
```
562
563
### Framework Integration Patterns
564
565
```python
566
# Flask integration example
567
def create_flask_assets(app):
568
env = Environment(
569
directory=app.static_folder,
570
url=app.static_url_path,
571
debug=app.debug,
572
auto_build=app.debug
573
)
574
575
# Register common bundles
576
env.register('js_vendor',
577
'vendor/jquery.js',
578
'vendor/bootstrap.js',
579
filters='jsmin',
580
output='gen/vendor.js'
581
)
582
583
return env
584
```