0
# Configuration System
1
2
Configuration classes for various framework features including CORS, compression, static files, templates, and application settings. Litestar provides type-safe configuration with validation and comprehensive options.
3
4
## Capabilities
5
6
### CORS Configuration
7
8
Cross-Origin Resource Sharing configuration for handling browser security policies.
9
10
```python { .api }
11
class CORSConfig:
12
def __init__(
13
self,
14
*,
15
allow_origins: Sequence[str] = ("*",),
16
allow_methods: Sequence[str] = ("GET",),
17
allow_headers: Sequence[str] = (),
18
allow_credentials: bool = False,
19
allow_origin_regex: str | None = None,
20
expose_headers: Sequence[str] = (),
21
max_age: int = 600,
22
vary_header: bool = True,
23
):
24
"""
25
CORS configuration.
26
27
Parameters:
28
- allow_origins: List of allowed origins or "*" for all
29
- allow_methods: List of allowed HTTP methods
30
- allow_headers: List of allowed request headers
31
- allow_credentials: Whether to allow credentials in requests
32
- allow_origin_regex: Regex pattern for allowed origins
33
- expose_headers: Headers to expose to the client
34
- max_age: Preflight request cache duration in seconds
35
- vary_header: Whether to add Vary header
36
"""
37
38
@property
39
def is_allow_all_origins(self) -> bool:
40
"""Check if all origins are allowed."""
41
42
@property
43
def is_allow_all_methods(self) -> bool:
44
"""Check if all methods are allowed."""
45
46
@property
47
def is_allow_all_headers(self) -> bool:
48
"""Check if all headers are allowed."""
49
```
50
51
### Compression Configuration
52
53
Response compression settings for reducing bandwidth usage.
54
55
```python { .api }
56
class CompressionConfig:
57
def __init__(
58
self,
59
backend: Literal["gzip", "brotli"] = "gzip",
60
minimum_size: int = 500,
61
exclude_opt_key: str = "skip_compression",
62
compression_facade: CompressionFacade | None = None,
63
gzip_compress_level: int = 9,
64
brotli_quality: int = 5,
65
brotli_mode: Literal["generic", "text", "font"] = "text",
66
brotli_lgwin: int = 22,
67
brotli_lgblock: int = 0,
68
):
69
"""
70
Compression configuration.
71
72
Parameters:
73
- backend: Compression algorithm to use
74
- minimum_size: Minimum response size in bytes to compress
75
- exclude_opt_key: Route option key to skip compression
76
- compression_facade: Custom compression implementation
77
- gzip_compress_level: Gzip compression level (1-9)
78
- brotli_quality: Brotli compression quality (0-11)
79
- brotli_mode: Brotli compression mode
80
- brotli_lgwin: Brotli window size (10-24)
81
- brotli_lgblock: Brotli block size (0-24)
82
"""
83
84
class CompressionFacade:
85
"""Interface for custom compression implementations."""
86
87
def compress(self, data: bytes) -> bytes:
88
"""Compress data using the configured algorithm."""
89
90
@property
91
def encoding(self) -> str:
92
"""Get the content-encoding header value."""
93
```
94
95
### Static Files Configuration
96
97
Configuration for serving static files like CSS, JavaScript, images, etc.
98
99
```python { .api }
100
class StaticFilesConfig:
101
def __init__(
102
self,
103
path: str | Path,
104
directories: Sequence[str | Path],
105
*,
106
name: str | None = None,
107
include_in_schema: bool = True,
108
guards: Sequence[Guard] | None = None,
109
opt: dict[str, Any] | None = None,
110
send_as_attachment: bool = False,
111
file_system: FileSystemProtocol | None = None,
112
):
113
"""
114
Static files serving configuration.
115
116
Parameters:
117
- path: URL path prefix for static files
118
- directories: List of directories to serve files from
119
- name: Name for the static files handler
120
- include_in_schema: Whether to include in OpenAPI schema
121
- guards: Authorization guards for static files
122
- opt: Additional options
123
- send_as_attachment: Send files as attachments
124
- file_system: Custom file system implementation
125
"""
126
127
@property
128
def to_static_files_app(self) -> StaticFiles:
129
"""Convert to StaticFiles ASGI application."""
130
```
131
132
### Template Configuration
133
134
Template engine configuration for rendering HTML responses.
135
136
```python { .api }
137
class TemplateConfig:
138
def __init__(
139
self,
140
directory: str | Path | Sequence[str | Path],
141
*,
142
engine: type[TemplateEngineProtocol] | TemplateEngineProtocol | None = None,
143
engine_callback: Callable[[TemplateEngineProtocol], None] | None = None,
144
auto_reload: bool = False,
145
):
146
"""
147
Template engine configuration.
148
149
Parameters:
150
- directory: Template directory or directories
151
- engine: Template engine instance or class
152
- engine_callback: Callback to configure the engine
153
- auto_reload: Automatically reload templates on change
154
"""
155
156
def to_engine(self) -> TemplateEngineProtocol:
157
"""Create template engine instance."""
158
159
@property
160
def engine_instance(self) -> TemplateEngineProtocol:
161
"""Get or create template engine instance."""
162
```
163
164
### OpenAPI Configuration
165
166
OpenAPI 3.1 specification generation settings.
167
168
```python { .api }
169
class OpenAPIConfig:
170
def __init__(
171
self,
172
*,
173
title: str = "Litestar API",
174
version: str = "1.0.0",
175
description: str | None = None,
176
summary: str | None = None,
177
contact: Contact | None = None,
178
license: License | None = None,
179
servers: list[Server] | None = None,
180
terms_of_service: str | None = None,
181
external_docs: ExternalDocumentation | None = None,
182
security: list[SecurityRequirement] | None = None,
183
components: Components | None = None,
184
tags: list[Tag] | None = None,
185
webhooks: dict[str, PathItem | Reference] | None = None,
186
openapi_controller: type[OpenAPIController] | None = None,
187
favicon_url: str | None = None,
188
root_schema_site: Literal["redoc", "swagger", "rapidoc", "stoplight"] = "redoc",
189
enabled_endpoints: set[str] = frozenset({"redoc", "swagger", "openapi.json", "openapi.yaml"}),
190
path: str = "/schema",
191
create_examples: bool = True,
192
plugins: list[OpenAPIPlugin] | None = None,
193
operation_id_creator: Callable[[str, str, list[str]], str] | None = None,
194
use_handler_docstrings: bool = False,
195
by_alias: bool = True,
196
prefer_alias: bool = False,
197
openapi_version: str = "3.1.0",
198
):
199
"""
200
OpenAPI documentation configuration.
201
202
Parameters:
203
- title: API title
204
- version: API version
205
- description: API description
206
- summary: API summary
207
- contact: Contact information
208
- license: License information
209
- servers: Server configurations
210
- terms_of_service: Terms of service URL
211
- external_docs: External documentation
212
- security: Security requirements
213
- components: Reusable components
214
- tags: API tags
215
- webhooks: Webhook definitions
216
- openapi_controller: Custom OpenAPI controller
217
- favicon_url: Favicon URL for documentation
218
- root_schema_site: Default documentation UI
219
- enabled_endpoints: Enabled documentation endpoints
220
- path: Base path for documentation endpoints
221
- create_examples: Generate examples automatically
222
- plugins: OpenAPI plugins
223
- operation_id_creator: Custom operation ID generator
224
- use_handler_docstrings: Use handler docstrings in schema
225
- by_alias: Use field aliases in schema
226
- prefer_alias: Prefer aliases over field names
227
- openapi_version: OpenAPI specification version
228
"""
229
```
230
231
### CSRF Configuration
232
233
Cross-Site Request Forgery protection settings.
234
235
```python { .api }
236
class CSRFConfig:
237
def __init__(
238
self,
239
secret: str | Secret,
240
*,
241
cookie_name: str = "csrftoken",
242
cookie_path: str = "/",
243
cookie_domain: str | None = None,
244
cookie_secure: bool = False,
245
cookie_httponly: bool = False,
246
cookie_samesite: Literal["lax", "strict", "none"] = "lax",
247
header_name: str = "x-csrftoken",
248
safe_methods: frozenset[str] = frozenset({"GET", "HEAD", "OPTIONS", "TRACE"}),
249
exclude: str | list[str] | None = None,
250
exclude_from_csrf_key: str = "exclude_from_csrf",
251
):
252
"""
253
CSRF protection configuration.
254
255
Parameters:
256
- secret: Secret key for token generation
257
- cookie_name: CSRF token cookie name
258
- cookie_path: Cookie path
259
- cookie_domain: Cookie domain
260
- cookie_secure: Use secure cookies
261
- cookie_httponly: Use HTTP-only cookies
262
- cookie_samesite: SameSite cookie attribute
263
- header_name: HTTP header containing CSRF token
264
- safe_methods: HTTP methods exempt from CSRF protection
265
- exclude: Paths to exclude from CSRF protection
266
- exclude_from_csrf_key: Route option key for exclusion
267
"""
268
```
269
270
### Cache Configuration
271
272
Response caching configuration for improving performance.
273
274
```python { .api }
275
class CacheConfig:
276
def __init__(
277
self,
278
*,
279
backend: Literal["simple", "redis", "memory"] = "simple",
280
expiration: int = 60,
281
cache_key_builder: Callable[[Request], str] | None = None,
282
exclude_opt_key: str = "skip_cache",
283
):
284
"""
285
Response caching configuration.
286
287
Parameters:
288
- backend: Caching backend to use
289
- expiration: Default cache expiration in seconds
290
- cache_key_builder: Custom cache key generation function
291
- exclude_opt_key: Route option key to skip caching
292
"""
293
294
def create_cache_key(self, request: Request) -> str:
295
"""Generate cache key for request."""
296
```
297
298
### Allowed Hosts Configuration
299
300
Host validation configuration for security.
301
302
```python { .api }
303
class AllowedHostsConfig:
304
def __init__(
305
self,
306
allowed_hosts: Sequence[str],
307
*,
308
exclude_opt_key: str = "exclude_from_allowed_hosts",
309
exclude: str | list[str] | None = None,
310
scopes: set[ScopeType] | None = None,
311
www_redirect: bool = True,
312
):
313
"""
314
Allowed hosts validation configuration.
315
316
Parameters:
317
- allowed_hosts: List of allowed hostnames/patterns
318
- exclude_opt_key: Route option key for exclusion
319
- exclude: Paths to exclude from host validation
320
- scopes: ASGI scopes to validate
321
- www_redirect: Redirect www to non-www
322
"""
323
324
def is_allowed_host(self, host: str) -> bool:
325
"""Check if host is allowed."""
326
```
327
328
### Logging Configuration
329
330
Logging system configuration with structured logging support.
331
332
```python { .api }
333
class BaseLoggingConfig:
334
"""Base logging configuration."""
335
336
def configure(self) -> GetLogger:
337
"""Configure logging and return logger getter."""
338
339
class LoggingConfig(BaseLoggingConfig):
340
def __init__(
341
self,
342
*,
343
root: dict[str, Any] | None = None,
344
disable_existing_loggers: bool = False,
345
filters: dict[str, dict[str, Any]] | None = None,
346
formatters: dict[str, dict[str, Any]] | None = None,
347
handlers: dict[str, dict[str, Any]] | None = None,
348
loggers: dict[str, dict[str, Any]] | None = None,
349
version: Literal[1] = 1,
350
incremental: bool = False,
351
configure_root_logger: bool = True,
352
log_exceptions: Literal["always", "debug", "never"] = "debug",
353
traceback_line_limit: int = -1,
354
exception_logging_handler: ExceptionLoggingHandler | None = None,
355
request_logging_handler: RequestLoggingHandler | None = None,
356
response_logging_handler: ResponseLoggingHandler | None = None,
357
):
358
"""
359
Standard logging configuration.
360
361
Parameters:
362
- root: Root logger configuration
363
- disable_existing_loggers: Disable existing loggers
364
- filters: Logging filters configuration
365
- formatters: Log formatters configuration
366
- handlers: Log handlers configuration
367
- loggers: Logger configurations
368
- version: Logging config version
369
- incremental: Incremental configuration
370
- configure_root_logger: Configure root logger
371
- log_exceptions: When to log exceptions
372
- traceback_line_limit: Traceback line limit
373
- exception_logging_handler: Custom exception handler
374
- request_logging_handler: Custom request handler
375
- response_logging_handler: Custom response handler
376
"""
377
378
class StructLoggingConfig(BaseLoggingConfig):
379
def __init__(
380
self,
381
*,
382
processors: Sequence[structlog.types.Processor] | None = None,
383
wrapper_class: structlog.types.BoundLoggerLazyProxy | None = None,
384
logger_factory: structlog.types.LoggerFactory | None = None,
385
cache_logger_on_first_use: bool = True,
386
standard_lib_logging_config: LoggingConfig | dict[str, Any] | None = None,
387
log_exceptions: Literal["always", "debug", "never"] = "debug",
388
exception_logging_handler: ExceptionLoggingHandler | None = None,
389
request_logging_handler: RequestLoggingHandler | None = None,
390
response_logging_handler: ResponseLoggingHandler | None = None,
391
):
392
"""
393
Structured logging configuration using structlog.
394
395
Parameters:
396
- processors: Log processors pipeline
397
- wrapper_class: Logger wrapper class
398
- logger_factory: Logger factory
399
- cache_logger_on_first_use: Cache logger instances
400
- standard_lib_logging_config: Standard library logging config
401
- log_exceptions: When to log exceptions
402
- exception_logging_handler: Custom exception handler
403
- request_logging_handler: Custom request handler
404
- response_logging_handler: Custom response handler
405
"""
406
```
407
408
### ETag Configuration
409
410
Entity tag configuration for HTTP caching.
411
412
```python { .api }
413
class ETagConfig:
414
def __init__(
415
self,
416
algorithm: Literal["sha1", "sha256", "md5"] = "sha1",
417
decorator: Callable[[str], str] | None = None
418
):
419
"""
420
ETag configuration.
421
422
Parameters:
423
- algorithm: Hashing algorithm for ETag generation
424
- decorator: Function to decorate generated ETags
425
"""
426
427
def create_etag(self, data: bytes) -> str:
428
"""Generate ETag for data."""
429
```
430
431
## Usage Examples
432
433
### Basic Application Configuration
434
435
```python
436
from litestar import Litestar
437
from litestar.config import (
438
CORSConfig, CompressionConfig, OpenAPIConfig,
439
StaticFilesConfig, TemplateConfig
440
)
441
442
# CORS configuration
443
cors_config = CORSConfig(
444
allow_origins=["https://frontend.example.com", "https://admin.example.com"],
445
allow_methods=["GET", "POST", "PUT", "DELETE"],
446
allow_headers=["Content-Type", "Authorization"],
447
allow_credentials=True,
448
max_age=86400, # 24 hours
449
)
450
451
# Compression configuration
452
compression_config = CompressionConfig(
453
backend="gzip",
454
minimum_size=1000, # Only compress responses > 1KB
455
gzip_compress_level=6, # Balance compression vs speed
456
)
457
458
# Static files configuration
459
static_config = StaticFilesConfig(
460
path="/static",
461
directories=["static", "assets"],
462
name="static_files"
463
)
464
465
# OpenAPI documentation
466
openapi_config = OpenAPIConfig(
467
title="My API",
468
version="1.0.0",
469
description="A comprehensive API for my application",
470
root_schema_site="redoc",
471
path="/docs"
472
)
473
474
app = Litestar(
475
route_handlers=[...],
476
cors_config=cors_config,
477
compression_config=compression_config,
478
static_files_config=[static_config],
479
openapi_config=openapi_config,
480
)
481
```
482
483
### Template Configuration with Jinja2
484
485
```python
486
from litestar.template import TemplateConfig
487
from litestar.contrib.jinja import JinjaTemplateEngine
488
489
template_config = TemplateConfig(
490
directory="templates",
491
engine=JinjaTemplateEngine,
492
auto_reload=True, # For development
493
engine_callback=lambda engine: engine.env.globals.update({
494
"app_name": "My Application",
495
"version": "1.0.0"
496
})
497
)
498
499
@get("/page")
500
def render_page() -> Template:
501
return Template(
502
"page.html",
503
context={"title": "Welcome", "user": "Alice"}
504
)
505
506
app = Litestar(
507
route_handlers=[render_page],
508
template_config=template_config
509
)
510
```
511
512
### Security Configuration
513
514
```python
515
from litestar.config import CSRFConfig, AllowedHostsConfig
516
from litestar.datastructures import Secret
517
518
# CSRF protection
519
csrf_config = CSRFConfig(
520
secret=Secret("your-csrf-secret-key"),
521
cookie_secure=True,
522
cookie_httponly=True,
523
cookie_samesite="strict",
524
exclude=["/api/webhook"] # Exclude webhook endpoints
525
)
526
527
# Host validation
528
allowed_hosts_config = AllowedHostsConfig(
529
allowed_hosts=[
530
"example.com",
531
"*.example.com", # Wildcard subdomain
532
"192.168.1.*", # IP range
533
],
534
www_redirect=True
535
)
536
537
app = Litestar(
538
route_handlers=[...],
539
csrf_config=csrf_config,
540
allowed_hosts=allowed_hosts_config
541
)
542
```
543
544
### Comprehensive Logging Configuration
545
546
```python
547
from litestar.logging import LoggingConfig
548
import logging
549
550
logging_config = LoggingConfig(
551
root={
552
"level": "INFO",
553
"handlers": ["console", "file"]
554
},
555
formatters={
556
"standard": {
557
"format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
558
},
559
"detailed": {
560
"format": "%(asctime)s [%(levelname)s] %(name)s:%(lineno)d - %(message)s"
561
}
562
},
563
handlers={
564
"console": {
565
"class": "logging.StreamHandler",
566
"level": "INFO",
567
"formatter": "standard",
568
"stream": "ext://sys.stdout"
569
},
570
"file": {
571
"class": "logging.handlers.RotatingFileHandler",
572
"level": "DEBUG",
573
"formatter": "detailed",
574
"filename": "app.log",
575
"maxBytes": 10485760, # 10MB
576
"backupCount": 5
577
}
578
},
579
loggers={
580
"litestar": {
581
"level": "INFO",
582
"handlers": ["console", "file"],
583
"propagate": False
584
},
585
"uvicorn": {
586
"level": "INFO",
587
"handlers": ["console"],
588
"propagate": False
589
}
590
},
591
log_exceptions="always",
592
configure_root_logger=True
593
)
594
595
app = Litestar(
596
route_handlers=[...],
597
logging_config=logging_config
598
)
599
```
600
601
### Structured Logging with Structlog
602
603
```python
604
from litestar.logging import StructLoggingConfig
605
import structlog
606
607
struct_logging_config = StructLoggingConfig(
608
processors=[
609
structlog.contextvars.merge_contextvars,
610
structlog.processors.add_log_level,
611
structlog.processors.TimeStamper(fmt="iso"),
612
structlog.dev.ConsoleRenderer()
613
],
614
wrapper_class=structlog.make_filtering_bound_logger(20), # INFO level
615
logger_factory=structlog.WriteLoggerFactory(),
616
cache_logger_on_first_use=True
617
)
618
619
app = Litestar(
620
route_handlers=[...],
621
logging_config=struct_logging_config
622
)
623
624
# Usage in route handlers
625
logger = structlog.get_logger()
626
627
@get("/api/users/{user_id:int}")
628
def get_user(user_id: int) -> dict:
629
logger.info("Fetching user", user_id=user_id)
630
# ... fetch user logic
631
logger.info("User fetched successfully", user_id=user_id, user_name="Alice")
632
return {"id": user_id, "name": "Alice"}
633
```
634
635
### Custom Cache Configuration
636
637
```python
638
from litestar.config import CacheConfig
639
from litestar.stores.redis import RedisStore
640
641
# Redis-backed caching
642
redis_store = RedisStore(url="redis://localhost:6379")
643
644
def custom_cache_key(request: Request) -> str:
645
"""Generate custom cache keys."""
646
return f"api:{request.method}:{request.url.path}:{hash(str(request.query_params))}"
647
648
cache_config = CacheConfig(
649
backend="redis",
650
expiration=300, # 5 minutes
651
cache_key_builder=custom_cache_key
652
)
653
654
@get("/expensive-operation", cache=True)
655
def expensive_operation() -> dict:
656
# This response will be cached
657
return {"result": "computed data", "timestamp": datetime.utcnow().isoformat()}
658
659
app = Litestar(
660
route_handlers=[expensive_operation],
661
stores={"cache": redis_store},
662
cache_config=cache_config
663
)
664
```
665
666
### Environment-Specific Configuration
667
668
```python
669
import os
670
from functools import lru_cache
671
672
@lru_cache()
673
def get_settings():
674
"""Get environment-specific settings."""
675
env = os.getenv("ENVIRONMENT", "development")
676
677
if env == "production":
678
return {
679
"debug": False,
680
"cors_origins": ["https://myapp.com"],
681
"compression": CompressionConfig(backend="brotli"),
682
"static_config": StaticFilesConfig(
683
path="/static",
684
directories=["static"],
685
send_as_attachment=False
686
)
687
}
688
else:
689
return {
690
"debug": True,
691
"cors_origins": ["http://localhost:3000"],
692
"compression": CompressionConfig(backend="gzip"),
693
"static_config": StaticFilesConfig(
694
path="/static",
695
directories=["static", "dev-assets"],
696
send_as_attachment=False
697
)
698
}
699
700
def create_app() -> Litestar:
701
settings = get_settings()
702
703
return Litestar(
704
route_handlers=[...],
705
debug=settings["debug"],
706
cors_config=CORSConfig(allow_origins=settings["cors_origins"]),
707
compression_config=settings["compression"],
708
static_files_config=[settings["static_config"]]
709
)
710
711
app = create_app()
712
```
713
714
## Types
715
716
```python { .api }
717
# Configuration protocol
718
class ConfigProtocol(Protocol):
719
"""Protocol for configuration classes."""
720
def __post_init__(self) -> None: ...
721
722
# File system protocol for static files
723
class FileSystemProtocol(Protocol):
724
def open(self, path: str) -> BinaryIO: ...
725
def stat(self, path: str) -> os.stat_result: ...
726
727
# Template engine protocol
728
class TemplateEngineProtocol(Protocol):
729
def render_template(self, template_name: str, context: dict[str, Any]) -> str: ...
730
731
# Logging types
732
GetLogger = Callable[..., Logger]
733
ExceptionLoggingHandler = Callable[[Request, Exception], None]
734
RequestLoggingHandler = Callable[[Request], None]
735
ResponseLoggingHandler = Callable[[Request, Response], None]
736
737
# Security requirement types
738
SecurityRequirement = dict[str, list[str]]
739
740
# OpenAPI component types
741
Contact = dict[str, str]
742
License = dict[str, str]
743
Server = dict[str, Any]
744
ExternalDocumentation = dict[str, str]
745
Components = dict[str, Any]
746
Tag = dict[str, Any]
747
PathItem = dict[str, Any]
748
Reference = dict[str, str]
749
```