<h1 align="center"> confiGOAT </h1>
confiGOAT is a powerful, flexible, and developer-friendly management tool for all your
environment variables and configurations. 🔥🔥🔥
## Features
Here are some of the features that confiGOAT provides:
- Manage all environment variables or configuration parameters from a single setup.
- Support all development, testing, and production environments.
- Define configurations once, use it everywhere.
- Define configuration parameters using both YAML and Python scripts.
- Cast values before using them.
- Powerful reference mechanism to reuse variables *from any levels at any levels in any direction*.
- Multiple resource types in the YAML to support the vast majority of use cases.
- Support both simple use cases and complex, multi-layered nested configurations.
- Use dynamic modules to access the parameters through import interface in Python.
- Use a single exposed API to interact with the layered configurations.
- Support nested structures to model the configurations as per business needs.
🎉🚀🌟
## Installation
confiGOAT can be installed with [pip](https://pip.pypa.io):
```bash
pip install configoat
```
Alternatively, you can grab the latest source code from [GitHub](https://github.com/aag13/configoat):
```bash
git clone https://github.com/aag13/configoat
cd configoat
pip install .
```
## How to Use
### Initial Setup
confiGOAT provides a user-friendly CLI command to initialize the configuration setup
for your project.
1. Go to the root directory of your project and run the following command
in the terminal.
```bash
configoat init
```
2. For the directory name, enter the name of the folder that will contain all
the configuration files and scripts. E.g. *"environments/"* will create a directory
inside the root directory of your project. Default is *"configs/"*.
3. For the main configuration file, provide a name that confiGOAT will look
for when initializing the setup for your project. (we will see how to do that
later). Default is *"main.yaml"*.
4. While selecting the type of configurations, you have 3 options. Choose the one that
best suits your specific project needs. 👇
- **Single (Only one YAML file)** : Use this for small projects where all your configurations will fit
in one single YAML file.
- **Nested (Parent-child YAML files)** : Use this for projects where it makes sense to structure the
configuration files in a nested hierarchy.
- **Nested with Scripts (Includes .py scripts)** : Use this for large-scale projects where some
configurations need to be resolved using python scripts on top of a multi-layered hierarchy.
For example, if you can fit all your configuration variables in a single file, choose option 1. Choose option
2 if you want to structure all the configuration parameters in separate files based on their types, such as,
security configurations in *security.yaml* file and database configurations in *database.yaml* file. Option 3
is best suited for cases where you need both the nested hierarchy structure and need to resolve values
for some parameters that require executing some code.
❄️❄️❄️
### Preparing Configuration Files
Now that you have set up the configuration folder and starting file(s), you need to populate all your
configuration and environment variables in the generated YAML and python script files.
1. First, open the *main.yaml* (or whatever name you gave during the initial setup) file.
2. Each YAML file has 2 root properties, namely *doc* and *resources*. 👇
- You can use *doc* to provide basic description on the type of environment or configuration variables
which are defined in this YAML.
- *resources* contains all the configuration variables that are defined in this file. If you want to
create a new variable, you need to define it inside *resources*.
```yaml
doc: 'This is the main config file where the processing starts from'
resources:
...
```
3. You can define 4 different types of resources in confiGOAT. 👇
- *normal* : Use this type if the value of the variable will be different for different environments. You can
use different data types for different environments, such as string, integer, float, boolean, list, and dictionary.
```yaml
var1:
type: 'normal'
value:
dev: 'value of var1 for dev'
stage: 'value of var1 for stage'
uat: 'value of var1 for uat'
production: 'value of var1 for production'
qa: 'value of var1 for qa'
```
- *common* : Use this type if the value of the variable will be same across all environments. We support
the following data types - string, integer, float, boolean, list, and dictionary.
```yaml
var2:
type: 'common'
value: "value of var2"
var3:
type: 'common'
value: False
var4:
type: 'common'
value: 100
var5:
type: 'common'
value: [ "Banana", "Mango", "Apple" ]
var6:
type: 'common'
value: {
"name": "Raihan The Boss",
"age": 66,
"address": {
"city": "Dhaka",
"country": "Bangladesh",
}
}
```
- *nested* : Use this type for a nested YAML file (Available if you chose option 2 or 3 during setup). *path*
is the relative path from the project root folder to that nested YAML file, e.g. *configs/yamls/nested.yaml*.
All the variables which are defined in the specified nested YAML file will be available under the
namespace of the *var7* variable. ✨
```yaml
var7:
type: 'nested'
path: 'path/from/project/root/to/nested.yaml'
```
- *script* : Use this type for a python script file (Available if you chose option 3 during setup). *path*
is the relative path from the project root folder to that nested script file, e.g. *configs/scripts/script.py*.
Only the variables which are defined in the *variable_list* property will be available from specified
nested script file under the namespace of the *var9* variable. ✨
```yaml
var9:
type: 'script'
variable_list: ['a', 'b', 'c', 'd', 'e']
path: 'path/from/project/root/to/script.py'
```
4. For the *nested* type, confiGOAT will process the specified YAML file **recursively**, so that if
the nested YAML file contains other *nested* variables, it will resolve all those nested YAML files
recursively as well. 👀
5. If you want to reuse the value from another variable using reference, either in the same file or any file
in the configuration hierarchy, you need to use **$ref(variable_name)** format by replacing the
variable_name with the actual variable in your configuration that you want to refer to. 👇
6. Let's consider a couple of scenarios to demonstrate how variable referencing works. 🌅
- First, you need to understand the difference between the *source* and *target* variables. Here,
*source* variable is the one whose reference is being used and *target* variable is the one that is
using the reference. 🎁🎁
- ***Target* variable in the main config YAML file** : If the *target* variable is in the main config file,
such as *main.yaml*, then you can accomplish that in two ways depending on where the *source*
variable is.
- **Source variable in the main config file** : If the *source* variable is in the main config
file, then use *$ref(SIBLING)* in the *target variable*. This will get the value from a variable
called *SIBLING* to the *target* variable like this. ✨
```yaml
target_var:
type: 'common'
value: "$ref(SIBLING)"
```
- **Source variable in a nested file** : If there is a *nested* variable called *nested1* and inside
the YAML of this file, there exists a variable called *varAA*, then the full *dot notation path* to this variable
from the main config file is *nested1.varAA*. So use *$ref(nested1.varAA)* in the *target variable*. ✨
```yaml
target_var:
type: 'common'
value: "$ref(nested1.varAA)"
```
- ***Target* variable in any other YAML/script file** : If the *target* variable is in any file other than
the main config file, then you can accomplish that in two ways depending on where the *source* variable is.
- **Source variable in the same file** : If the *source* variable is in the same file as the
*target variable*, then use *$ref(SIBLING)* in the *target variable*. This will get the value from a variable
called *SIBLING* to the *target* variable like this. ✨
```yaml
target_var:
type: 'common'
value: "$ref(SIBLING)"
```
- **Source variable in any other file** : If there is a *nested* variable called *nested1* in the
main config file and inside the YAML of this *nested* variable, there exists a variable called
*varAA*, then the full *dot notation path* to this variable is *@.nested1.varAA*.
So use *$ref(@.nested1.varAA)* in the *target variable*. ✨
```yaml
target_var:
type: 'common'
value: "$ref(@.nested1.varAA)"
```
- **So, when to use *@* in the reference**: If the *target* variable is in the root config file, then you don't need
to add *@* in the full *dot notation path*. Because you can use the dotted path to follow the nested
variable hierarchy since you are already in the root config file. However, if the *target* variable
is in anywhere other than the root config file, then you need to prepend the *dot notation path*
with *@* to indicate whether to start looking for the *nested* variable from the root file or the
current file. Starting the dotted path with *@* simply means to *start looking for this variable
from the root config file*. 🎂🎂
NOTE: Referencing a variable is bidirectional and depth agnostic, meaning that any variable can be referenced
**at any depth from any depth in any direction**, as long as no circular dependency is created during the
referencing of another variable. *Circular Dependency* means that definitions of two variables are dependent
on each other and neither variable can be resolved due to this dependency. In case of any circular dependency,
confiGOAT will raise an exception indicating the circular dependency.
🌟🌟🌟
### Using Configuration Parameters in the Project
Now that you have prepared the configurations for your project, you need to use them in your project.
1. First, you need to initialize and load all the configuration and environment variables.
```python3
from configoat import conf
conf.initialize(config="configs/main.yaml", env="dev", module="all_config")
```
- *config* denotes the path to the main configuration YAML file to start loading the variables from.
- *env* denotes which environment the variables should be loaded for.
- *module* denotes the name of the namespace under which all variables will be made available for the
dynamic module access.
- In practice, you don't want to hardcode the environment value like this, *env="dev"*. This way, you
won't be able to change it dynamically on the different environments your app is running on. We
recommend getting this value from another source that can be resolved during runtime. E.g. if you are
using confiGOAT in a Django app, then using CI/CD or starting script, inject the environment value
as the command line argument during the project run. Then, before initialization,
fetch this value from *os* like below,
```python3
import os
from configoat import conf
current_env = os.getenv("YOUR_ENVIRONMENT_VARIABLE")
conf.initialize(config="configs/main.yaml", env=current_env, module="all_config")
```
2. To access the configuration variables, you have 2 options.
- *Dot notation* : You can use the *conf* object to access any variable by providing its full
*dot notation path* from the root configuration file. *@* denotes the root of the configuration,
i.e. the main configuration file. You can also pass the *conf* variable around like any other variable in python
and access values like shown below.
```python3
print(conf("@.VARIABLE_NAME"))
print(conf("@.NESTED.VARIABLE_NAME"))
print(conf.get("@.VARIABLE_NAME"))
print(conf.get("@.NESTED.VARIABLE_NAME"))
```
- *Dynamic module* : Use python's module and import mechanism to access any configuration
variable. In this approach, you import the module that you defined during the initialization step,
e.g. *all_config*. When confiGOAT initialized your configuration variables, it also created dynamic
modules and attributes in those modules following your configuration nested hierarchy. All these
dynamic modules are inserted under the provided namespace, e.g. the *all_config* module name. After
initialization, you can import this module anywhere in your project and access the variables like any other modules
and their attributes. Some examples are given below on how variables can be accessed using dynamic module.
```python3
# accessing variables from the root module name, i.e. all_config
import all_config
print(all_config.var3)
print(all_config.var2.var4)
# importing all variables using * from the root module name, i.e. all_config
from all_config import *
print(var3)
print(var2.var4)
from all_config import var2 as current
print(current.var4)
```
**You can also provide a default value in case the variable is not found and a casting function to transform
the final value before returning. Casting and default value features are available only when
accessing values using *conf()* or *conf.get()***.
```python3
print(conf("@.VARIABLE_NAME", default=10, cast=int))
print(conf.get("@.VARIABLE_NAME", default=10, cast=int))
```
## Issues
Please let us know if you find any issue by [filing an issue.](https://github.com/aag13/configoat/issues)
## Maintainers
- [@banna](https://github.com/Hasan-Ul-Banna) (Hasan-UL-Banna)
- [@galib](https://github.com/aag13) (Asadullah Al Galib)
👋
=======
History
=======
Raw data
{
"_id": null,
"home_page": "https://github.com/aag13/configoat",
"name": "configoat",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.5",
"maintainer_email": "",
"keywords": "configoat",
"author": "Hasan-UL-Banna, Asadullah Al Galib",
"author_email": "hasanulbanna04056@gmail.com, asadullahgalib13@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/46/3a/40bd70f5b1d93b8dffd0063cd9cb2c16e37aa57a129986f61b93171a82b0/configoat-0.1.6.tar.gz",
"platform": null,
"description": "<h1 align=\"center\"> confiGOAT </h1>\n\nconfiGOAT is a powerful, flexible, and developer-friendly management tool for all your \nenvironment variables and configurations. \ud83d\udd25\ud83d\udd25\ud83d\udd25\n\n## Features\nHere are some of the features that confiGOAT provides:\n\n- Manage all environment variables or configuration parameters from a single setup.\n- Support all development, testing, and production environments.\n- Define configurations once, use it everywhere.\n- Define configuration parameters using both YAML and Python scripts.\n- Cast values before using them.\n- Powerful reference mechanism to reuse variables *from any levels at any levels in any direction*.\n- Multiple resource types in the YAML to support the vast majority of use cases.\n- Support both simple use cases and complex, multi-layered nested configurations.\n- Use dynamic modules to access the parameters through import interface in Python.\n- Use a single exposed API to interact with the layered configurations.\n- Support nested structures to model the configurations as per business needs.\n\n\ud83c\udf89\ud83d\ude80\ud83c\udf1f\n\n## Installation\n\nconfiGOAT can be installed with [pip](https://pip.pypa.io):\n\n```bash\npip install configoat\n```\n\nAlternatively, you can grab the latest source code from [GitHub](https://github.com/aag13/configoat):\n\n```bash\ngit clone https://github.com/aag13/configoat\ncd configoat\npip install .\n```\n\n## How to Use\n\n### Initial Setup\nconfiGOAT provides a user-friendly CLI command to initialize the configuration setup\nfor your project. \n\n1. Go to the root directory of your project and run the following command \nin the terminal.\n\n ```bash\n configoat init\n ```\n\n2. For the directory name, enter the name of the folder that will contain all\nthe configuration files and scripts. E.g. *\"environments/\"* will create a directory\ninside the root directory of your project. Default is *\"configs/\"*.\n3. For the main configuration file, provide a name that confiGOAT will look\nfor when initializing the setup for your project. (we will see how to do that\nlater). Default is *\"main.yaml\"*.\n4. While selecting the type of configurations, you have 3 options. Choose the one that\nbest suits your specific project needs. \ud83d\udc47\n - **Single (Only one YAML file)** : Use this for small projects where all your configurations will fit \n in one single YAML file.\n - **Nested (Parent-child YAML files)** : Use this for projects where it makes sense to structure the \n configuration files in a nested hierarchy.\n - **Nested with Scripts (Includes .py scripts)** : Use this for large-scale projects where some \n configurations need to be resolved using python scripts on top of a multi-layered hierarchy.\n\nFor example, if you can fit all your configuration variables in a single file, choose option 1. Choose option \n2 if you want to structure all the configuration parameters in separate files based on their types, such as, \nsecurity configurations in *security.yaml* file and database configurations in *database.yaml* file. Option 3 \nis best suited for cases where you need both the nested hierarchy structure and need to resolve values \nfor some parameters that require executing some code.\n\n\u2744\ufe0f\u2744\ufe0f\u2744\ufe0f\n\n### Preparing Configuration Files\nNow that you have set up the configuration folder and starting file(s), you need to populate all your \nconfiguration and environment variables in the generated YAML and python script files.\n1. First, open the *main.yaml* (or whatever name you gave during the initial setup) file.\n2. Each YAML file has 2 root properties, namely *doc* and *resources*. \ud83d\udc47\n - You can use *doc* to provide basic description on the type of environment or configuration variables \n which are defined in this YAML. \n - *resources* contains all the configuration variables that are defined in this file. If you want to \n create a new variable, you need to define it inside *resources*. \n ```yaml\n doc: 'This is the main config file where the processing starts from'\n resources:\n ...\n ```\n3. You can define 4 different types of resources in confiGOAT. \ud83d\udc47\n - *normal* : Use this type if the value of the variable will be different for different environments. You can\n use different data types for different environments, such as string, integer, float, boolean, list, and dictionary.\n ```yaml\n var1:\n type: 'normal'\n value:\n dev: 'value of var1 for dev'\n stage: 'value of var1 for stage'\n uat: 'value of var1 for uat'\n production: 'value of var1 for production'\n qa: 'value of var1 for qa'\n ```\n - *common* : Use this type if the value of the variable will be same across all environments. We support\n the following data types - string, integer, float, boolean, list, and dictionary.\n ```yaml\n var2:\n type: 'common'\n value: \"value of var2\"\n\n var3:\n type: 'common'\n value: False\n\n var4:\n type: 'common'\n value: 100\n\n var5:\n type: 'common'\n value: [ \"Banana\", \"Mango\", \"Apple\" ]\n\n var6:\n type: 'common'\n value: {\n \"name\": \"Raihan The Boss\",\n \"age\": 66,\n \"address\": {\n \"city\": \"Dhaka\",\n \"country\": \"Bangladesh\",\n }\n }\n ```\n - *nested* : Use this type for a nested YAML file (Available if you chose option 2 or 3 during setup). *path* \n is the relative path from the project root folder to that nested YAML file, e.g. *configs/yamls/nested.yaml*. \n All the variables which are defined in the specified nested YAML file will be available under the \n namespace of the *var7* variable. \u2728\n ```yaml\n var7:\n type: 'nested'\n path: 'path/from/project/root/to/nested.yaml'\n ```\n - *script* : Use this type for a python script file (Available if you chose option 3 during setup). *path* \n is the relative path from the project root folder to that nested script file, e.g. *configs/scripts/script.py*. \n Only the variables which are defined in the *variable_list* property will be available from specified \n nested script file under the namespace of the *var9* variable. \u2728\n ```yaml\n var9:\n type: 'script'\n variable_list: ['a', 'b', 'c', 'd', 'e']\n path: 'path/from/project/root/to/script.py'\n ```\n4. For the *nested* type, confiGOAT will process the specified YAML file **recursively**, so that if \n the nested YAML file contains other *nested* variables, it will resolve all those nested YAML files \n recursively as well. \ud83d\udc40\n5. If you want to reuse the value from another variable using reference, either in the same file or any file \nin the configuration hierarchy, you need to use **$ref(variable_name)** format by replacing the \nvariable_name with the actual variable in your configuration that you want to refer to. \ud83d\udc47\n6. Let's consider a couple of scenarios to demonstrate how variable referencing works. \ud83c\udf05\n - First, you need to understand the difference between the *source* and *target* variables. Here, \n *source* variable is the one whose reference is being used and *target* variable is the one that is \n using the reference. \ud83c\udf81\ud83c\udf81\n - ***Target* variable in the main config YAML file** : If the *target* variable is in the main config file, \n such as *main.yaml*, then you can accomplish that in two ways depending on where the *source* \n variable is.\n - **Source variable in the main config file** : If the *source* variable is in the main config \n file, then use *$ref(SIBLING)* in the *target variable*. This will get the value from a variable \n called *SIBLING* to the *target* variable like this. \u2728\n ```yaml\n target_var:\n type: 'common'\n value: \"$ref(SIBLING)\"\n ```\n - **Source variable in a nested file** : If there is a *nested* variable called *nested1* and inside \n the YAML of this file, there exists a variable called *varAA*, then the full *dot notation path* to this variable \n from the main config file is *nested1.varAA*. So use *$ref(nested1.varAA)* in the *target variable*. \u2728\n ```yaml\n target_var:\n type: 'common'\n value: \"$ref(nested1.varAA)\"\n ```\n - ***Target* variable in any other YAML/script file** : If the *target* variable is in any file other than \n the main config file, then you can accomplish that in two ways depending on where the *source* variable is.\n - **Source variable in the same file** : If the *source* variable is in the same file as the \n *target variable*, then use *$ref(SIBLING)* in the *target variable*. This will get the value from a variable \n called *SIBLING* to the *target* variable like this. \u2728\n ```yaml\n target_var:\n type: 'common'\n value: \"$ref(SIBLING)\"\n ```\n - **Source variable in any other file** : If there is a *nested* variable called *nested1* in the \n main config file and inside the YAML of this *nested* variable, there exists a variable called \n *varAA*, then the full *dot notation path* to this variable is *@.nested1.varAA*. \n So use *$ref(@.nested1.varAA)* in the *target variable*. \u2728\n ```yaml\n target_var:\n type: 'common'\n value: \"$ref(@.nested1.varAA)\"\n ```\n - **So, when to use *@* in the reference**: If the *target* variable is in the root config file, then you don't need \n to add *@* in the full *dot notation path*. Because you can use the dotted path to follow the nested \n variable hierarchy since you are already in the root config file. However, if the *target* variable \n is in anywhere other than the root config file, then you need to prepend the *dot notation path* \n with *@* to indicate whether to start looking for the *nested* variable from the root file or the \n current file. Starting the dotted path with *@* simply means to *start looking for this variable \n from the root config file*. \ud83c\udf82\ud83c\udf82\n\nNOTE: Referencing a variable is bidirectional and depth agnostic, meaning that any variable can be referenced \n**at any depth from any depth in any direction**, as long as no circular dependency is created during the \nreferencing of another variable. *Circular Dependency* means that definitions of two variables are dependent \non each other and neither variable can be resolved due to this dependency. In case of any circular dependency, \nconfiGOAT will raise an exception indicating the circular dependency.\n\n\ud83c\udf1f\ud83c\udf1f\ud83c\udf1f\n\n### Using Configuration Parameters in the Project\n\nNow that you have prepared the configurations for your project, you need to use them in your project. \n\n1. First, you need to initialize and load all the configuration and environment variables.\n ```python3\n from configoat import conf\n conf.initialize(config=\"configs/main.yaml\", env=\"dev\", module=\"all_config\")\n ```\n - *config* denotes the path to the main configuration YAML file to start loading the variables from.\n - *env* denotes which environment the variables should be loaded for.\n - *module* denotes the name of the namespace under which all variables will be made available for the \n dynamic module access.\n - In practice, you don't want to hardcode the environment value like this, *env=\"dev\"*. This way, you \n won't be able to change it dynamically on the different environments your app is running on. We \n recommend getting this value from another source that can be resolved during runtime. E.g. if you are \n using confiGOAT in a Django app, then using CI/CD or starting script, inject the environment value \n as the command line argument during the project run. Then, before initialization, \n fetch this value from *os* like below,\n ```python3\n import os\n from configoat import conf\n current_env = os.getenv(\"YOUR_ENVIRONMENT_VARIABLE\")\n conf.initialize(config=\"configs/main.yaml\", env=current_env, module=\"all_config\")\n ```\n2. To access the configuration variables, you have 2 options.\n - *Dot notation* : You can use the *conf* object to access any variable by providing its full \n *dot notation path* from the root configuration file. *@* denotes the root of the configuration, \n i.e. the main configuration file. You can also pass the *conf* variable around like any other variable in python\n and access values like shown below.\n ```python3\n print(conf(\"@.VARIABLE_NAME\"))\n print(conf(\"@.NESTED.VARIABLE_NAME\"))\n\n print(conf.get(\"@.VARIABLE_NAME\"))\n print(conf.get(\"@.NESTED.VARIABLE_NAME\"))\n ```\n - *Dynamic module* : Use python's module and import mechanism to access any configuration \n variable. In this approach, you import the module that you defined during the initialization step,\n e.g. *all_config*. When confiGOAT initialized your configuration variables, it also created dynamic \n modules and attributes in those modules following your configuration nested hierarchy. All these \n dynamic modules are inserted under the provided namespace, e.g. the *all_config* module name. After \n initialization, you can import this module anywhere in your project and access the variables like any other modules \n and their attributes. Some examples are given below on how variables can be accessed using dynamic module. \n ```python3\n # accessing variables from the root module name, i.e. all_config\n import all_config\n print(all_config.var3)\n print(all_config.var2.var4)\n\n # importing all variables using * from the root module name, i.e. all_config\n from all_config import *\n print(var3)\n print(var2.var4)\n\n from all_config import var2 as current\n print(current.var4)\n ```\n\n**You can also provide a default value in case the variable is not found and a casting function to transform\nthe final value before returning. Casting and default value features are available only when \naccessing values using *conf()* or *conf.get()***.\n```python3\nprint(conf(\"@.VARIABLE_NAME\", default=10, cast=int))\n\nprint(conf.get(\"@.VARIABLE_NAME\", default=10, cast=int))\n```\n\n\n## Issues\n\nPlease let us know if you find any issue by [filing an issue.](https://github.com/aag13/configoat/issues)\n\n## Maintainers\n\n- [@banna](https://github.com/Hasan-Ul-Banna) (Hasan-UL-Banna)\n- [@galib](https://github.com/aag13) (Asadullah Al Galib)\n\n\ud83d\udc4b\n\n\n\n\n\n=======\nHistory\n=======\n\n\n",
"bugtrack_url": null,
"license": "MIT license",
"summary": "confiGOAT is a powerful, flexible, and developer-friendly configuration management tool.",
"version": "0.1.6",
"project_urls": {
"Homepage": "https://github.com/aag13/configoat"
},
"split_keywords": [
"configoat"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4779e58cec00aaa935b64b845ab110016bc2c2ee0faae2394bf43fb96698fcf5",
"md5": "4c88c7fdef87f10406a567640ca44b7e",
"sha256": "44b8df76e77a755934cd38ba30c9a198930caee2a208cd62f89cefdc403fea89"
},
"downloads": -1,
"filename": "configoat-0.1.6-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "4c88c7fdef87f10406a567640ca44b7e",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.5",
"size": 15063,
"upload_time": "2023-12-18T11:15:03",
"upload_time_iso_8601": "2023-12-18T11:15:03.768001Z",
"url": "https://files.pythonhosted.org/packages/47/79/e58cec00aaa935b64b845ab110016bc2c2ee0faae2394bf43fb96698fcf5/configoat-0.1.6-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "463a40bd70f5b1d93b8dffd0063cd9cb2c16e37aa57a129986f61b93171a82b0",
"md5": "6330f4d02f5f1ab817d51dbd4e12f3fd",
"sha256": "b4ba2bd943b7d8d1eeaea5fe4a376557620ce4c8c88f939de57512b28fccedc7"
},
"downloads": -1,
"filename": "configoat-0.1.6.tar.gz",
"has_sig": false,
"md5_digest": "6330f4d02f5f1ab817d51dbd4e12f3fd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.5",
"size": 23375,
"upload_time": "2023-12-18T11:15:05",
"upload_time_iso_8601": "2023-12-18T11:15:05.536192Z",
"url": "https://files.pythonhosted.org/packages/46/3a/40bd70f5b1d93b8dffd0063cd9cb2c16e37aa57a129986f61b93171a82b0/configoat-0.1.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-18 11:15:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "aag13",
"github_project": "configoat",
"travis_ci": true,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "configoat"
}