.. 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"
}