# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['stela']

package_data = \
{'': ['*']}

install_requires = \
['loguru', 'pyyaml', 'scalpl', 'toml']

extras_require = \
{':python_version < "3.7"': ['dataclasses']}

setup_kwargs = {
    'name': 'stela',
    'version': '1.0.12',
    'description': 'Find and read your project configuration files easily',
    'long_description': '# Welcome to Stela\n\n[![PyPI](https://img.shields.io/pypi/v/stela)](https://pypi.org/project/stela/)\n[![Build](https://github.com/chrismaille/stela/workflows/tests/badge.svg)](https://github.com/chrismaille/stela/actions)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/stela)](https://www.python.org)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n<a href="https://github.com/psf/black"><img alt="Code style: black"\nsrc="https://img.shields.io/badge/code%20style-black-000000.svg"></a>\n\n[Stela](https://en.wikipedia.org/wiki/Stele) were the "configuration\nfiles" of ancient times. This library aims to simplify your project\nconfigurations, from *json*, *yaml*, *ini* or *toml* files in a single\nPython dictionary, which values can be easily be override by environment\nvariables.\n\n### Install\n\n```shell\n$ pip install stela\n```\n\n### Example\n\nYou can use `.yaml`, `.ini`, `.json` and `.toml` files. Suppose a file\ncalled `development.ini` which contains:\n\n```ini\n[foo]\nbar = value\n```\n\nStela will convert data into a python dictionary:\n\n```python\n{\n    "foo": {\n        "bar": "value"\n    }\n}\n```\n\nAnd you can use the settings like this:\n\n```python\nfrom stela import settings\n\nmy_conf = settings["foo.bar"]\n# my_conf = "value"\n```\n\nThis is possible because Stela uses under the hood the\n[Scalpl](https://github.com/ducdetronquito/scalpl) library.\n\n### How Stela find the configuration files?\n\nBy default, Stela will use the value from `ENVIRONMENT` environment\nvariable to find correspondent INI file. For example, if you set\n`ENVIRONMENT=development` Stela will look for `development.ini` file in\nproject root.\n\nYou can change this behaviour inside `pyproject.toml` file:\n\n```toml\n[tools.stela]\nenvironment_variable_name = "ENVIRONMENT"\nconfig_file_extension = "INI" # YAML, TOML, JSON\nconfig_file_prefix = ""  # You can add a prefix before name - ex.: env_development.ini\nconfig_file_suffix = ""  # You can add a suffix after name - ex.: development_v1.ini\ndefault_environment = "development" # use this if you do not want to define the ENVIRONMENT key\nconfig_file_path = "."  # relative path from project root for configuration files\n```\n\n### How Stela find the Environment Variables?\n\nWhen asked for a value, Stela will try to find a environment variable\nusing the full uppercase slug path. For example, if key is `foo.bar`,\nStela will search for a env called `FOO_BAR` before returning his dict\nvalue. Also, you can add a prefix/suffix in this calculated environment\nname (ex.: `MYPROJECT_FOO_BAR`). To do this, define them in\n`pyproject.toml`:\n\n```toml\n[tools.stela]\nenvironment_prefix = "MYPROJECT_"\nenvironment_suffix = ""\n```\n\nIn above case, Stela will look for the `MYPROJECT_FOO_BAR` env:\n\n```python\n# FOO_BAR = "hello_world" or\n# MYPROJECT_FOO_BAR = "hello world" if you define environment_prefix\nfrom stela import settings\n\nmy_conf = settings["foo.bar"]\n# my_conf = "hello world"\n```\n\nAlso, you can define Stela to never get values from environment\nvariables, only from dictionary:\n\n```toml\n[tools.stela]\ndo_not_read_environment = true\n```\n\n### How Stela handle more complex cases?\n\nStela uses this lifecycle to handle the settings load:\n\n```text\nPre-Load (optional) -> Load or Default Load > Post-Load (optional)\n```\n\nIf you have more complex cases to retrieve your project settings (ex.:\nreading external services, load settings from database or parse from a\ndifferent file format or library), you can use Stela decorators for\n`pre_load`, `load` and `post_load` phases:\n\n* If you use the `pre_load` decorator, data parsed in this phase will be\n  passed to **Load** phase.\n* If you use the `load` decorator, it will be used instead the Stela\'s\n  `default_loader`. The data returned here will update the dictionary\n  received in previous phase\n* If you use the `post_load` decorator, data returned in this phase will\n  update the dictionary received in previous phase.\n\nOnly one function are allowed per phase.\n\n>  These loaders need to return a valid Python dictionary.\n\n##### Lifecycle example:\n\n```python\nfrom stela.decorators import pre_load, load, post_load\nfrom typing import Dict, Any\nfrom stela import StelaOptions\n\n@pre_load\ndef pre_load(options: StelaOptions) -> Dict[Any, Any]:\n    # data value is: {}\n    # Stela Options are available in options object.\n    return {"foo": "bar"}\n\n@load\ndef load(data: dict, options: StelaOptions) -> Dict[Any, Any]:\n    # data value is: {"foo": "bar"}\n    # Using load, default_loader will not be invoked\n    return {"has_dogs": True}\n\n@post_load\ndef post_load(data: dict, options: StelaOptions) -> Dict[Any, Any]:\n    # data value is: {"foo": "bar", "has_dogs": True}\n    return {"number_of_dogs": 1}\n\n# Final data is {"foo": "bar", "has_dogs": True, "number_of_dogs": 1}\n```\n\n##### Post-Load SSM Example:\n\n```python\n# stela_loader.py\nimport boto3\nfrom stela.decorators import post_load\nfrom stela import StelaOptions\nfrom typing import Dict, Any\n\n@post_load\ndef add_ssm_parameters(data: dict, options: StelaOptions) -> Dict[Any, Any]:\n    """Load settings from SSM to current Stela data.\n    \n    This loader will be called after Stela default loader.\n    Data returned must be a Python Dictionary.\n    \n    :param data (dict): Data parsed from previous phases\n    :param options (obj): Stela Options from pyproject.toml\n    :return Dict[Any, Any]\n    """\n    ssm = boto3.client(\'ssm\')\n    environment = options.current_environment\n    parameters = ssm.get_parameters_by_path(\n        Name=f\'/foo/bar/{environment}\',\n        WithDecryption=True\n    )\n    return parameters\n```\n\n### When Stela read the data?\n\nStela are imported once, at module level. This is the python equivalent\nfor a Singleton object - project settings are load and immediately\navailable:\n\n```python\nfrom stela import settings\nfrom flask import Flask\n\napp = Flask(__name__)\napp.config.update(\n    SECRET_KEY=settings["my_app.secret"] # will read from dict or MY_APP_SECRET value\n)\n\n@app.route("/")\ndef hello():\n    return f"Hello, Environment is {settings.stela_options.current_environment}"\n```\n\nIf you need to reload settings, use the `stela.stela_reload` function:\n\n```python\nfrom stela import stela_reload\n\ndef test_different_environments(monkeypatch):\n    from stela import settings\n    assert settings.stela_options.current_environment == "test"\n    \n    monkeypatch.setenv("ENVIRONMENT", "production")\n    settings = stela_reload()\n    assert settings.stela_options.current_environment == "production"\n    monkeypatch.delenv("ENVIRONMENT")\n```\n\n### How Stela read the dictionary values?\n\nStela will respect the file format limitations. For example, INI files\nalways return values as string, TOML files returning datetime objects,\netc...\n\nFor environment variables, Stela will return value as string, by\ndefault. For example: `NUMBER_OF_CATS=3` will return a string.\n\nYou can set Stela to literal evaluate these values, as per\n[ast.literal_eval](https://docs.python.org/3.7/library/ast.html?highlight=literal_eval#ast.literal_eval)\nrules. To do this, add in `pyproject.toml`:\n\n```toml\n[tool.stela]\nevaluate_data = true\n```\n\n### All Stela Configuration Options:\n\nAll configuration files can be override using a environment variable,\nusing the `STELA_` prefix. For example, `default_environment` turns\n`STELA_DEFAULT_ENVIRONMENT`.\n\n```toml\n# All keys and default values available in pyproject.toml\n[tool.stela]\nenvironment_variable_name = "ENVIRONMENT"\nconfig_file_extension = "INI" # YAML, TOML, JSON\nconfig_file_prefix = ""  # You can add a prefix before name - ex.: env_development.ini\nconfig_file_suffix = ""  # You can add a suffix after name - ex.: development_v1.ini\nconfig_file_path = "."\nenvironment_prefix = ""  # ex.: settings["foo.bar"\'] looks for MY_PREFIX_FOO_BAR\nenvironment_suffix = ""  # ex.: settings["foo.bar"\'] looks for FOO_BAR_MY_SUFFIX\ndefault_environment = ""\nevaluate_data = false\ndo_not_read_environment = false\nshow_logs = true  # as per loguru settings.\n```\n\n### Not working?\n\nDont panic. Get a towel and, please, open a\n[issue](https://github.com/chrismaille/stela/issues).\n',
    'author': 'Chris Maillefaud',
    'author_email': 'chrismaillefaud@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/chrismaille/stela',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
