API Reference¶
Auto-generated from source docstrings.
Core¶
layerclass ¶
Converts a plain class into a layered configuration object.
The decorated class gains full support for deterministic multi-source
config merging: load values from files, environment variables, and remote
stores; merge them in priority order; resolve ${variable} references;
validate by category; and freeze the result for safe sharing across threads.
Methods added to the class
layer(other, rules=None): Merge another config on top. Nested
@layerclass fields are recursively merged. rules is a
{field_name: LayerRule} dict controlling merge strategy
(OVERRIDE, PRESERVE, MERGE, APPEND).
validate(categories=None, fields=None): Run validation rules.
Pass a list of category names to run only those; None runs
bare (uncategorized) rules only; "*" runs everything.
resolve(): Resolve all ${field_name} interpolations in-place.
copy(): Deep copy the config instance.
to_dict(redact=False, by_alias=False): Export as a plain dict.
explain(full_history=False, redact=True): Structured info about
current values, sources, and types—great for debugging.
diff(other): Compare two configs; returns a list of changed fields.
freeze() / frozen: Prevent further mutation of field values.
json_schema(): Generate a JSON Schema dict from field definitions.
get(field, default=None): Dot-notation field access with fallback.
set(field, value, strict=False, source="set()"): Dot-notation setter
with optional immediate single-field validation.
Class-level attributes added
_field_defs: {name: FieldDef} schema from field() declarations.
_sources: Per-instance {name: SourceHistory} tracking provenance.
_computed_fields: {name: fn} for @computed_field methods.
Example
@layerclass class DatabaseConfig: host: str = field(str, default="localhost", description="DB host") port: int = field(int, default=5432, server=[require, is_port]) url: str = field(str, default="${host}:${port}")
@computed_field
def dsn(self) -> str:
return f"postgresql://{self.host}:{self.port}/mydb"
Source code in src/layer/core.py
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 | |
field ¶
field(
type_hint: type,
*uncategorized_rules,
default: Any = None,
meta: dict[str, Any] = None,
description: str = None,
secret: bool = False,
parser: Any = None,
alias: str = None,
aliases: list[str] = None,
env: str = None,
reloadable: bool = True,
**category_rules,
) -> Any
Declares a configuration field with optional validation rules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
type_hint
|
type
|
The expected type of the field. |
required |
*uncategorized_rules
|
Validators that always run (bare rules). |
()
|
|
default
|
Any
|
Default value for the field. |
None
|
meta
|
dict[str, Any]
|
Arbitrary metadata dict (e.g. {"cli_option": click.option(...)}). |
None
|
description
|
str
|
Human-readable description of the field. |
None
|
alias
|
str
|
Alternate name used when loading from dicts/JSON/YAML (e.g. "apiKey"). |
None
|
aliases
|
list[str]
|
Additional fallback names tried in order after alias. |
None
|
env
|
str
|
Explicit environment variable name, overrides PREFIX_FIELD_NAME convention. |
None
|
**category_rules
|
Named categories mapping to lists of validators. e.g. cluster=[require], common=[one_of("json", "yaml")] |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
A FieldDef instance (replaced by the default value after @layer_obj processes it). |
Source code in src/layer/core.py
FieldDef ¶
Metadata about a single configuration field.
Source code in src/layer/core.py
computed_field ¶
Marks a method as a computed (read-only, dynamic) field.
The decorated method is exposed as a property evaluated on each access and
is automatically included in to_dict() and explain(). Attempting to
assign a value to a computed field raises AttributeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
The method to promote to a computed field. Must accept only |
required |
Returns:
| Type | Description |
|---|---|
|
The same callable with |
|
|
|
Example
@layerclass class ServiceConfig: timeout_base: int = field(int, default=10) retry_count: int = field(int, default=3)
@computed_field
def total_timeout(self) -> int:
"""Total max wait across all retries."""
return self.timeout_base * self.retry_count
Source code in src/layer/core.py
parser ¶
Marks a method as a data parser for the specified field(s).
By default, the method is called after type coercion but before the value is
written to the field. If before_coerce=True is provided, it runs before
the value is coerced by the type resolution engine.
The method receives the current value and must return the transformed value. It runs during solidify(), solidify_env(), and set().
Usage
@parser("endpoint") def _clean_endpoint(self, value: str) -> str: return value.strip().rstrip("/")
@parser("status", before_coerce=True) def _parse_status(self, value: Any) -> str: if isinstance(value, dict) and "status" in value: return value["status"] return value
Source code in src/layer/core.py
validator ¶
Marks a method as a stateful validator for the specified field(s).
Called once per listed field during validate(). The method receives (self, field_name, value) and should raise ValidationError if invalid. If categories is omitted the validator runs on every validate() call (bare).
Usage
@validator("cert_path", "key_path") def _files_exist(self, field_name, value): if value and not os.path.exists(value): raise ValidationError(field_name, "File not found", "path_check", "bare")
@validator("cert_path", categories=["production"]) def _certs_match(self, field_name, value): ...
Source code in src/layer/core.py
root_validator ¶
Marks a method as a cross-field (root) validator.
Called at the end of validate() with no arguments besides self. Should raise ConfigError (or ValidationError) if the overall state is invalid. If categories is omitted the validator runs on every validate() call.
Usage
@root_validator(categories=["database"]) def _check_connection(self): if self.dsn and self.host: raise ConfigError("Cannot specify both 'dsn' and 'host'.")
Source code in src/layer/core.py
Pipeline¶
ConfigPipeline ¶
Orchestrates multiple providers into a layered config instance.
Follows a strict separation of concerns:
- Load —
load()ingests all providers, merges overlays (with optionalLayerRuleper provider), resolves${variable}references, and freezes the live config. It never runs validation. - Validate — call
pipeline.validate(categories)explicitly after loading. - Hot-reload — providers with
watch=Truetrigger_reload()automatically when their source changes.
Example
pipeline = ( ConfigPipeline(AppConfig, mode=SolidifyMode.STRICT) .add_provider(FileProvider("base.yml")) .add_provider(EnvProvider("APP"), rules={"ports": LayerRule.APPEND}) ) config = pipeline.load() pipeline.validate(["server"]).raise_if_invalid()
Source code in src/layer/pipeline.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | |
__init__ ¶
Initialize the pipeline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
Any
|
A |
required |
mode
|
Optional |
None
|
|
observer
|
Optional |
None
|
|
logger
|
Logger
|
Optional |
None
|
Source code in src/layer/pipeline.py
add_provider ¶
Add a provider to the pipeline, optionally with per-field layering rules.
Providers are applied in order during load(). Later providers override
values from earlier ones, subject to any LayerRule overrides.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
A |
required | |
rules
|
dict
|
Optional |
None
|
Returns:
| Type | Description |
|---|---|
ConfigPipeline
|
|
Example
pipeline.add_provider(EnvProvider("APP"), rules={"ports": LayerRule.APPEND})
Source code in src/layer/pipeline.py
on_change ¶
Register a callback for field changes during hot-reload.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field_path
|
str
|
Dot-separated field path (e.g. |
required |
callback
|
Callable
|
Called with |
required |
Returns:
| Type | Description |
|---|---|
ConfigPipeline
|
|
Source code in src/layer/pipeline.py
load ¶
Execute all providers in order, merging results onto the live config.
The pipeline performs four operations in sequence:
- Read each provider and coerce its data via
solidify(). - Layer each overlay onto the live config using the provider's rules.
- Resolve all
${variable}interpolations. - Freeze the live config to prevent accidental mutation.
No validation is performed. Call pipeline.validate() separately.
Returns:
| Type | Description |
|---|---|
Any
|
The frozen live config instance. |
Source code in src/layer/pipeline.py
validate ¶
Run validation on the live config.
This is the correct place to trigger validation — never inside load().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
categories
|
Passed directly to |
None
|
Returns:
| Type | Description |
|---|---|
|
A |
Source code in src/layer/pipeline.py
start ¶
Start watching for changes from watchable providers.
Requires watchdog: pip install layer[watch]
Source code in src/layer/pipeline.py
Solidification¶
solidify ¶
solidify(
data: dict[str, Any],
target: type,
source: str = "unknown",
check: list[str] | None = None,
strict: bool = False,
coerce: bool = True,
mode: Optional[SolidifyMode] = None,
)
Converts loose data (dict) into a typed config instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict[str, Any]
|
Input data dict. |
required |
target
|
type
|
Target @layer_obj class. |
required |
source
|
str
|
Source tag for tracking (e.g. "config.yml", "cli"). |
'unknown'
|
check
|
list[str] | None
|
If provided, validate these categories immediately after loading. |
None
|
strict
|
bool
|
If True, raise StructureError on unknown keys. (Legacy; prefer mode=) |
False
|
coerce
|
bool
|
If True, attempt type coercion based on field type hints. (Legacy; prefer mode=) |
True
|
mode
|
Optional[SolidifyMode]
|
SolidifyMode controlling strictness. Overrides strict/coerce when set. LAX — unknown keys ignored, coercion errors swallowed. STANDARD — unknown keys ignored, CoercionError bubbles. STRICT — unknown keys raise StructureError, no coercion. |
None
|
Returns:
| Type | Description |
|---|---|
|
An instance of target with values set from data. |
Source code in src/layer/solidify.py
solidify_file ¶
solidify_file(
path: str,
target: type,
source: str = None,
check: list[str] | None = None,
strict: bool = False,
coerce: bool = True,
mode: Optional[SolidifyMode] = None,
)
Load a config file (YAML, JSON, or TOML) and solidify it into a typed config.
Detects format from file extension. Requires the corresponding library to be installed (PyYAML for .yml/.yaml, tomllib/tomli for .toml).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Path to the config file. |
required |
target
|
type
|
Target @layer_obj class. |
required |
source
|
str
|
Source tag. Defaults to the file path. |
None
|
check
|
list[str] | None
|
Categories to validate after loading. |
None
|
strict
|
bool
|
Raise on unknown keys. (Legacy; prefer mode=) |
False
|
coerce
|
bool
|
Attempt type coercion. (Legacy; prefer mode=) |
True
|
mode
|
Optional[SolidifyMode]
|
SolidifyMode controlling strictness. Overrides strict/coerce when set. |
None
|
Returns:
| Type | Description |
|---|---|
|
An instance of target. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If path doesn't exist. |
StructureError
|
If file format is unsupported or parsing fails. |
Source code in src/layer/solidify.py
solidify_env ¶
solidify_env(
prefix: str,
target: type,
key_map: dict[str, Any] | None = None,
separator: str = "_",
)
Loads configuration from environment variables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prefix
|
str
|
Env var prefix (e.g. "AK" -> reads AK_ENDPOINT, AK_DEBUG, etc.) |
required |
target
|
type
|
Target @layer_obj class. |
required |
key_map
|
dict[str, Any] | None
|
Optional dict mapping field names to custom env var names. Values can be a string (single env var) or list of strings (fallback chain). |
None
|
separator
|
str
|
Separator between prefix and field name (default "_"). |
'_'
|
Returns:
| Type | Description |
|---|---|
|
An instance of target with values set from environment variables. |
Source code in src/layer/solidify.py
write_file ¶
Write a config object to a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
A @layer_obj instance. |
required | |
path
|
str
|
Output file path. |
required |
format
|
str
|
"yaml", "json", or "toml". Auto-detected from extension if None. |
None
|
by_alias
|
bool
|
If True, use field aliases as keys in the output file. |
False
|
Source code in src/layer/solidify.py
SolidifyMode ¶
Bases: Enum
Strictness mode for solidify() and ConfigPipeline.
LAX
Unknown keys are silently ignored. Type coercion errors are swallowed; the raw value is used as-is.
STANDARD (default): Unknown keys are silently ignored. Type coercion errors bubble up as CoercionError. STRICT: Unknown keys immediately raise StructureError. No coercion is attempted; incoming values must already match the type hint.
Source code in src/layer/solidify.py
Validation¶
require ¶
optional ¶
not_empty ¶
Value must not be empty (empty string, empty list, empty dict).
Unlike require (which checks for None), this catches "" and [] too.
Source code in src/layer/validation.py
one_of ¶
Value must be in the given set.
Source code in src/layer/validation.py
in_range ¶
Numeric value must be in [lo, hi].
Source code in src/layer/validation.py
is_port ¶
Shorthand for in_range(1, 65535) with a clearer error message.
Source code in src/layer/validation.py
is_url ¶
Value must look like a URL (http:// or https://).
Source code in src/layer/validation.py
is_positive ¶
Numeric value must be > 0.
Source code in src/layer/validation.py
regex ¶
String must match the given regex pattern.
Usage
endpoint: str = field(str, cluster=[regex(r"https?://.+")])
Source code in src/layer/validation.py
min_length ¶
String length >= n.
Source code in src/layer/validation.py
max_length ¶
String length <= n.
Source code in src/layer/validation.py
path_exists ¶
Path must exist on filesystem.
Source code in src/layer/validation.py
instance_of ¶
Value must be isinstance(val, expected_type).
Source code in src/layer/validation.py
each_item ¶
Apply a validator to each item in a list field.
Usage
partition_ids: list = field(list, each_item(min_length(1)), default=[])
Source code in src/layer/validation.py
requires_if ¶
Field is required when another field equals a specific value.
Usage
client_cert: str = field(str, cluster=[requires_if("tls_enabled", True)], default=None )
Source code in src/layer/validation.py
requires_any ¶
At least one of the listed fields must be set (not None).
Apply this validator to any ONE of the fields in the group.
Usage
token: str = field(str, auth=[requires_any("token", "username")], default=None) username: str = field(str, default=None)
Source code in src/layer/validation.py
requires_all ¶
All of the listed fields must be set together, or none of them.
Usage
client_cert: str = field(str, cluster=[requires_all("client_certificate", "client_key")], default=None )
Source code in src/layer/validation.py
mutually_exclusive ¶
At most one of the listed fields may be set.
Usage
token: str = field(str, auth=[mutually_exclusive("token", "username_password", "certificate")], default=None )
Source code in src/layer/validation.py
depends_on ¶
If this field is set, the listed fields must also be set.
Usage
client_key: str = field(str, cluster=[depends_on("client_certificate")], default=None )
Source code in src/layer/validation.py
Layering¶
LayerRule ¶
Providers¶
BaseProvider ¶
Bases: ABC
Abstract base class for configuration providers.
Every provider must implement read() -> dict. The pipeline calls providers in order, layering each result onto the config instance.
Source code in src/layer/providers/base.py
read
abstractmethod
¶
bind_schema ¶
Optional hook for providers that need to inspect the @layerclass schema (e.g., for deep mapping or explicit alias resolution) before reading.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
type
|
The target @layerclass type. |
required |
Source code in src/layer/providers/base.py
Sources¶
SourceHistory
dataclass
¶
Full history stack for a single field.
Source code in src/layer/sources.py
current
property
¶
The most recent source tag (backward-compatible with old _sources[name]).
Exceptions¶
ConfigError ¶
ValidationError ¶
Bases: ConfigError
One or more validation rules failed.
Source code in src/layer/exceptions.py
StructureError ¶
Bases: ConfigError
Source data doesn't match schema (unknown keys in strict mode).
LayeringError ¶
Bases: ConfigError
Merge conflict or invalid rule application.
CoercionError ¶
Bases: ConfigError
Raised when a value cannot be coerced to the target type.
Used internally so Union handling can try the next candidate type on failure.
InterpolationError ¶
Bases: ConfigError
Raised on unresolvable or circular references.
InterpolationCycleError ¶
Bases: InterpolationError
Raised when a circular ${variable} reference is detected.
MissingDependencyError ¶
Bases: ConfigError
Raised when an optional dependency (boto3, watchdog, etc.) is not installed.
HotReloadError ¶
Bases: ConfigError
Raised when an error occurs during hot-reload of configuration.
Exporters¶
to_json_schema ¶
Return the JSON Schema dict for a @layerclass.
Wraps config_cls.json_schema() and returns the result directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_cls
|
type
|
A |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A JSON Schema dict (draft-07). |
Source code in src/layer/exporters.py
to_yaml ¶
Generate a YAML configuration template from a @layerclass.
Non-secret fields are emitted with their default values. Secret fields are omitted and replaced with a commented-out placeholder. Field descriptions are emitted as YAML comments above the fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_cls
|
type
|
A |
required |
Returns:
| Type | Description |
|---|---|
str
|
A YAML string suitable for saving as |
Source code in src/layer/exporters.py
to_dotenv_template ¶
Generate a .env file template from a @layerclass definition.
Each field becomes one KEY=<default> line, with its description emitted
as a # comment above the line. Nested @layerclass fields are rendered
as a labelled section. Secret fields have their default replaced with
<secret>.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_cls
|
type
|
A |
required |
prefix
|
str
|
Optional env var prefix (e.g. |
''
|
Returns:
| Type | Description |
|---|---|
str
|
A multi-line string suitable for saving as |
Example
@layerclass class Config: host: str = field(str, default="localhost", description="Database host") port: int = field(int, default=5432)
print(to_dotenv_template(Config, prefix="APP"))
# Database host¶
APP_HOST=localhost¶
APP_PORT=5432¶
Source code in src/layer/exporters.py
to_configmap ¶
Generate a Kubernetes ConfigMap YAML string from a @layerclass.
Non-secret fields are emitted as ConfigMap data entries. Secret fields are omitted with a comment indicating they belong in a Secret resource.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_cls
|
type
|
A |
required |
name
|
str
|
The |
'app-config'
|
Returns:
| Type | Description |
|---|---|
str
|
A YAML string suitable for |
Example
print(to_configmap(AppConfig, name="my-app"))
apiVersion: v1¶
kind: ConfigMap¶
metadata:¶
name: my-app¶
data:¶
HOST: localhost¶
PORT: "5432"¶
Source code in src/layer/exporters.py
Observers¶
BasePipelineObserver ¶
Abstract base class for pipeline lifecycle observers.
All methods are no-ops by default. Subclass and override only the hooks you need.
Example
class MetricsObserver(BasePipelineObserver): def on_hot_reload_triggered(self, diffs): statsd.increment("config.reload", tags=[f"changes:{len(diffs)}"])
def on_hot_reload_locked(self, field):
statsd.increment("config.reload.locked", tags=[f"field:{field}"])
Source code in src/layer/observers.py
on_provider_read ¶
Called after a provider successfully reads its data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider_name
|
str
|
The |
required |
data
|
dict
|
The raw dict returned by the provider. |
required |
on_coercion_error ¶
Called when a type coercion fails (LAX mode swallows the error).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field
|
str
|
The field name that failed coercion. |
required |
value
|
Any
|
The raw value that could not be coerced. |
required |
target_type
|
type
|
The target type that coercion was attempted for. |
required |
error
|
Exception
|
The original exception. |
required |
Source code in src/layer/observers.py
on_layer_merged ¶
Called after each provider's overlay is layered onto the live config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider_name
|
str
|
The |
required |
rules_applied
|
dict
|
The |
required |
Source code in src/layer/observers.py
on_hot_reload_triggered ¶
Called when a hot-reload detects one or more field changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
diffs
|
list
|
List of diff dicts (field, old_value, new_value, …) from
|
required |
on_hot_reload_locked ¶
Called when a hot-reload is skipped for a reloadable=False field.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field
|
str
|
Dot-notation path of the locked field. |
required |
LoggerObserver ¶
Bases: BasePipelineObserver
Observer that emits structured log messages via a standard logging.Logger.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logger
|
Logger
|
A |
required |
Example
import logging pipeline = ConfigPipeline(AppConfig, logger=logging.getLogger("myapp"))