everett


Nameeverett JSON
Version 3.4.0 PyPI version JSON
download
home_pageNone
SummaryConfiguration library for Python applications
upload_time2024-10-30 23:16:00
maintainerNone
docs_urlNone
authorWill Kahn-Greene
requires_python>=3.9
licenseMPLv2
keywords conf config configuration ini env yaml
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. NOTE: Make sure to edit the template for this file in docs_tmpl/ and
.. not the cog-generated version.

=======
Everett
=======

Everett is a Python configuration library for your app.

:Code:          https://github.com/willkg/everett
:Issues:        https://github.com/willkg/everett/issues
:License:       MPL v2
:Documentation: https://everett.readthedocs.io/


Goals
=====

Goals of Everett:

1. flexible configuration from multiple configured environments
2. easy testing with configuration
3. easy automated documentation of configuration for users

From that, Everett has the following features:

* is flexible for your configuration environment needs and supports
  process environment, env files, dicts, INI files, YAML files,
  and writing your own configuration environments
* facilitates helpful error messages for users trying to configure your
  software
* has a Sphinx extension for documenting configuration including
  ``autocomponentconfig`` and ``automoduleconfig`` directives for
  automatically generating configuration documentation
* facilitates testing of configuration values
* supports parsing values of a variety of types like bool, int, lists of
  things, classes, and others and lets you write your own parsers
* supports key namespaces
* supports component architectures
* works with whatever you're writing--command line tools, web sites, system
  daemons, etc

Everett is inspired by
`python-decouple <https://github.com/henriquebastos/python-decouple>`__
and `configman <https://configman.readthedocs.io/en/latest/>`__.


Install
=======

Run::

    $ pip install everett

Some configuration environments require additional dependencies::


    # For INI support
    $ pip install 'everett[ini]'

    # for YAML support
    $ pip install 'everett[yaml]'


Quick start
===========

Example:

.. [[[cog
   import cog
   with open("examples/myserver.py", "r") as fp:
       cog.outl("\n::\n")
       for line in fp.readlines():
           if line.strip():
               cog.out(f"   {line}")
           else:
               cog.outl()
   cog.outl()
   ]]]

::

   # myserver.py

   """
   Minimal example showing how to use configuration for a web app.
   """

   from everett.manager import ConfigManager

   config = ConfigManager.basic_config(
       doc="Check https://example.com/configuration for documentation."
   )

   host = config("host", default="localhost")
   port = config("port", default="8000", parser=int)
   debug_mode = config(
       "debug",
       default="False",
       parser=bool,
       doc="Set to True for debugmode; False for regular mode",
   )

   print(f"host: {host}")
   print(f"port: {port}")
   print(f"debug_mode: {debug_mode}")

.. [[[end]]]

Then you can run it:

.. [[[cog
   import cog
   import os
   import subprocess
   if os.path.exists(".env"):
       os.remove(".env")
   ret = subprocess.run(["python", "examples/myserver.py"], capture_output=True)
   cog.outl("\n::\n") 
   cog.outl("   $ python myserver.py")
   for line in ret.stdout.decode("utf-8").splitlines():
       cog.outl(f"   {line}")
   cog.outl()
   ]]]

::

   $ python myserver.py
   host: localhost
   port: 8000
   debug_mode: False

.. [[[end]]]

You can set environment variables to affect configuration:

.. [[[cog
   import cog
   import os
   import subprocess
   if os.path.exists(".env"):
       os.remove(".env")
   os.environ["PORT"] = "7000"
   cog.outl("\n::\n")
   cog.outl("   $ PORT=7000 python myserver.py")
   ret = subprocess.run(["python", "examples/myserver.py"], capture_output=True)
   for line in ret.stdout.decode("utf-8").splitlines():
       cog.outl(f"   {line}")
   cog.outl()
   del os.environ["PORT"]
   ]]]

::

   $ PORT=7000 python myserver.py
   host: localhost
   port: 7000
   debug_mode: False

.. [[[end]]]

It checks a ``.env`` file in the current directory:

.. [[[cog
   import cog
   import os
   import subprocess
   if os.path.exists(".env"):
       os.remove(".env")
   with open(".env", "w") as fp:
       fp.write("HOST=127.0.0.1")
   cog.outl("\n::\n")
   cog.outl("   $ echo \"HOST=127.0.0.1\" > .env")
   cog.outl("   $ python myserver.py")
   ret = subprocess.run(["python", "examples/myserver.py"], capture_output=True)
   for line in ret.stdout.decode("utf-8").splitlines():
       cog.outl(f"   {line}")
   cog.outl()
   ]]]

::

   $ echo "HOST=127.0.0.1" > .env
   $ python myserver.py
   host: 127.0.0.1
   port: 8000
   debug_mode: False

.. [[[end]]]

It spits out useful error information if configuration is wrong:

.. [[[cog
   import cog
   import os
   import subprocess
   if os.path.exists(".env"):
       os.remove(".env")
   os.environ["DEBUG"] = "foo"
   ret = subprocess.run(["python", "examples/myserver.py"], capture_output=True)
   stderr = ret.stderr.decode("utf-8").strip()
   stderr = stderr[stderr.find("everett.InvalidValueError"):]
   cog.outl("\n::\n")
   cog.outl("   $ DEBUG=foo python myserver.py")
   cog.outl("   <traceback>")
   for line in stderr.splitlines():
      cog.outl(f"   {line}")
   cog.outl()
   ]]]

::

   $ DEBUG=foo python myserver.py
   <traceback>
   everett.InvalidValueError: ValueError: 'foo' is not a valid bool value
   DEBUG requires a value parseable by everett.manager.parse_bool
   DEBUG docs: Set to True for debugmode; False for regular mode
   Project docs: Check https://example.com/configuration for documentation.

.. [[[end]]]

You can test your code using ``config_override`` in your tests to test various
configuration values:

.. [[[cog
   import cog
   cog.outl("\n::\n")
   with open("examples/testdebug.py", "r") as fp:
       for line in fp.readlines():
           cog.out(f"   {line}")
   cog.outl()
   ]]]

::

   # testdebug.py
   
   """
   Minimal example showing how to override configuration values when testing.
   """
   
   import unittest
   
   from everett.manager import ConfigManager, config_override
   
   
   class App:
       def __init__(self):
           config = ConfigManager.basic_config()
           self.debug = config("debug", default="False", parser=bool)
   
   
   class TestDebug(unittest.TestCase):
       def test_debug_on(self):
           with config_override(DEBUG="on"):
               app = App()
               self.assertTrue(app.debug)
   
       def test_debug_off(self):
           with config_override(DEBUG="off"):
               app = App()
               self.assertFalse(app.debug)
   
   
   if __name__ == "__main__":
       unittest.main()

.. [[[end]]]

Run that:

.. [[[cog
   import cog
   import os
   import subprocess
   ret = subprocess.run(["python", "examples/testdebug.py"], capture_output=True)
   stderr = ret.stderr.decode("utf-8").strip()
   cog.outl("\n::\n")
   cog.outl("   $ python testdebug.py")
   for line in stderr.splitlines():
       cog.outl(f"   {line}")
   cog.outl()
   ]]]

::

   $ python testdebug.py
   ..
   ----------------------------------------------------------------------
   Ran 2 tests in 0.000s
   
   OK

.. [[[end]]]

That's perfectly fine for a `12-Factor <https://12factor.net/>`__ app.

When you outgrow that or need different variations of it, you can switch to
creating a ``ConfigManager`` instance that meets your needs.


Why not other libs?
===================

Most other libraries I looked at had one or more of the following issues:

* were tied to a specific web app framework
* didn't allow you to specify configuration sources
* provided poor error messages when users configure things wrong
* had a global configuration object
* made it really hard to override specific configuration when writing tests
* had no facilities for autogenerating configuration documentation

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "everett",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "conf, config, configuration, ini, env, yaml",
    "author": "Will Kahn-Greene",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/f5/f4/709258252f35f1ccadef745833252cc646eac540c97af28a860d8482860c/everett-3.4.0.tar.gz",
    "platform": null,
    "description": ".. NOTE: Make sure to edit the template for this file in docs_tmpl/ and\n.. not the cog-generated version.\n\n=======\nEverett\n=======\n\nEverett is a Python configuration library for your app.\n\n:Code:          https://github.com/willkg/everett\n:Issues:        https://github.com/willkg/everett/issues\n:License:       MPL v2\n:Documentation: https://everett.readthedocs.io/\n\n\nGoals\n=====\n\nGoals of Everett:\n\n1. flexible configuration from multiple configured environments\n2. easy testing with configuration\n3. easy automated documentation of configuration for users\n\nFrom that, Everett has the following features:\n\n* is flexible for your configuration environment needs and supports\n  process environment, env files, dicts, INI files, YAML files,\n  and writing your own configuration environments\n* facilitates helpful error messages for users trying to configure your\n  software\n* has a Sphinx extension for documenting configuration including\n  ``autocomponentconfig`` and ``automoduleconfig`` directives for\n  automatically generating configuration documentation\n* facilitates testing of configuration values\n* supports parsing values of a variety of types like bool, int, lists of\n  things, classes, and others and lets you write your own parsers\n* supports key namespaces\n* supports component architectures\n* works with whatever you're writing--command line tools, web sites, system\n  daemons, etc\n\nEverett is inspired by\n`python-decouple <https://github.com/henriquebastos/python-decouple>`__\nand `configman <https://configman.readthedocs.io/en/latest/>`__.\n\n\nInstall\n=======\n\nRun::\n\n    $ pip install everett\n\nSome configuration environments require additional dependencies::\n\n\n    # For INI support\n    $ pip install 'everett[ini]'\n\n    # for YAML support\n    $ pip install 'everett[yaml]'\n\n\nQuick start\n===========\n\nExample:\n\n.. [[[cog\n   import cog\n   with open(\"examples/myserver.py\", \"r\") as fp:\n       cog.outl(\"\\n::\\n\")\n       for line in fp.readlines():\n           if line.strip():\n               cog.out(f\"   {line}\")\n           else:\n               cog.outl()\n   cog.outl()\n   ]]]\n\n::\n\n   # myserver.py\n\n   \"\"\"\n   Minimal example showing how to use configuration for a web app.\n   \"\"\"\n\n   from everett.manager import ConfigManager\n\n   config = ConfigManager.basic_config(\n       doc=\"Check https://example.com/configuration for documentation.\"\n   )\n\n   host = config(\"host\", default=\"localhost\")\n   port = config(\"port\", default=\"8000\", parser=int)\n   debug_mode = config(\n       \"debug\",\n       default=\"False\",\n       parser=bool,\n       doc=\"Set to True for debugmode; False for regular mode\",\n   )\n\n   print(f\"host: {host}\")\n   print(f\"port: {port}\")\n   print(f\"debug_mode: {debug_mode}\")\n\n.. [[[end]]]\n\nThen you can run it:\n\n.. [[[cog\n   import cog\n   import os\n   import subprocess\n   if os.path.exists(\".env\"):\n       os.remove(\".env\")\n   ret = subprocess.run([\"python\", \"examples/myserver.py\"], capture_output=True)\n   cog.outl(\"\\n::\\n\") \n   cog.outl(\"   $ python myserver.py\")\n   for line in ret.stdout.decode(\"utf-8\").splitlines():\n       cog.outl(f\"   {line}\")\n   cog.outl()\n   ]]]\n\n::\n\n   $ python myserver.py\n   host: localhost\n   port: 8000\n   debug_mode: False\n\n.. [[[end]]]\n\nYou can set environment variables to affect configuration:\n\n.. [[[cog\n   import cog\n   import os\n   import subprocess\n   if os.path.exists(\".env\"):\n       os.remove(\".env\")\n   os.environ[\"PORT\"] = \"7000\"\n   cog.outl(\"\\n::\\n\")\n   cog.outl(\"   $ PORT=7000 python myserver.py\")\n   ret = subprocess.run([\"python\", \"examples/myserver.py\"], capture_output=True)\n   for line in ret.stdout.decode(\"utf-8\").splitlines():\n       cog.outl(f\"   {line}\")\n   cog.outl()\n   del os.environ[\"PORT\"]\n   ]]]\n\n::\n\n   $ PORT=7000 python myserver.py\n   host: localhost\n   port: 7000\n   debug_mode: False\n\n.. [[[end]]]\n\nIt checks a ``.env`` file in the current directory:\n\n.. [[[cog\n   import cog\n   import os\n   import subprocess\n   if os.path.exists(\".env\"):\n       os.remove(\".env\")\n   with open(\".env\", \"w\") as fp:\n       fp.write(\"HOST=127.0.0.1\")\n   cog.outl(\"\\n::\\n\")\n   cog.outl(\"   $ echo \\\"HOST=127.0.0.1\\\" > .env\")\n   cog.outl(\"   $ python myserver.py\")\n   ret = subprocess.run([\"python\", \"examples/myserver.py\"], capture_output=True)\n   for line in ret.stdout.decode(\"utf-8\").splitlines():\n       cog.outl(f\"   {line}\")\n   cog.outl()\n   ]]]\n\n::\n\n   $ echo \"HOST=127.0.0.1\" > .env\n   $ python myserver.py\n   host: 127.0.0.1\n   port: 8000\n   debug_mode: False\n\n.. [[[end]]]\n\nIt spits out useful error information if configuration is wrong:\n\n.. [[[cog\n   import cog\n   import os\n   import subprocess\n   if os.path.exists(\".env\"):\n       os.remove(\".env\")\n   os.environ[\"DEBUG\"] = \"foo\"\n   ret = subprocess.run([\"python\", \"examples/myserver.py\"], capture_output=True)\n   stderr = ret.stderr.decode(\"utf-8\").strip()\n   stderr = stderr[stderr.find(\"everett.InvalidValueError\"):]\n   cog.outl(\"\\n::\\n\")\n   cog.outl(\"   $ DEBUG=foo python myserver.py\")\n   cog.outl(\"   <traceback>\")\n   for line in stderr.splitlines():\n      cog.outl(f\"   {line}\")\n   cog.outl()\n   ]]]\n\n::\n\n   $ DEBUG=foo python myserver.py\n   <traceback>\n   everett.InvalidValueError: ValueError: 'foo' is not a valid bool value\n   DEBUG requires a value parseable by everett.manager.parse_bool\n   DEBUG docs: Set to True for debugmode; False for regular mode\n   Project docs: Check https://example.com/configuration for documentation.\n\n.. [[[end]]]\n\nYou can test your code using ``config_override`` in your tests to test various\nconfiguration values:\n\n.. [[[cog\n   import cog\n   cog.outl(\"\\n::\\n\")\n   with open(\"examples/testdebug.py\", \"r\") as fp:\n       for line in fp.readlines():\n           cog.out(f\"   {line}\")\n   cog.outl()\n   ]]]\n\n::\n\n   # testdebug.py\n   \n   \"\"\"\n   Minimal example showing how to override configuration values when testing.\n   \"\"\"\n   \n   import unittest\n   \n   from everett.manager import ConfigManager, config_override\n   \n   \n   class App:\n       def __init__(self):\n           config = ConfigManager.basic_config()\n           self.debug = config(\"debug\", default=\"False\", parser=bool)\n   \n   \n   class TestDebug(unittest.TestCase):\n       def test_debug_on(self):\n           with config_override(DEBUG=\"on\"):\n               app = App()\n               self.assertTrue(app.debug)\n   \n       def test_debug_off(self):\n           with config_override(DEBUG=\"off\"):\n               app = App()\n               self.assertFalse(app.debug)\n   \n   \n   if __name__ == \"__main__\":\n       unittest.main()\n\n.. [[[end]]]\n\nRun that:\n\n.. [[[cog\n   import cog\n   import os\n   import subprocess\n   ret = subprocess.run([\"python\", \"examples/testdebug.py\"], capture_output=True)\n   stderr = ret.stderr.decode(\"utf-8\").strip()\n   cog.outl(\"\\n::\\n\")\n   cog.outl(\"   $ python testdebug.py\")\n   for line in stderr.splitlines():\n       cog.outl(f\"   {line}\")\n   cog.outl()\n   ]]]\n\n::\n\n   $ python testdebug.py\n   ..\n   ----------------------------------------------------------------------\n   Ran 2 tests in 0.000s\n   \n   OK\n\n.. [[[end]]]\n\nThat's perfectly fine for a `12-Factor <https://12factor.net/>`__ app.\n\nWhen you outgrow that or need different variations of it, you can switch to\ncreating a ``ConfigManager`` instance that meets your needs.\n\n\nWhy not other libs?\n===================\n\nMost other libraries I looked at had one or more of the following issues:\n\n* were tied to a specific web app framework\n* didn't allow you to specify configuration sources\n* provided poor error messages when users configure things wrong\n* had a global configuration object\n* made it really hard to override specific configuration when writing tests\n* had no facilities for autogenerating configuration documentation\n",
    "bugtrack_url": null,
    "license": "MPLv2",
    "summary": "Configuration library for Python applications",
    "version": "3.4.0",
    "project_urls": {
        "Homepage": "https://everett.readthedocs.io/",
        "Issues": "https://github.com/willkg/everett/issues",
        "Source": "https://github.com/willkg/everett/"
    },
    "split_keywords": [
        "conf",
        " config",
        " configuration",
        " ini",
        " env",
        " yaml"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8cf1fd919ed781658d611322a41fcc1fbd8618887f09dc554f583e474a153f40",
                "md5": "34a278c99b33792beab36aa4de633241",
                "sha256": "f8c29c7300702f47b7323b75348e2b86647246694fda7ad410c2a2bfaa980ff7"
            },
            "downloads": -1,
            "filename": "everett-3.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "34a278c99b33792beab36aa4de633241",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 34111,
            "upload_time": "2024-10-30T23:15:56",
            "upload_time_iso_8601": "2024-10-30T23:15:56.204217Z",
            "url": "https://files.pythonhosted.org/packages/8c/f1/fd919ed781658d611322a41fcc1fbd8618887f09dc554f583e474a153f40/everett-3.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f5f4709258252f35f1ccadef745833252cc646eac540c97af28a860d8482860c",
                "md5": "f175a5148dd50159e3ffb3348ef47e0d",
                "sha256": "f403c4a41764a6301fb31e2558d6e9718999f0eab9e260d986b894fa2e6b6871"
            },
            "downloads": -1,
            "filename": "everett-3.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f175a5148dd50159e3ffb3348ef47e0d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 66841,
            "upload_time": "2024-10-30T23:16:00",
            "upload_time_iso_8601": "2024-10-30T23:16:00.320008Z",
            "url": "https://files.pythonhosted.org/packages/f5/f4/709258252f35f1ccadef745833252cc646eac540c97af28a860d8482860c/everett-3.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-30 23:16:00",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "willkg",
    "github_project": "everett",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "everett"
}
        
Elapsed time: 0.40543s