{ "info": { "author": "Florian Plattner", "author_email": "me@florianplattner.de", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Other Environment", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "config_py\n=========\n\nDeclare and load configuration from environment variables.\n\nSupported features:\n\n- declare different sets of variables for production, test and other environments\n- load variables from file if necessary\n- parse configuration into different datatypes\n\n - str\n - int\n - float\n - bool ('True', 'False', 1, 0, 'yes', 'no')\n - str[]\n - int[]\n - float[]\n - bool[]\n - nested types\n- easy to work with reports about missing variables and declaration issues\n\n .. code-block:: python\n\n Missing environment variables:\n export ERR_KEY_1=[your value here]\n export ERR_KEY_1_DICT2_DICT3_KEY4=[your value here]\n export ERR_KEY_1_DICT2_KEY3=[your value here]\n\n Missing declarations:\n declare(\"undeclared\", [your definition here])\n\n Parse errors:\n ERR_KEY_1_VALUE1: invalid literal for int() with base 10: 'some int value'\n\n\nInstall\n-------\n\n.. code-block:: sh\n\n pip install config\n\n\n\nExamples\n--------\n\n* `Create a new Config instance`_\n* `Configure log levels`_\n* `Declare and load scalar values`_\n* `Declare and load list values`_\n* `Declare and load nested values`_\n* `Namespace your variables`_\n* `Add validation`_\n* `Reloading configuration at runtime`_\n* `Declaring optional variables`_\n* `Loading variables from a file`_\n\n\nCreate a new Config instance\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n from env_config import\n\n # control error reporting.\n # If deferred, config errors are raised the first time Config.get() is called.\n # The error message contains a detailed report about all errors encountered while parsing config variables.\n # If not deferred, Config raises on the first error encountered. This most likely happens while calling Config.declare().\n # Default is defer_raise=True\n cfg = Config(defer_raise=False)\n\n # load config from a file. See a more detailed example further down.\n cfg = Config(filename_variable='CONFIG_FILE')\n\n\nConfigure log levels\n^^^^^^^^^^^^^^^^^^^^\n\nenv_config has a simple mechanism to set log levels for python logging, including all configured loggers.\nThe library searches for environment variables that are build following this schema:\n`LOG_LEVEL_{logger_name.upper}`\nIf found the values of each variable is applied as the log_level for the respective logger.\nThe environment variable `LOG_LEVEL` (without a logger name) set the log level for the root logger.\n\nthe available values are:\n- debug\n- info\n- warning\n- error\n- critical\n\n\n.. code-block:: python\n\n import os\n from env_config import\n\n os.environ['LOG_LEVEL'] = 'info' # set the root logger to logging.INFO\n os.environ['LOG_LEVEL_URLLIB3'] = 'critical' # set the urllib3 logger to logging.CRITICAL\n os.environ['LOG_LEVEL_PARAMIKO.TRANSPORT'] = 'debug' # set paramiko.transport to logging.DEBUG\n\n cfg = Config()\n cfg.apply_log_levels() # read the environment variables and apply to the respective log levels\n\n\n\nDeclare and load scalar values\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n from env_config import Config, parse_int, parse_float, parse_str, parse_bool\n\n cfg = Config()\n\n # declare variables with the appropriate parser\n cfg.declare('my_int_variable', parse_int())\n cfg.declare('my_float_variable', parse_float())\n cfg.declare('my_str_variable', parse_str())\n cfg.declare('my_bool_variable', parse_bool())\n\n # load the values\n\n # will load the value of MY_INT_VARIABLE as an int\n int_result = cfg.get('my_int_variable')\n # will load the value of MY_FLOAT_VARIABLE as a float\n float_result = cfg.get('my_float_variable')\n # will load the value of MY_STR_VARIABLE as a str\n str_result = cfg.get('my_str_variable')\n\n\nDeclare and load list values\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n from env_config import Config, parse_int_list\n\n cfg = Config()\n\n # declare variables with the appropriate parser\n cfg.declare('my_int_list_variable', parse_int_list())\n\n # load the values\n\n # will load the value of MY_INT_LIST_VARIABLE as a list of ints.\n # By default it assumes the elements to be comma separated\n int_list_result = cfg.get('my_int_list_variable')\n\n\nDeclare and load nested values\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nMost libraries need multiple variables to be correctly configured.\nNested values help reduce boilerplate necessary to wire configuration with the library.\n\n.. code-block:: python\n\n from env_config import Config, parse_str\n import psycopg2\n\n cfg = Config()\n cfg.declare(\n 'database',\n {\n 'dbname': parse_str(),\n 'user': parse_str(),\n 'password': parse_str()\n },\n )\n\n # this will load values from these environment variables and parse them into a dict:\n # - DATABASE_DBNAME\n # - DATABASE_USER\n # - DATABASE_PASSWORD\n\n psyco_config = cfg.get('database')\n # the dict will look like this: {'dbname': 'some value', 'user': 'username', 'password': 'vsjkfl'}\n psyco_connection = psycopg2.connect(**psyco_config)\n\n\nNamespace your variables\n^^^^^^^^^^^^^^^^^^^^^^^^\n.. code-block:: python\n\n from env_config import Config, parse_str\n import psycopg2\n\n cfg = Config(namespace='my_prefix')\n cfg.declare('database')\n\n # the value will be loaded from the environment variable: MY_PREFIX_DATABASE\n value = cfg.get('database')\n\n\nAdd validation\n^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n from env_config import Config, parse_str, parse_str_list\n from validators import email\n\n # config expects validators to raise an Error on failure.\n # Since the validators package returns Failures instead of raising, we create a small adapter.\n def email_validator(value):\n result = email(value)\n if isinstance(result, ValidationFailure):\n raise ValueError('\"{}\" is not a valid email address'.format(value))\n\n cfg = Config()\n\n cfg.declare('valid_email', parse_str(validator=email_validator))\n # this also works with lists. The validator function is applied to each value separately\n cfg.declare('valid_list_of_emails, parse_str_list(validator=email_validator))\n\n valid_email = cfg.get('valid_email')\n valid_list_of_emails = cfg.get('valid_list_of_emails')\n\n\nReloading configuration at runtime\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n from env_config import Config, parse_str, reload\n\n cfg = Config()\n cfg.declare('some_value', parse_str())\n value = cfg.get('some_value')\n\n # Values are actually loaded during declare().\n # Changes to the environment at runtime are not picked up automatically.\n # Relaoding has to be triggered explicitly.\n\n cfg.reload()\n\n new_value = cfg.get('some_value')\n\n\nDeclaring optional variables\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSometimes you just want to load a subset of all variables. For example most applications nowadays get executed\nin a live environment and in a testing environment.\nAnother example is different processes, for example a web endpoint and a background worker, sharing configuration setup.\n\n.. code-block:: python\n\n # config.py\n\n from env_config import Config, parse_str\n\n def declare_config(tag):\n required = ('live', 'test')\n test_optional = ('live',)\n\n cfg = Config()\n # this variable is available both in live and test\n cfg.declare('some_value', parse_str(), required, tag)\n # this variable is only available in live. In test it won't be loaded and only raises an error when accessed.\n cfg.declare('some_other_value', parse_str(), test_optional, tag)\n return cfg\n\n.. code-block:: python\n\n # live-app.py\n\n from config import declare_config\n\n # the active tag is 'live', so all variables tagged with 'live' are required and raise errors when missing.\n cfg = declare_config('live')\n\n # access variables\n val = cfg.get('some_value')\n\n.. code-block:: python\n\n # something_test.py\n\n from config import declare_config\n\n # the active tag is 'test', so all variables tagged with 'test' are required and raise errors when missing.\n # All other variables become optional and only raise errors when accessed with\n cfg.declare_config('test')\n\n # access variables\n val = cfg.get('some_value')\n\n # raise an error, because the variable is not available in 'test'\n val2 = cfg.get('some_other_value')\n\n\nLoading variables from a file\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSometimes it's rather cumbersome to declare all the variables explicitly.\nFor example the PyCharm variable declaration is rather awkward to use.\n\nTo elegantly deal with these kinds of situations, it's possible to load variables declared to a tag from a bash file.\nSo only one variable (the file name) has to be declared. The rest is loaded from that file.\nThe file is not evaluated, though. Only :code:`export` declarations are extracted and parsed into variables.\n\n\ndefine the variable holding the file name\n\n.. code-block:: bash\n\n export CONFIG_FILE=test.sh\n\n\nCreate a file test.sh with the variable declarations.\n\n.. code-block:: bash\n\n #!/usr/bin/env bash\n\n # comment is ignored\n\n HIDDEN_VARIABLE=\"value not parsed\"\n export VISIBLE_VARIABLE_1=\"this value will be available\"\n\n function {\n # if the line does not start with export it's ignored\n }\n\n # variables inside strings are not expanded. The value will contain the literal :code:`$OTHER_VARIABLE`.\n export VARIABLE_CONTAINING_REFERENCE=\"$OTHER_VARIABLE\"\n\n\nThen setup the CONFIG_FILE variable to load the file.\n\n\n.. code-block:: python\n\n from env_config import Config, parse_str\n\n # uses the value of CONFIG_FILE as the file name to load variables from\n config = Config(filename_variable='CONFIG_FILE', defer_raise=False)\n # visible_variable_1 is declared in test and the current tag is test. variable1 will be loaded from test.sh\n config.declare('visible_variable_1', parse_int(), ('test',), 'test'))\n\n # visible_variable_2 is declared in the 'default' tag and not available in the config file.\n # visible_variable_2 will be ignored because the current tag is 'test'\n config.declare('visible_variable_1', parse_int(), ('default',), 'test')\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/flowpl/env_config", "keywords": "config\nconfiguration\nenvironment\nenv\nenvironment variables", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "env_config", "package_url": "https://pypi.org/project/env_config/", "platform": "", "project_url": "https://pypi.org/project/env_config/", "project_urls": { "Homepage": "https://github.com/flowpl/env_config" }, "release_url": "https://pypi.org/project/env_config/1.10.0/", "requires_dist": null, "requires_python": "", "summary": "Declare and load configuration from environment variables", "version": "1.10.0" }, "last_serial": 4040108, "releases": { "1.10.0": [ { "comment_text": "", "digests": { "md5": "bd114ea7af845b154097904adf5e7373", "sha256": "3aed25d9bcf8050b7b96d00dfe5cc142d131af97e06bdd2bdb08aaed3bc6ffcd" }, "downloads": -1, "filename": "env_config-1.10.0.tar.gz", "has_sig": false, "md5_digest": "bd114ea7af845b154097904adf5e7373", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14435, "upload_time": "2018-07-08T07:54:14", "url": "https://files.pythonhosted.org/packages/4e/fc/883e0be4da2617fa05ed8065ef91d2f4b94b367e9c831401416f0fe8e645/env_config-1.10.0.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "366c301d5e6fb17cd209ee6631a81e6c", "sha256": "dd298d4b1b27e96a594681d216fe8b79529f713132c804fd73a29c426a008e99" }, "downloads": -1, "filename": "env_config-1.3.0.tar.gz", "has_sig": false, "md5_digest": "366c301d5e6fb17cd209ee6631a81e6c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8425, "upload_time": "2017-10-29T17:36:44", "url": "https://files.pythonhosted.org/packages/97/ab/a7f98fc249ef1a9ff30e86ad3585d847c23187bab89228e669512c1336ea/env_config-1.3.0.tar.gz" } ], "1.4.0": [ { "comment_text": "", "digests": { "md5": "8295e8161731e93c9632ed2e4cf2847b", "sha256": "019cc39a207d4a7dad9f8ae306449f7ff5866845508a9caefa328639e8375556" }, "downloads": -1, "filename": "env_config-1.4.0.tar.gz", "has_sig": false, "md5_digest": "8295e8161731e93c9632ed2e4cf2847b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8477, "upload_time": "2017-11-01T07:52:58", "url": "https://files.pythonhosted.org/packages/0f/f6/5a838150c3935c2e7f7a957565ea47ad871a0b3fa0ac7347bd3d51a33c02/env_config-1.4.0.tar.gz" } ], "1.4.1": [ { "comment_text": "", "digests": { "md5": "b5fbf0258b2804ab895bf97fd8f6ddf9", "sha256": "8d958205e261ca29e4f1db59a3a3171594f82301723286baf08fa2b628deb2dc" }, "downloads": -1, "filename": "env_config-1.4.1.tar.gz", "has_sig": false, "md5_digest": "b5fbf0258b2804ab895bf97fd8f6ddf9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8512, "upload_time": "2017-11-01T08:06:40", "url": "https://files.pythonhosted.org/packages/84/a5/409a908fedf9dcbe87b8f24b18561e7159e93eba1efed02de64244b881e4/env_config-1.4.1.tar.gz" } ], "1.4.2": [ { "comment_text": "", "digests": { "md5": "71acd5398b20609f1a956af43e67c823", "sha256": "94b981311d243d82d5fb94d08b0eedc431da93f45306ba7e72370b44efaecc93" }, "downloads": -1, "filename": "env_config-1.4.2.tar.gz", "has_sig": false, "md5_digest": "71acd5398b20609f1a956af43e67c823", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8586, "upload_time": "2017-11-01T08:24:06", "url": "https://files.pythonhosted.org/packages/ad/35/e3fcb84728cc0e88559d514ef9b4118f3bca133b18f7052ddd64d5c22be8/env_config-1.4.2.tar.gz" } ], "1.4.3": [ { "comment_text": "", "digests": { "md5": "132bd1da78d3b5d99dcbb57fcff473dc", "sha256": "e0a0963718a02ca9dac2a6c1a67942bd249e706b62bc36f34feaa4f705f25d4e" }, "downloads": -1, "filename": "env_config-1.4.3.tar.gz", "has_sig": false, "md5_digest": "132bd1da78d3b5d99dcbb57fcff473dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8600, "upload_time": "2017-11-01T08:42:45", "url": "https://files.pythonhosted.org/packages/6e/33/6a18dc960533425deff18e8be91d66c87af404a77c512788ac4fad72ff01/env_config-1.4.3.tar.gz" } ], "1.4.5": [ { "comment_text": "", "digests": { "md5": "a1d2ec5a7a91a2bebb029fd95f6c531d", "sha256": "2923b0b5a0aa30f4a0b08e4068c60ad9518b15c284df52861cdb624f12952b6a" }, "downloads": -1, "filename": "env_config-1.4.5.tar.gz", "has_sig": false, "md5_digest": "a1d2ec5a7a91a2bebb029fd95f6c531d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8603, "upload_time": "2017-11-01T08:47:02", "url": "https://files.pythonhosted.org/packages/5f/8c/7357476ccb7ae75d7d3b664f1b7e51cd5b25a03375eb05a10d80226a0778/env_config-1.4.5.tar.gz" } ], "1.5.0": [ { "comment_text": "", "digests": { "md5": "d86eb6cbc65986f2d76b253fa3c1bcf9", "sha256": "708c4f9af6e9df0b27e1a3274265c5deed6df925450292a65f132c936058be45" }, "downloads": -1, "filename": "env_config-1.5.0.tar.gz", "has_sig": false, "md5_digest": "d86eb6cbc65986f2d76b253fa3c1bcf9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9141, "upload_time": "2017-12-07T23:50:13", "url": "https://files.pythonhosted.org/packages/c6/39/891731e62324d5789d595d9d0b11eeb3bba3e228499ceca4526903a48146/env_config-1.5.0.tar.gz" } ], "1.6.0": [ { "comment_text": "", "digests": { "md5": "679ddec0d0007ed4b9ecfc019f1cffc5", "sha256": "e006b47ac4873a6578a45a5669f2b80ea3398f314a061acb0f1d00683fb67360" }, "downloads": -1, "filename": "env_config-1.6.0.tar.gz", "has_sig": false, "md5_digest": "679ddec0d0007ed4b9ecfc019f1cffc5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9419, "upload_time": "2017-12-09T15:09:53", "url": "https://files.pythonhosted.org/packages/96/68/922816767f2a7206c1bb517f0eaac8ed4e382c711515c7014185bceb2b97/env_config-1.6.0.tar.gz" } ], "1.7.0": [ { "comment_text": "", "digests": { "md5": "efaf888ca76d4d774c7700c6b4614b7b", "sha256": "e5c0e40c1ddc9b1a5577bc611e90b2438078eec42afa84361cf9c3db2fbd80a7" }, "downloads": -1, "filename": "env_config-1.7.0.tar.gz", "has_sig": false, "md5_digest": "efaf888ca76d4d774c7700c6b4614b7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10589, "upload_time": "2017-12-10T17:20:04", "url": "https://files.pythonhosted.org/packages/6f/79/2c4f8036e13c6ef03aa96efcf33228bdd093cb5b3966c85836a8753aa744/env_config-1.7.0.tar.gz" } ], "1.8.0": [ { "comment_text": "", "digests": { "md5": "098e5f552a2ceffbf00b7682f2b53b38", "sha256": "4fdf5f9279fa6387208ae8138c39d936942562ee3aa9cbe9b8fc9b12250dcb47" }, "downloads": -1, "filename": "env_config-1.8.0.tar.gz", "has_sig": false, "md5_digest": "098e5f552a2ceffbf00b7682f2b53b38", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11583, "upload_time": "2018-02-23T11:06:41", "url": "https://files.pythonhosted.org/packages/d2/67/4da64e43edd376d7e3556aeb07087173bbc688535548371fa0896d20fa92/env_config-1.8.0.tar.gz" } ], "1.9.0": [ { "comment_text": "", "digests": { "md5": "0bbd4a3a9217e62d6c8d9afd9e0a8a79", "sha256": "4c843167f9424dc8fe3e5db51003a6efce6a8f0de269a9cae4ada9d5e35dc36f" }, "downloads": -1, "filename": "env_config-1.9.0.tar.gz", "has_sig": false, "md5_digest": "0bbd4a3a9217e62d6c8d9afd9e0a8a79", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12469, "upload_time": "2018-04-29T10:56:08", "url": "https://files.pythonhosted.org/packages/91/bd/0b351b39c4cc52f773876e02ca090624d18367e18a80763e325ff0fcb2c2/env_config-1.9.0.tar.gz" } ], "1.9.1": [ { "comment_text": "", "digests": { "md5": "48650914cf7b59f5b7af881a064267dd", "sha256": "83883ce9e50eb1d1a8009370f7f4bfa397aee00ed8ddccd4951e77a5096ef7e5" }, "downloads": -1, "filename": "env_config-1.9.1.tar.gz", "has_sig": false, "md5_digest": "48650914cf7b59f5b7af881a064267dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12895, "upload_time": "2018-04-29T11:38:49", "url": "https://files.pythonhosted.org/packages/01/be/00822b89a3fa43d4ec4ff6d7ddf8fd624a465d992f2a0ee4f0ceb13ab0e0/env_config-1.9.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bd114ea7af845b154097904adf5e7373", "sha256": "3aed25d9bcf8050b7b96d00dfe5cc142d131af97e06bdd2bdb08aaed3bc6ffcd" }, "downloads": -1, "filename": "env_config-1.10.0.tar.gz", "has_sig": false, "md5_digest": "bd114ea7af845b154097904adf5e7373", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14435, "upload_time": "2018-07-08T07:54:14", "url": "https://files.pythonhosted.org/packages/4e/fc/883e0be4da2617fa05ed8065ef91d2f4b94b367e9c831401416f0fe8e645/env_config-1.10.0.tar.gz" } ] }