pulpo-config


Namepulpo-config JSON
Version 2.0.2 PyPI version JSON
download
home_page
SummarySimple configuration library
upload_time2024-01-04 00:50:35
maintainer
docs_urlNone
authorMighty Pulpo
requires_python>=3.6
license
keywords configuration
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pulpo-config

[![Python CI](https://github.com/jasonray/pulpo-config/actions/workflows/python-package.yml/badge.svg?branch=main)](https://github.com/jasonray/pulpo-config/actions/workflows/python-package.yml)
[![PyPI version](https://badge.fury.io/py/pulpo-config.svg)](https://badge.fury.io/py/pulpo-config)

# Overview
The `Config` class provides a robust and flexible way to manage configuration settings in Python applications. It offers a simple interface to load, retrieve, and set configuration parameters, making it ideal for projects that require dynamic configuration handling.

# Key Features
## Easy Initialization
* Initialize with a dictionary of options or a JSON file.
* Automatically loads options from a file if a file path is provided.
## Flexible Option Retrieval
* Retrieve configuration values with support for nested keys.
* Environment variable substitution for values starting with `$ENV`.
## Command-Line Argument Processing
* Seamlessly integrates with `argparse` to update configurations from command-line arguments.
* Accepts arguments as a dictionary or `argparse.Namespace` object.
## JSON and String Representation
* Convert configurations to a JSON string or a standard string representation for easy debugging and logging.
## Specialized Value Retrieval
* Get configuration values as boolean or integer types with `getAsBool` and `getAsInt`.
* Handles type conversion and validation internally.
## Dynamic Configuration Setting
* Set configuration values with support for nested keys.
* Automatically creates intermediate dictionaries if needed.
# Benefits
* `Flexibility`: Easily manage configurations with varying levels of complexity.
* `Simplicity`: Streamline configuration management without extensive boilerplate code.
* `Compatibility`: Works seamlessly with common Python libraries like `argparse`.
* `Extensibility`: Customize and extend for more complex use cases or specific project needs.

# Basic Usage
``` python
from pulpo_config import Config

# Can load values manually through a dictionary..
config = Config(options={"database": {"host": "localhost", "port": 3306}})

# Or can load values manually..
config.set("api_key", "your-api-key")
config.set('database.host', 'localhost')

# Or can load options from a JSON config file
config = Config(json_file_path="config.json")

# Or can load from command line parameters
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--debug_mode', type=str)
config.process_args(parser)

# Retrieve a simple configuration value
api_key = config.get("api_key")

# Retrieve a simple configuration value
is_debug_mode = config.getAsBool("debug_mode")

# Retrieve a nested configuration value
db_host = config.get("database.host")
```

# API

# Terms: Config vs Options
In this library, I use the following terms:
* `config`: higher level class that offers ability to `set`/`get`, but also ability to load from a variety of sources or convenience methods
* `options`: low level dictionary of key-value pairs, used to initialize `Config`.  An `options` dictionary is used as the internal data store for the Config implementation

## Constructor
`Config` can be initialized with a dictionary or json formatted config file
* `Config(options: dict = None, json_file_path: str = None)`
  * With no parameters, will create a `Config` with no values
  * If `options` supplied, will initialize with the supplied key-value pairs.  Note that this does support nest key-value structures.
  * What if `options` is modified after being used to initialize `Config`?  Read [here]([url](https://github.com/jasonray/pulpo-config/issues/26)).
  * If `json_file_path` will load values from json formatted config file

## Load from sources
There are a set of methods to load from others sources.  Each for these will copy key-value pairs from parameter to `Config` and return the instance of `Config` (to support chain calls).  For example:
``` python
config = Config().fromOptions(options).fromKeyValue('k', 'v').fromJsonFile('config.json')
```

* `fromOptions(self, options: dict = None)`
  * load `Config` with the supplied key-value pairs.  Note that this does support nest key-value structures.
* `fromKeyValue(self, key: str, value: typing.Any)`
  * load `Config` with the supplied key-value pair.
* `fromJsonFile(self, file_path: str)`
  * load `Config` with the content from the supplied json file
* `fromYamlFile(self, file_path: str)`
  * load `Config` with the content from the supplied yaml file
* `fromArgumentParser(self, args: dict)`
  * load `Config` with command line arguments.
  * `args` can be either `argparser` or `argparser.namepspace` (the output from `argparser.parse()`)

## Load from sources
There are a set of methods to load from others sources.  Each for these will copy key-value pairs from parameter to `Config` and return the instance of `Config` (to support chain calls).  For example:
``` python
config = Config().fromOptions(options).fromKeyValue('k', 'v').fromJsonFile('config.json')
```

* `fromOptions(self, options: dict = None)`
  * load `Config` with the supplied key-value pairs.  Note that this does support nest key-value structures.
* `fromKeyValue(self, key: str, value: typing.Any)`
  * load `Config` with the supplied key-value pair.
* `fromKeyValueList(self, key_value_list)`
  * load `Config` with supplied key-value pairs.
* `fromJsonFile(self, file_path: str)`
  * load `Config` with the content from the supplied json file.
* `fromYamlFile(self, file_path: str)`
  * load `Config` with the content from the supplied yaml file.
* `fromArgumentParser(self, args: dict)`
  * load `Config` with command line arguments.
  * `args` can be either `argparser` or `argparser.namepspace` (the output from `argparser.parse()`)
 
## process_args
Passing a standard `argparser` or `argparser.namepspace` will integrate command line params into the config values
* `process_args(self, args: dict)`
 
## Set
* `set(key: str, value: typing.Any)`
  *  Will set key=value
  *  `value` can be of any type, and would be returned as set
  *  To set a nested value (such as if database option has child option of host), use a `.`: `config.set('database.host', 'localhost')`
  *  If nested value parent(s) (such as database in the above example) does not exist, those parent(s) will be created.

## Get
* `get(key: str, default_value: typing.Any = None)`
  * Will return the value associated the key
  * If there is not a set value, the the `default_value` is returned
  * To get a nested value, use a `.`: `config.get('database.host')`
* There are also specialized get methods to cast values to specific types
* `getAsBool(self, key: str, default_value: typing.Any = None) -> bool`
* `getAsInt(self, key: str, default_value: int = None) -> int`

## Keys, Values, Iterator
* `keys`: returns a list of keys.  If the options are nested, will return in dot notation (i.e. `['parent.k1', 'parent.k2']`)
* `values`: returns a dictionary with all key-value pairs.If the options are nested, will return in dot notation (i.e. `{'parent.k1': 'v1', 'parent.k2': 'v2'}`)
* `__iter__`: iterates over the list of keys (`for key in config`)

# More Usage Patterns

## Loading from dictionary

### Using fromOptions
``` python
from pulpo_config import Config
options={"api_key": "your-api-key", "database": {"host": "localhost", "port": 3306}}
config = Config().fromOptions(options)

api_key = config.get("api_key")    
host = config.get("database.host")   
```

### Using constructor
``` python
from pulpo_config import Config
config = Config(options={"api_key": "your-api-key", "database": {"host": "localhost", "port": 3306}}
api_key = config.get("api_key")    
host = config.get("database.host")    
```

## Manually setting config
``` python
from pulpo_config import Config
config = Config()
config.set("api_key", "your-api-key")
config.set("database.host", "localhost")
config.set("database.port", 3306)
api_key = config.get("api_key")
host = config.get("database.host")    
```

## Loading from json config file
Most use cases will utilize a config file to store options.  Below is a sample config
``` json
{
    "api_key": "your-api-key",
    "database": {
        "host": "localhost",
        "port": 3306
    }
}
```
Load this config file named `config.json` using the following:
```
from pulpo_config import Config
config = Config().fromJsonFile(file_path='config.json')
api_key = config.get("api_key")
host = config.get("database.host")    
```

## Loading from command line parameters
In a scenario in which you are using commandline params with `argparser`, use the following:
```
from pulpo_config import Config
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--api_key', type=str)
config = Config().fromArgumentParser(parser)
api_key = config.get("api_key")
```

## Get bool values
The `getAsBool` will cast the value to a bool.  For this purpose, the following are considered `true`: `[True, 'TRUE', 'T', '1', 1]` (case-insensitive)
```
if config.getAsBool("enable_feature_x"):
   # do stuff
```

## Get in values
The `getAsInt` will cast the value to an int.
```
port = config.getAsInt("database.host")
```

## Extending the Config class
For many application, I prefer to create an application-specific config class, extending from the provided config class.  Example:

``` python
class MyApplicationConfig(Config):

    def __init__(self, options: dict = None, json_file_path: str = None):
        super().__init__(options=options, json_file_path=json_file_path)

    @property
    def api_key(self: Config) -> str:
        return self.get('api_key')

    @property
    def debug_mode(self: Config) -> str:
        return self.getAsBool('debug_mode', False)
```

# Installation
Pulpo-config is avaiable on PyPi: https://pypi.org/project/pulpo-config/  
Install using
```
pip install pulpo-config
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "pulpo-config",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "configuration",
    "author": "Mighty Pulpo",
    "author_email": "jayray.net@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/0f/6c/e58ddfaf32fa4c7e46d611d1500ca322994b343aa95123a459bad7cb7e8c/pulpo-config-2.0.2.tar.gz",
    "platform": null,
    "description": "# pulpo-config\n\n[![Python CI](https://github.com/jasonray/pulpo-config/actions/workflows/python-package.yml/badge.svg?branch=main)](https://github.com/jasonray/pulpo-config/actions/workflows/python-package.yml)\n[![PyPI version](https://badge.fury.io/py/pulpo-config.svg)](https://badge.fury.io/py/pulpo-config)\n\n# Overview\nThe `Config` class provides a robust and flexible way to manage configuration settings in Python applications. It offers a simple interface to load, retrieve, and set configuration parameters, making it ideal for projects that require dynamic configuration handling.\n\n# Key Features\n## Easy Initialization\n* Initialize with a dictionary of options or a JSON file.\n* Automatically loads options from a file if a file path is provided.\n## Flexible Option Retrieval\n* Retrieve configuration values with support for nested keys.\n* Environment variable substitution for values starting with `$ENV`.\n## Command-Line Argument Processing\n* Seamlessly integrates with `argparse` to update configurations from command-line arguments.\n* Accepts arguments as a dictionary or `argparse.Namespace` object.\n## JSON and String Representation\n* Convert configurations to a JSON string or a standard string representation for easy debugging and logging.\n## Specialized Value Retrieval\n* Get configuration values as boolean or integer types with `getAsBool` and `getAsInt`.\n* Handles type conversion and validation internally.\n## Dynamic Configuration Setting\n* Set configuration values with support for nested keys.\n* Automatically creates intermediate dictionaries if needed.\n# Benefits\n* `Flexibility`: Easily manage configurations with varying levels of complexity.\n* `Simplicity`: Streamline configuration management without extensive boilerplate code.\n* `Compatibility`: Works seamlessly with common Python libraries like `argparse`.\n* `Extensibility`: Customize and extend for more complex use cases or specific project needs.\n\n# Basic Usage\n``` python\nfrom pulpo_config import Config\n\n# Can load values manually through a dictionary..\nconfig = Config(options={\"database\": {\"host\": \"localhost\", \"port\": 3306}})\n\n# Or can load values manually..\nconfig.set(\"api_key\", \"your-api-key\")\nconfig.set('database.host', 'localhost')\n\n# Or can load options from a JSON config file\nconfig = Config(json_file_path=\"config.json\")\n\n# Or can load from command line parameters\nimport argparse\nparser = argparse.ArgumentParser()\nparser.add_argument('--debug_mode', type=str)\nconfig.process_args(parser)\n\n# Retrieve a simple configuration value\napi_key = config.get(\"api_key\")\n\n# Retrieve a simple configuration value\nis_debug_mode = config.getAsBool(\"debug_mode\")\n\n# Retrieve a nested configuration value\ndb_host = config.get(\"database.host\")\n```\n\n# API\n\n# Terms: Config vs Options\nIn this library, I use the following terms:\n* `config`: higher level class that offers ability to `set`/`get`, but also ability to load from a variety of sources or convenience methods\n* `options`: low level dictionary of key-value pairs, used to initialize `Config`.  An `options` dictionary is used as the internal data store for the Config implementation\n\n## Constructor\n`Config` can be initialized with a dictionary or json formatted config file\n* `Config(options: dict = None, json_file_path: str = None)`\n  * With no parameters, will create a `Config` with no values\n  * If `options` supplied, will initialize with the supplied key-value pairs.  Note that this does support nest key-value structures.\n  * What if `options` is modified after being used to initialize `Config`?  Read [here]([url](https://github.com/jasonray/pulpo-config/issues/26)).\n  * If `json_file_path` will load values from json formatted config file\n\n## Load from sources\nThere are a set of methods to load from others sources.  Each for these will copy key-value pairs from parameter to `Config` and return the instance of `Config` (to support chain calls).  For example:\n``` python\nconfig = Config().fromOptions(options).fromKeyValue('k', 'v').fromJsonFile('config.json')\n```\n\n* `fromOptions(self, options: dict = None)`\n  * load `Config` with the supplied key-value pairs.  Note that this does support nest key-value structures.\n* `fromKeyValue(self, key: str, value: typing.Any)`\n  * load `Config` with the supplied key-value pair.\n* `fromJsonFile(self, file_path: str)`\n  * load `Config` with the content from the supplied json file\n* `fromYamlFile(self, file_path: str)`\n  * load `Config` with the content from the supplied yaml file\n* `fromArgumentParser(self, args: dict)`\n  * load `Config` with command line arguments.\n  * `args` can be either `argparser` or `argparser.namepspace` (the output from `argparser.parse()`)\n\n## Load from sources\nThere are a set of methods to load from others sources.  Each for these will copy key-value pairs from parameter to `Config` and return the instance of `Config` (to support chain calls).  For example:\n``` python\nconfig = Config().fromOptions(options).fromKeyValue('k', 'v').fromJsonFile('config.json')\n```\n\n* `fromOptions(self, options: dict = None)`\n  * load `Config` with the supplied key-value pairs.  Note that this does support nest key-value structures.\n* `fromKeyValue(self, key: str, value: typing.Any)`\n  * load `Config` with the supplied key-value pair.\n* `fromKeyValueList(self, key_value_list)`\n  * load `Config` with supplied key-value pairs.\n* `fromJsonFile(self, file_path: str)`\n  * load `Config` with the content from the supplied json file.\n* `fromYamlFile(self, file_path: str)`\n  * load `Config` with the content from the supplied yaml file.\n* `fromArgumentParser(self, args: dict)`\n  * load `Config` with command line arguments.\n  * `args` can be either `argparser` or `argparser.namepspace` (the output from `argparser.parse()`)\n \n## process_args\nPassing a standard `argparser` or `argparser.namepspace` will integrate command line params into the config values\n* `process_args(self, args: dict)`\n \n## Set\n* `set(key: str, value: typing.Any)`\n  *  Will set key=value\n  *  `value` can be of any type, and would be returned as set\n  *  To set a nested value (such as if database option has child option of host), use a `.`: `config.set('database.host', 'localhost')`\n  *  If nested value parent(s) (such as database in the above example) does not exist, those parent(s) will be created.\n\n## Get\n* `get(key: str, default_value: typing.Any = None)`\n  * Will return the value associated the key\n  * If there is not a set value, the the `default_value` is returned\n  * To get a nested value, use a `.`: `config.get('database.host')`\n* There are also specialized get methods to cast values to specific types\n* `getAsBool(self, key: str, default_value: typing.Any = None) -> bool`\n* `getAsInt(self, key: str, default_value: int = None) -> int`\n\n## Keys, Values, Iterator\n* `keys`: returns a list of keys.  If the options are nested, will return in dot notation (i.e. `['parent.k1', 'parent.k2']`)\n* `values`: returns a dictionary with all key-value pairs.If the options are nested, will return in dot notation (i.e. `{'parent.k1': 'v1', 'parent.k2': 'v2'}`)\n* `__iter__`: iterates over the list of keys (`for key in config`)\n\n# More Usage Patterns\n\n## Loading from dictionary\n\n### Using fromOptions\n``` python\nfrom pulpo_config import Config\noptions={\"api_key\": \"your-api-key\", \"database\": {\"host\": \"localhost\", \"port\": 3306}}\nconfig = Config().fromOptions(options)\n\napi_key = config.get(\"api_key\")    \nhost = config.get(\"database.host\")   \n```\n\n### Using constructor\n``` python\nfrom pulpo_config import Config\nconfig = Config(options={\"api_key\": \"your-api-key\", \"database\": {\"host\": \"localhost\", \"port\": 3306}}\napi_key = config.get(\"api_key\")    \nhost = config.get(\"database.host\")    \n```\n\n## Manually setting config\n``` python\nfrom pulpo_config import Config\nconfig = Config()\nconfig.set(\"api_key\", \"your-api-key\")\nconfig.set(\"database.host\", \"localhost\")\nconfig.set(\"database.port\", 3306)\napi_key = config.get(\"api_key\")\nhost = config.get(\"database.host\")    \n```\n\n## Loading from json config file\nMost use cases will utilize a config file to store options.  Below is a sample config\n``` json\n{\n    \"api_key\": \"your-api-key\",\n    \"database\": {\n        \"host\": \"localhost\",\n        \"port\": 3306\n    }\n}\n```\nLoad this config file named `config.json` using the following:\n```\nfrom pulpo_config import Config\nconfig = Config().fromJsonFile(file_path='config.json')\napi_key = config.get(\"api_key\")\nhost = config.get(\"database.host\")    \n```\n\n## Loading from command line parameters\nIn a scenario in which you are using commandline params with `argparser`, use the following:\n```\nfrom pulpo_config import Config\nimport argparse\nparser = argparse.ArgumentParser()\nparser.add_argument('--api_key', type=str)\nconfig = Config().fromArgumentParser(parser)\napi_key = config.get(\"api_key\")\n```\n\n## Get bool values\nThe `getAsBool` will cast the value to a bool.  For this purpose, the following are considered `true`: `[True, 'TRUE', 'T', '1', 1]` (case-insensitive)\n```\nif config.getAsBool(\"enable_feature_x\"):\n   # do stuff\n```\n\n## Get in values\nThe `getAsInt` will cast the value to an int.\n```\nport = config.getAsInt(\"database.host\")\n```\n\n## Extending the Config class\nFor many application, I prefer to create an application-specific config class, extending from the provided config class.  Example:\n\n``` python\nclass MyApplicationConfig(Config):\n\n    def __init__(self, options: dict = None, json_file_path: str = None):\n        super().__init__(options=options, json_file_path=json_file_path)\n\n    @property\n    def api_key(self: Config) -> str:\n        return self.get('api_key')\n\n    @property\n    def debug_mode(self: Config) -> str:\n        return self.getAsBool('debug_mode', False)\n```\n\n# Installation\nPulpo-config is avaiable on PyPi: https://pypi.org/project/pulpo-config/  \nInstall using\n```\npip install pulpo-config\n```\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Simple configuration library",
    "version": "2.0.2",
    "project_urls": null,
    "split_keywords": [
        "configuration"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c574fdd8078ab9af5e5c1a151971f7ceb73fc403393bef223a8044640d0a6ad6",
                "md5": "b26720d6d8d252069e435829f6ca3d90",
                "sha256": "9fbc80bb1b20d16e64efb3e48ff643c837ca68cca73743017dee200f280cb0a1"
            },
            "downloads": -1,
            "filename": "pulpo_config-2.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b26720d6d8d252069e435829f6ca3d90",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 6782,
            "upload_time": "2024-01-04T00:50:33",
            "upload_time_iso_8601": "2024-01-04T00:50:33.502476Z",
            "url": "https://files.pythonhosted.org/packages/c5/74/fdd8078ab9af5e5c1a151971f7ceb73fc403393bef223a8044640d0a6ad6/pulpo_config-2.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0f6ce58ddfaf32fa4c7e46d611d1500ca322994b343aa95123a459bad7cb7e8c",
                "md5": "913186dfb6aba627b7cf6a06fbd9fe05",
                "sha256": "2b8d6a1912fa0c302af27254432632186d46bedb3379d14e36bea2ae65d31576"
            },
            "downloads": -1,
            "filename": "pulpo-config-2.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "913186dfb6aba627b7cf6a06fbd9fe05",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 6705,
            "upload_time": "2024-01-04T00:50:35",
            "upload_time_iso_8601": "2024-01-04T00:50:35.159665Z",
            "url": "https://files.pythonhosted.org/packages/0f/6c/e58ddfaf32fa4c7e46d611d1500ca322994b343aa95123a459bad7cb7e8c/pulpo-config-2.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-04 00:50:35",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "pulpo-config"
}
        
Elapsed time: 0.14744s