Name | pulpo-config JSON |
Version |
2.0.2
JSON |
| download |
home_page | |
Summary | Simple configuration library |
upload_time | 2024-01-04 00:50:35 |
maintainer | |
docs_url | None |
author | Mighty 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"
}