Metadata-Version: 2.3
Name: granular-configuration-language
Version: 2.4.0
Summary: This general purpose configuration utility library allows your code to use YAML as a configuration language for internal and external parties, allowing configuration to be crafted from multiple sources and merged just before use, using YAML Tags for additional functionality.
License: MIT
Author: Eric Jensen
Author-email: eric.jensen42@gmail.com
Requires-Python: >=3.10
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Provides-Extra: printing
Requires-Dist: python-dateutil ; python_version < "3.11"
Requires-Dist: python-jsonpath
Requires-Dist: ruamel.yaml (>=0.18)
Requires-Dist: tabulate (>=0.9.0) ; extra == "printing"
Project-URL: Documentation, https://lifedox.github.io/granular-configuration-language/README.html
Project-URL: Homepage, https://lifedox.github.io/granular-configuration-language/README.html
Project-URL: Repository, https://github.com/lifedox/granular-configuration-language
Description-Content-Type: text/markdown

# `granular-configuration-language` – A General Purpose Configuration Utility Library

[![Coverage badge](https://raw.githubusercontent.com/lifedox/granular-configuration-language/python-coverage-comment-action-data/badge.svg)](https://github.com/lifedox/granular-configuration-language/tree/python-coverage-comment-action-data) ![Testing workflow](https://github.com/lifedox/granular-configuration-language/actions/workflows/testing.yaml/badge.svg?event=push) ![codeql workflow](https://github.com/lifedox/granular-configuration-language/actions/workflows/codeql-analysis.yaml/badge.svg?event=push)
<br>
[![pypi](https://img.shields.io/pypi/v/granular-configuration-language.svg)](https://pypi.org/project/granular-configuration-language/) [![pypi](https://img.shields.io/pypi/pyversions/granular-configuration-language.svg)](https://pypi.org/project/granular-configuration-language/) [![pypi](https://img.shields.io/pypi/types/granular-configuration-language.svg)](https://pypi.org/project/granular-configuration-language/) [![pypi](https://img.shields.io/pypi/l/granular-configuration-language.svg)](https://pypi.org/project/granular-configuration-language/)

> ⚠️ **This library is meant for trusted configuration files.** ⚠️

## How to get started?

See [Documentation - Getting Started](https://lifedox.github.io/granular-configuration-language/doc-spec/getting_started.html).

## How to install?

From [PyPI](https://pypi.org/project/granular-configuration-language/):

```shell
pip install granular-configuration-language
```

## Why does this exist?

This library exists to allow your code to use YAML as a configuration language for internal and external parties, allowing configuration to be crafted from multiple sources and merged just before use, using [YAML Tags](https://lifedox.github.io/granular-configuration-language/doc-spec/yaml.html) for additional functionality, and plugin support for creating custom YAML Tags.

Some use cases:

- You are writing a library to help connect to some databases. You want users to easily changes settings and defined databases by name.
  - Conceptual Example:
    - Library Code:
      ```python
      # database_util/config/config.py
      CONFIG = LazyLoadConfiguration(
          Path(__file___).parent / "config.yaml",
          "./database-util-config.yaml",
          "~/configs/database-util-config.yaml",
          base_path="database-util",
          env_location_var_name="ORG_COMMON_CONFIG_LOCATIONS",
      )
      ```
    - Library configuration:
      ```yaml
      # database_util/config/config.yaml
      database-util:
        common_settings:
          use_decimal: true
          encryption_type: secure
        databases: {} # Empty mapping, for users define
      ```
    - User application configuration:
      ```yaml
      # ~/configs/database-util-config.yaml
      database-util:
        common_settings:
          use_decimal: false
        databases:
          datebase1:
            location: http://somewhere
            user: !Mask ${DB_USERNAME}
            password: !Mask ${DB_PASSWORD}
      ```
    - Library Code with type annotations:
      ```python
      class CommonSettings(Configuration):
          use_decimal: bool
          encryption_type: str
      #
      class DatabaseSettings:
          location: str
          user: str
          password: str
      #
      class Settings(Configuration):
          common_settings: CommonSettings
          databases: Configuration[str, DatabaseSettings]
      #
      CONFIG = LazyLoadConfiguration(
          Path(__file___).parent / "config.yaml",
          "./database-util-config.yaml",
          "~/configs/database-util-config.yaml",
          base_path="database-util",
          env_location_var_name="ORG_COMMON_CONFIG_LOCATIONS",
      ).as_typed(Settings)
      ```
- You are deploying an application that has multiple deployment types with specific settings.
  - Conceptual Example:
    - Library Code:
      ```python
      # app/config/config.py
      CONFIG = LazyLoadConfiguration(
          Path(__file___).parent / "config.yaml",
          "./database-util-config.yaml",
          base_path="app",
      )
      ```
    - Base configuration:
      ```yaml
      # app/config/config.yaml
      app:
        log_as: really cool app name
        log_to: nowhere
      ```
    - AWS Lambda deploy:
      ```yaml
      # ./database-util-config.yaml
      app:
        log_to: std_out
      ```
    - Server deploy:
      ```yaml
      # ./database-util-config.yaml
      app:
        log_to: !Sub file://var/log/${$.app.log_as}.log
      ```
- You are writing a [`pytest`](https://docs.pytest.org/en/stable/) plugin that creates test data using named fixtures configured by the user.
  - Conceptual Examples:
    - Library Code:
      ```python
      # fixture_gen/config/config.py
      CONFIG = LazyLoadConfiguration(
          Path(__file___).parent / "fixture_config.yaml",
          *Path().rglob("fixture_config.yaml"),
          base_path="fixture-gen",
      ).config
      #
      for name, spec in CONFIG.fixtures:
          generate_fixture(name, spec)
      ```
    - Library configuration:
      ```yaml
      # fixture_gen/config/fixture_config.yaml
      fixture-gen:
        fixtures: {} # Empty mapping, for users define
      ```
    - User application configuration:
      ```yaml
      # fixture_config.yaml
      fixture-gen:
        fixtures:
          fixture1:
            api: does something
      ```

## Why the long name?

- It's "granular" because you can specify settings across multiple files at a fine granularity for overriding values.
- It is meant for trusted "configuration" files.
- Including "language" makes it clear that this is not the source of configuration, but a library for processing generic configuration files.
  - Feedback was that "granular-configuration" sounded like it was the source for configuration.
  - "Format" sounded weirder than "language".
  - Including "YAML" sounded like this was trying to be more than YAML, rather than just using YAML.

