Skip to main content

CarlyleConfig

Small Hierarchical Configuration loader

PyPI version

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)

Source distribution for carlyleconfig 2025.43.1
File Size Uploaded Provenance
carlyleconfig-2025.43.1.tar.gz 22.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for carlyleconfig 2025.43.1
File Interpreter ABI Platform
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page