Include Schemes¶
Loaders for !include directives. Each scheme handles a different content source.
file:path¶
Load from the filesystem.
database: !include file:db.yaml
nested: !include file:configs/nested/settings.yaml
home: !include file:~/defaults.yaml
- Paths are resolved relative to the current working directory.
- Extension search: if the exact path is not found, Dracon tries
.yamland.ymlsuffixes automatically. - File context variables (
DIR,FILE,FILE_PATH,FILE_STEM,FILE_EXT,FILE_LOAD_TIME,FILE_LOAD_TIME_UNIX,FILE_LOAD_TIME_UNIX_MS,FILE_SIZE) are set and available in${...}expressions within the loaded file. ~is expanded viaPath.expanduser().
pkg:package:path¶
Load from a Python package's bundled resources via importlib.resources.
Format: pkg:PACKAGE_NAME:RESOURCE_PATH
env:VAR_NAME¶
Load the value of an environment variable as a YAML string.
The value is parsed as YAML, so env:PORT where PORT=8080 yields an integer, not a string.
Raises FileNotFoundError if the variable is not set. Use !include? for optional env vars.
var:var_name¶
Load a value from the current interpolation context (in-memory).
The variable is looked up in the loader's context dict. Useful for including values defined by !define or injected programmatically.
raw:path¶
Load a file as plain text without YAML parsing. The raw string becomes a scalar node.
Same path resolution and extension behavior as file:.
rawpkg:package:path¶
Load a package resource as plain text without YAML parsing.
Format: rawpkg:PACKAGE_NAME:RESOURCE_PATH
cascade:path¶
Walk up the directory tree from the current file's DIR (or CWD), collecting all files matching the relative path. Files are merged root-first, so the closest file has the highest priority.
This finds every .myapp.yaml from the current directory up to the filesystem root, then merges them with the outermost (root-level) file as the base and the closest file winning on conflicts.
Custom merge strategy¶
The merge key spec is prepended before the path, enclosed in {...} and/or [...], followed by :.
Default merge strategy: <<{<+}[<~] (recursive append, new wins).
Path requirements¶
- Must be a relative path (absolute paths raise
ValueError). - Raises
FileNotFoundErrorif no matching files are found anywhere in the directory hierarchy.
Selectors¶
Any scheme can include a @keypath selector to extract a subtree from the loaded content:
db_host: !include file:config.yaml@database.host
port: !include pkg:mypackage:defaults.yaml@server.port
The keypath is applied after loading and parsing. See KeyPaths for path syntax.
Custom Loaders¶
Register additional schemes via custom_loaders in DraconLoader:
def read_from_s3(path, node=None, draconloader=None, **_):
content = boto3.client('s3').get_object(...)['Body'].read().decode()
return content, {} # (yaml_string, context_dict)
loader = DraconLoader(custom_loaders={"s3": read_from_s3})
A loader function receives:
| Argument | Description |
|---|---|
path |
Everything after the scheme: prefix |
node |
The IncludeNode (access .context, .value, etc.) |
draconloader |
The current DraconLoader instance |
It must return a tuple of (content, context_dict) where:
contentis either a YAML string (will be parsed) or aCompositionResult(used directly)context_dictis a dict of context variables to inject (can be empty)