CarlyleConfig
Small Hierarchical Configuration loader
Examples
Simple example
import argparse
from carlyleconfig import deriveconfig, derive
from carlyleconfig.plugins import ArgParsePlugin
# Load the ArgParsePlugin and attach it to the default derive object.
# this gives us access to the derive.field().with_argparse(...) method.
# The with_constant and with_env_var methods are plugins that are loaded
# by default since they are so simple.
PARSER_PLUGIN = ArgParsePlugin()
derive.plugins = [PARSER_PLUGIN]
@deriveconfig
class Config:
# Derive the debug field from the following sources in order:
# 1) an argparse argument named --debug.
# Defaults to None if not provided so we can fall through to the next case
# if not provided. Uses argparse's store_true action if it is provided so we get a bool
# value.
# 2) the EXAMPLE_DEBUG environment variable. The string env var is cast to a bool.
# If not present None will be returned, falling through to the next case.
# 3) a constant value of False, this will always provide a value and should be treated
# as the last fallback case.
debug: bool = (
derive.field()
.from_argparse("--debug", action="store_true", default=None)
.from_env_var("EXAMPLE_DEBUG", cast=bool)
.from_constant(False)
)
def main():
parser = argparse.ArgumentParser()
# Binding the parser to the ArgParsePlugin allows it to fill out extra
# arguments, and intercept the parse_args() call.
PARSER_PLUGIN.bind_parser(parser)
# Since we don't have any other arguments we don't need to save the args.
# the ArgParsePlugin intercepts the call and gets a copy of the parsed args
# to use when populating the Config object.
parser.parse_args()
# Instantiating a Config object resolves the derive chains into concrete values.
# Explicit overrides can be provided as well, such as Config(debug=True).
config = Config()
print(f'DEBUG: {config.debug}')
if __name__ == "__main__":
main()
$ python samples/example.py
DEBUG: False
$ EXAMPLE_DEBUG=1 python samples/example.py
DEBUG: True
$ python samples/example.py --debug
DEBUG: True
Loading from files
This example adds a file as an additional source of configuration. And the added indirection of allowing config to change where the config file is loaded from.
import argparse
from carlyleconfig import deriveconfig, derive
from carlyleconfig.plugins import ArgParsePlugin
# Load the ArgParsePlugin and attach it to the default derive object.
# this gives us access to the derive.field().with_argparse(...) method.
# The with_constant, with_file, and with_env_var methods are plugins that are
# loaded by default since they require no extra steps.
PARSER_PLUGIN = ArgParsePlugin()
derive.plugins = [PARSER_PLUGIN]
@deriveconfig
class Config:
# Derive the filepath field from the first non-None source below:
# 1) The command line argument --config-path. If not provided it will be
# None falling through to the next case.
# 2) The environment variable EXAMPLE_CONFIG_PATH if present.
# 3) Constant value of ~/.default-config.json
filepath: str = (
derive.field()
.from_argparse("--config-path", default=None)
.from_env_var('EXAMPLE_CONFIG_PATH')
.from_constant("~/.default-config.json")
)
# Derive the debug field from the following sources in order:
# 1) an argparse argument named --debug.
# Defaults to None if not provided so we can fall through to the next case
# if not provided. Uses argparse's store_true action if it is provided so we get a bool
# value.
# 2) the EXAMPLE_DEBUG environment variable. The string env var is cast to a bool.
# If not present None will be returned, falling through to the next case.
# 3) A file named filepath. filepath is a reference to the prior config key in this class.
# Since it is loaded first we can ues a reference to it here as if it were a concrete
# value.
# Once the file is read it will be parsed as json by the from_json_file method. Finally
# the object will be searched using the "DEBUG" jmespath expression, and the result of
# that is returned.
# 4) a constant value of False, this will always provide a value and should be treated
# as the last fallback case.
debug: bool = (
derive.field()
.from_argparse("--debug", action="store_true", default=None)
.from_env_var("EXAMPLE_DEBUG", cast=bool)
.from_json_file(filepath, jmespath='DEBUG')
.from_constant(False)
)
# Grab the full contents of the config file without any parsing by using
# the from_file method without any parser/selector.
# Provide a default of empty string in case the file doesn't exist.
raw_config_file: str = derive.field().from_file(filepath).from_constant("")
def main():
parser = argparse.ArgumentParser()
# Binding the parser to the ArgParsePlugin allows it to fill out extra
# arguments, and intercept the parse_args() call.
PARSER_PLUGIN.bind_parser(parser)
# Since we don't have any other arguments we don't need to save the args.
# the ArgParsePlugin intercepts the call and gets a copy of the parsed args
# to use when populating the Config object.
parser.parse_args()
# Instantiating a Config object resolves the derive chains into concrete values.
# Explicit overrides can be provided as well, such as Config(debug=True).
config = Config()
print(f"DEBUG: {config.debug}")
print(f'config file contents: "{config.raw_config_file}"')
if __name__ == "__main__":
main()
$ python samples/config-file.py
DEBUG: False
config file contents: ""
$ python samples/config-file.py --config-path samples/configs/debug.json
DEBUG: True
config file contents: "{
"DEBUG": true
}
"
$ python samples/config-file.py --config-path samples/configs/no-debug.json
DEBUG: False
config file contents: "
{
"DEBUG": false
}
"
$ python samples/config-file.py --config-path samples/configs/missing-config.json
DEBUG: False
config file contents: "{}
"
python samples/config-file.py --config-path samples/configs/missing-config.json --debug
DEBUG: True
config file contents: "{}
"
$ EXAMPLE_CONFIG_PATH=samples/configs/debug.json python samples/config-file.py
DEBUG: True
config file contents: "{
"DEBUG": true
}
"
$ EXAMPLE_CONFIG_PATH=samples/configs/debug.json python samples/config-file.py --config-path samples/configs/no-debug.json
DEBUG: False
config file contents: "
{
"DEBUG": false
}
"
$ EXAMPLE_CONFIG_PATH=samples/configs/debug.json python samples/config-file.py --config-path samples/configs/no-debug.json --debug
DEBUG: True
config file contents: "
{
"DEBUG": false
}
""
Metadata
Release files for carlyleconfig 2025.43.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| carlyleconfig-2025.43.1.tar.gz | 22.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| carlyleconfig-2025.43.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.3 kB
Release files / carlyleconfig-2025.43.1.tar.gz
| Download URL | carlyleconfig-2025.43.1.tar.gz |
|---|---|
| Size | 22.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0e522ecd43932978451decf721d6fdf0be3f9be209a028eb0f689a287f29b871
|
|
BLAKE2b-256 checksum How to use checksums |
4001002e89631dbb3aae8bfcd9f478b9ed0ffdf3930be1487ee346f4ba6d6233
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / carlyleconfig-2025.43.1-py3-none-any.whl
| Download URL | carlyleconfig-2025.43.1-py3-none-any.whl |
|---|---|
| Size | 19.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2366c43e92147a31511f0c144dcbc3762cd8936b677813e6e7616b03fbfee273
|
|
BLAKE2b-256 checksum How to use checksums |
97178b028adf038b039c1f17b696ffd53dd5c4047400d44d7a412ec8c442b3ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Security for carlyleconfig 2025.43.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.