ConfigSourceList#
- pydantic model tollan.config.sources.ConfigSourceList[source]#
A list of configuration sources with conditional loading.
ConfigSourceList manages multiple ConfigSource instances, evaluates their enable_if conditions, and merges them in order.
Caching#
Per-source caching can be enabled with enable_cache(). This caches the loaded data for each source independently, which is useful for expensive loads (e.g., file I/O, remote APIs). Cache control can be granular: specify which sources to cache via names or orders.
Example
>>> sources = ConfigSourceList(data=[ ... {"format": "dict", "source": {"base": True}, "order": 0}, ... { ... "format": "dict", "source": {"override": True}, ... "order": 1, "enable_if": "env == 'dev'" ... } ... ]) >>> config = sources.load(context={"env": "dev"}) >>> config {'base': True, 'override': True}
Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Show JSON schema
{ "title": "ConfigSourceList", "description": "A list of configuration sources with conditional loading.\n\nConfigSourceList manages multiple ConfigSource instances, evaluates\ntheir enable_if conditions, and merges them in order.\n\nCaching\n-------\nPer-source caching can be enabled with enable_cache(). This caches\nthe loaded data for each source independently, which is useful for\nexpensive loads (e.g., file I/O, remote APIs). Cache control can be\ngranular: specify which sources to cache via names or orders.\n\nExample:\n >>> sources = ConfigSourceList(data=[\n ... {\"format\": \"dict\", \"source\": {\"base\": True}, \"order\": 0},\n ... {\n ... \"format\": \"dict\", \"source\": {\"override\": True},\n ... \"order\": 1, \"enable_if\": \"env == 'dev'\"\n ... }\n ... ])\n >>> config = sources.load(context={\"env\": \"dev\"})\n >>> config\n {'base': True, 'override': True}", "type": "object", "properties": { "data": { "description": "List of configuration sources", "items": { "type": "object" }, "title": "Data", "type": "array" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "description": "Optional name for this source list", "title": "Name" } }, "required": [ "data" ] }
- Config:
frozen: bool = True
- Fields:
- Validators:
_check_data_order_and_sort»data_validate_arg»all fields_validate_order_constraints»all fields
- field data: Annotated[list[ConfigSource], WithJsonSchema({'type': 'array', 'items': {'type': 'object'}})] [Required]#
List of configuration sources
- Constraints:
json_schema = {‘type’: ‘array’, ‘items’: {‘type’: ‘object’}}
- Validated by:
_check_data_order_and_sort_validate_arg_validate_order_constraints
- field name: str | None = None#
Optional name for this source list
- Validated by:
_validate_arg_validate_order_constraints
- enable_cache(predicate: Callable[[ConfigSource], bool] | None = None, exclude: Callable[[ConfigSource], bool] | None = None) None[source]#
Enable per-source caching for sources matching predicate.
Caching is applied at the source level, not at the merged config level. This allows expensive sources (e.g., file I/O, remote APIs) to be cached while keeping mutable dict sources uncached.
- Parameters:
predicate (Callable[[ConfigSource], bool] | None, optional) – Function to select sources to cache. If None, cache all sources (unless excluded), by default None
exclude (Callable[[ConfigSource], bool] | None, optional) – Function to select sources to exclude from caching. Applied after predicate, by default None
Example –
>>> from tollan.config.sources import ConfigSourceList >>> sources = ConfigSourceList(data=[ ... {"format": "dict", "source": {"a": 1}, "order": 0, "name": "base"}, ... {"format": "dict", "source": {"b": 2}, "order": 1, "name": "env"} ... ])
>>> # Cache all except env >>> sources.enable_cache( ... exclude=lambda s: s.name == "env" ... )
>>> # Cache only YAML sources >>> sources.enable_cache( ... lambda s: isinstance(s, YamlConfigSource) ... )
>>> # Cache sources with specific orders >>> sources.enable_cache(lambda s: s.order > 5)
>>> sources._cache_config.enabled True
- get(predicate: Callable[[ConfigSource], bool], *, unique: Literal[True] = True) ConfigSource | None[source]#
- get(predicate: Callable[[ConfigSource], bool], *, unique: Literal[False]) list[ConfigSource]
Get config source(s) using a predicate function.
Provides maximum flexibility for source selection via predicate function.
- Parameters:
- Returns:
If unique=True – ConfigSource if exactly one match found, None if no match.
If unique=False – list[ConfigSource] with all matches (empty if no matches).
- Raises:
ValueError – If unique=True and multiple sources match the predicate.:
Examples
>>> from tollan.config.sources import ConfigSourceList >>> sources = ConfigSourceList(data=[ ... {"format": "dict", "source": {"a": 1}, "order": 0, "name": "base"}, ... {"format": "dict", "source": {"b": 2}, "order": 1, "name": "env"}, ... {"format": "dict", "source": {"c": 3}, "order": 2, "name": "cli"}, ... ])
>>> # Unique match (default) >>> source = sources.get(lambda s: s.name == "base") >>> source.order 0
>>> # Multiple matches with unique=False (non-base sources) >>> sources_list = sources.get( ... lambda s: s.name in {"env", "cli"}, unique=False ... ) >>> len(sources_list) 2 >>> [s.order for s in sources_list] [1, 2]
>>> # All sources >>> all_sources = sources.get(lambda s: True, unique=False) >>> len(all_sources) 3
- invalidate_cache(predicate: Callable[[ConfigSource], bool] | None = None) None[source]#
Invalidate cache for sources matching predicate or all sources.
- Parameters:
predicate (Callable[[ConfigSource], bool] | None, optional) – Function to select sources to invalidate. If None, invalidate all cached sources, by default None
Example –
>>> from tollan.config.sources import ConfigSourceList >>> sources = ConfigSourceList(data=[ ... {"format": "dict", "source": {"a": 1}, "order": 0, "name": "base"}, ... {"format": "dict", "source": {"b": 2}, "order": 1, "name": "env"} ... ]) >>> sources.enable_cache() >>> _ = sources.load() # Populate cache
>>> # Invalidate all >>> sources.invalidate_cache()
>>> # Invalidate specific sources >>> sources.invalidate_cache( ... lambda s: s.name == "env" ... ) >>> sources.invalidate_cache(lambda s: s.order > 5)
- load(context: dict[str, Any] | None = None) DictConfigT[source]#
Load and merge all enabled configuration sources.
Sources are evaluated for enable_if conditions, then loaded and merged in order (lower order first, higher order overrides).
If caching is enabled, individual sources may be cached based on the cache configuration.