{ "info": { "author": "Peter Baumgartner", "author_email": "pete@lincolnloop.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "Goodconf\n========\n\n.. image:: https://img.shields.io/travis/lincolnloop/goodconf.svg\n :target: https://travis-ci.org/lincolnloop/goodconf\n\n.. image:: https://img.shields.io/codecov/c/github/lincolnloop/goodconf.svg\n :target: https://codecov.io/gh/lincolnloop/goodconf\n\n.. image:: https://img.shields.io/pypi/v/goodconf.svg\n :target: https://pypi.python.org/pypi/goodconf\n\n.. image:: https://img.shields.io/pypi/pyversions/goodconf.svg\n :target: https://pypi.python.org/pypi/goodconf\n\nDefine configuration variables and load them from environment or JSON/YAML\nfile. Also generates initial configuration files and documentation for your\ndefined configuration.\n\n\nInstallation\n------------\n\n``pip install goodconf`` or ``pip install goodconf[yaml]`` if\nparsing/generating YAML files is required.\n\n\nQuick Start\n-----------\n\nLet's use configurable Django settings as an example.\n\nFirst, create a ``conf.py`` file in your project's directory, next to\n``settings.py``:\n\n.. code:: python\n\n import base64\n import os\n\n from goodconf import GoodConf, Value\n\n class Config(GoodConf):\n \"Configuration for My App\"\n DEBUG = Value(default=False, help=\"Toggle debugging.\")\n DATABASE_URL = Value(\n default='postgres://localhost:5432/mydb',\n help=\"Database connection.\")\n SECRET_KEY = Value(\n initial=lambda: base64.b64encode(os.urandom(60)).decode(),\n help=\"Used for cryptographic signing. \"\n \"https://docs.djangoproject.com/en/2.0/ref/settings/#secret-key\")\n\nNext, use the config in your ``settings.py`` file:\n\n.. code:: python\n\n import os\n import dj_database_url\n from .conf import Config\n\n BASE_DIR = os.path.dirname(os.path.dirname(__file__))\n\n config = Config(\n default_files=[\n \"/etc/myproject/myproject.yaml\",\n os.path.join(BASE_DIR, \"myproject.yaml\"),\n ]\n ).load()\n\n DEBUG = config.DEBUG\n SECRET_KEY = config.SECRET_KEY\n DATABASES = {\"default\": dj_database_url.parse(config.DATABASE_URL)}\n\nIn your initial developer installation instructions, give some advice such as:\n\n.. code:: shell\n\n python -c \"import myproject; print(myproject.config.generate_yaml(DEBUG=True))\" > myproject.yaml\n\n\nUsage\n-----\n\n\n``GoodConf``\n^^^^^^^^^^^^\n\nYour subclassed ``GoodConf`` object can be initialized with the following\nkeyword args:\n\n``file_env_var``\n The name of an environment variable which can be used for\n the name of the configuration file to load.\n``default_files``\n If no file is passed to the ``load`` method, try to load a\n configuration from these files in order.\n``load``\n Trigger the load method during instantiation. Defaults to False.\n\nUse plain-text docstring for use as a header when generating a configuration\nfile.\n\n\n``Value``\n^^^^^^^^^\n\nDeclare configuration values by subclassing ``GoodConf`` and defining class\nattributes which are ``Value`` instances. They can be initialized with the\nfollowing keyword args:\n\n``default``\n Default value if none is provided. If left unset, loading\n a config that fails to provide this value will raise accept\n ``RequiredValueMissing`` exception.\n``initial``\n Initial value to use when generating a config\n``cast_as``\n Python type to cast variable as. Defaults to type of default\n (if provided) or str.\n``help``\n Plain-text description of the value.\n\n\nDjango Usage\n------------\n\nA helper is provided which monkey-patches Django's management commands to\naccept a ``--config`` argument. Replace your ``manage.py`` with the following:\n\n.. code:: python\n\n # Define your GoodConf in `myproject/__init__.py`\n from myproject import config\n\n if __name__ == '__main__':\n config.django_manage()\n\n\nWhy?\n----\n\nI took inspiration from `logan `__ (used by\nSentry) and `derpconf `__ (used by\nThumbor). Both, however used Python files for configuration. I wanted a safer\nformat and one that was easier to serialize data into from a configuration\nmanagement system.\n\nEnvironment Variables\n^^^^^^^^^^^^^^^^^^^^^\n\nI don't like working with environment variables. First, there are potential\nsecurity issues:\n\n1. Accidental leaks via logging or error reporting services.\n2. Child process inheritance (see `ImageTragick `__\n for an idea why this could be bad).\n\nSecond, in practice on deployment environments, environment variables end up\ngetting written to a number of files (cron, bash profile, service definitions,\nweb server config, etc.). Not only is it cumbersome, but also increases the\npossibility of leaks via incorrect file permissions.\n\nI prefer a single structured file which is explicitly read by the application.\nI also want it to be easy to run my applications on services like Heroku\nwhere environment variables are the preferred configuration method.\n\nThis module let's me do things the way I prefer in environments I control, but\nstill run them with environment variables on environments I don't control with\nminimal fuss.\n\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/lincolnloop/goodconf/", "keywords": "env,config,json,yaml", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "goodconf", "package_url": "https://pypi.org/project/goodconf/", "platform": "", "project_url": "https://pypi.org/project/goodconf/", "project_urls": { "Homepage": "https://github.com/lincolnloop/goodconf/" }, "release_url": "https://pypi.org/project/goodconf/1.0.0/", "requires_dist": [ "zest.releaser[recommended]; extra == 'maintainer'", "django (<2.1); extra == 'tests'", "ruamel.yaml; extra == 'tests'", "pytest (==3.5.0); extra == 'tests'", "pytest-cov (==2.5.1); extra == 'tests'", "pytest-mock (==1.7.1); extra == 'tests'", "ruamel.yaml; extra == 'yaml'" ], "requires_python": "", "summary": "Load configuration variables from a file or environment", "version": "1.0.0" }, "last_serial": 4079964, "releases": { "0.8.0": [ { "comment_text": "", "digests": { "md5": "acee6673b66e7b36f07494729e65bdcf", "sha256": "a2976cb63e3a39046e3ac2c637099c1d92b56548f878264c5c6ac227d3da4c0a" }, "downloads": -1, "filename": "goodconf-0.8.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "acee6673b66e7b36f07494729e65bdcf", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11912, "upload_time": "2018-03-28T04:18:43", "url": "https://files.pythonhosted.org/packages/42/aa/2e68fb5bfcbc92cf382014549caaaab68e76d1a8ea57cae851fdc4a85254/goodconf-0.8.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92f870a33941e50e1ab30e552e57e51c", "sha256": "48c3991cc55c56574811d88efa2a318126c20d50ea89bf6cf0d817e2e660c0e1" }, "downloads": -1, "filename": "goodconf-0.8.0.tar.gz", "has_sig": false, "md5_digest": "92f870a33941e50e1ab30e552e57e51c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8089, "upload_time": "2018-03-28T04:18:46", "url": "https://files.pythonhosted.org/packages/28/63/21ba09d2ac6f8cd11831f083f57605b8a5299082f3a3d4815ca9a93dc9e9/goodconf-0.8.0.tar.gz" } ], "0.8.1": [ { "comment_text": "", "digests": { "md5": "35799ae8023c0a5b49800461db057747", "sha256": "bff08f31b6de40823221726f9e8170b8af658bd44f04d8e077ab7677dce8d330" }, "downloads": -1, "filename": "goodconf-0.8.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "35799ae8023c0a5b49800461db057747", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 12196, "upload_time": "2018-03-28T16:07:18", "url": "https://files.pythonhosted.org/packages/57/0c/f3e3bc9f5bb46204cd7b0a6744e7c72a6ed24452f6efb403974138c54eeb/goodconf-0.8.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1c0c451ed003dacbd8f4d6cf07e56c4a", "sha256": "8611eac342e8617ef2a597dda7caa9b5669826bbf0edb22ccaef52f5db8babe1" }, "downloads": -1, "filename": "goodconf-0.8.1.tar.gz", "has_sig": false, "md5_digest": "1c0c451ed003dacbd8f4d6cf07e56c4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8155, "upload_time": "2018-03-28T16:07:20", "url": "https://files.pythonhosted.org/packages/07/14/a8e89a40170e2e5dc5893678bb9de6c48de074f1c80be9501163f42ee547/goodconf-0.8.1.tar.gz" } ], "0.8.2": [ { "comment_text": "", "digests": { "md5": "e8c39365e74571b9f3f08668320b85ea", "sha256": "6511c8a89adb56015df2728242c8c2c7d4cab7cbb07e344a368036b3da743a5f" }, "downloads": -1, "filename": "goodconf-0.8.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e8c39365e74571b9f3f08668320b85ea", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 12185, "upload_time": "2018-03-28T20:28:26", "url": "https://files.pythonhosted.org/packages/80/9e/0fbaf08c703873a06931d95819596cd734eba623b423bd1b4e993be6cf40/goodconf-0.8.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8aac133115f0f2aa54a12af80dadca1a", "sha256": "be3a991fe7dfb9cbb202fe23fff58f4eba80c8f42dc75ef76a4ad7456ebbe960" }, "downloads": -1, "filename": "goodconf-0.8.2.tar.gz", "has_sig": false, "md5_digest": "8aac133115f0f2aa54a12af80dadca1a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8156, "upload_time": "2018-03-28T20:28:27", "url": "https://files.pythonhosted.org/packages/2d/2e/c874e175cf084538a4863b51f94b5ac1fde86ffd75dc9163896922bdb984/goodconf-0.8.2.tar.gz" } ], "0.8.3": [ { "comment_text": "", "digests": { "md5": "a3aea94af411d5248115d67f7a92a70e", "sha256": "4f5872a9b3b14fa5835dcc50ede51bc6c26ee987b1140e08f07e4cedb16ed522" }, "downloads": -1, "filename": "goodconf-0.8.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a3aea94af411d5248115d67f7a92a70e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 12357, "upload_time": "2018-03-28T22:21:10", "url": "https://files.pythonhosted.org/packages/d3/d9/4ce7dc45ca645f960862c18b447e0a8ea41f439364b4acf1ff39c1c26e93/goodconf-0.8.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9bfa7809be9ba751d90c63f583c9651d", "sha256": "d8f5cf30513f40d4543669e5504a5549d5845bae310e8855f63ebb479ce2b04e" }, "downloads": -1, "filename": "goodconf-0.8.3.tar.gz", "has_sig": false, "md5_digest": "9bfa7809be9ba751d90c63f583c9651d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8311, "upload_time": "2018-03-28T22:21:11", "url": "https://files.pythonhosted.org/packages/7b/ac/24ba591720c7d30afc1bd82956a960c81865cc795010308dbe81dce9338a/goodconf-0.8.3.tar.gz" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "2e11d7301005ebbeecddc2a2faaa26ea", "sha256": "785f3b7fdf7d897fb058ae933de6b89a1d43dd0ff3165c27c9599a4f4210ebad" }, "downloads": -1, "filename": "goodconf-0.9.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2e11d7301005ebbeecddc2a2faaa26ea", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11343, "upload_time": "2018-04-09T03:09:23", "url": "https://files.pythonhosted.org/packages/85/ea/d3081fd3efcca26ebecd1d3d9e3ea5a93105afa520a4e40876836b3d4bfa/goodconf-0.9.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "edfe3300433c745c6917567af6d8264c", "sha256": "470d263e3da41194b00272d9a802ae1d24ac70d76ea0d3fe34e97e157b3a177d" }, "downloads": -1, "filename": "goodconf-0.9.0.tar.gz", "has_sig": false, "md5_digest": "edfe3300433c745c6917567af6d8264c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8427, "upload_time": "2018-04-09T03:09:24", "url": "https://files.pythonhosted.org/packages/d3/80/1b523d4e04247a5bc1c1bc796881c3d417a3e170ddfada1a76b29a649860/goodconf-0.9.0.tar.gz" } ], "0.9.1": [ { "comment_text": "", "digests": { "md5": "9d9a1041bb1251ccfdd50aebe4fa9137", "sha256": "384f179f9eb7842884b344f0f859141056962d847bcd11fd216328649c54909e" }, "downloads": -1, "filename": "goodconf-0.9.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9d9a1041bb1251ccfdd50aebe4fa9137", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11371, "upload_time": "2018-04-10T21:44:25", "url": "https://files.pythonhosted.org/packages/25/76/543892ce2616043fc163b0dca99230c96b8278f1ca9f72fbd3763eab5984/goodconf-0.9.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bb09d842352195fdae8194249eda263e", "sha256": "828fed415873da26bee78d518ce3a26936d80d61a600f8c3ccabc172cb90e843" }, "downloads": -1, "filename": "goodconf-0.9.1.tar.gz", "has_sig": false, "md5_digest": "bb09d842352195fdae8194249eda263e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8530, "upload_time": "2018-04-10T21:44:26", "url": "https://files.pythonhosted.org/packages/6b/1e/775e09dd04b294012a35b0a5336a4a55718e48f1abb2a5523e8d022798a2/goodconf-0.9.1.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "41c69a4bc9f839d2610a0d2be4eee24b", "sha256": "beb2f9ed734015e1becd4338d8b1e363cf51fb52e2f794f4e85e8c59d097442e" }, "downloads": -1, "filename": "goodconf-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "41c69a4bc9f839d2610a0d2be4eee24b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11814, "upload_time": "2018-07-18T21:33:10", "url": "https://files.pythonhosted.org/packages/84/33/30b77b95579c97a51865a58c377b456eaec1ce649f6e636885e3fc535007/goodconf-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ea59c25e75495270118a9afc8dbb8328", "sha256": "2c33460b4d9859ffacff32355b7effb1a922a16c1d54e8edd6452503bd8e809b" }, "downloads": -1, "filename": "goodconf-1.0.0.tar.gz", "has_sig": false, "md5_digest": "ea59c25e75495270118a9afc8dbb8328", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8880, "upload_time": "2018-07-18T21:33:12", "url": "https://files.pythonhosted.org/packages/5e/92/08363eeae5228562662b105c391dfe5c97d472a0e8ff5c43429be1b81301/goodconf-1.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "41c69a4bc9f839d2610a0d2be4eee24b", "sha256": "beb2f9ed734015e1becd4338d8b1e363cf51fb52e2f794f4e85e8c59d097442e" }, "downloads": -1, "filename": "goodconf-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "41c69a4bc9f839d2610a0d2be4eee24b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11814, "upload_time": "2018-07-18T21:33:10", "url": "https://files.pythonhosted.org/packages/84/33/30b77b95579c97a51865a58c377b456eaec1ce649f6e636885e3fc535007/goodconf-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ea59c25e75495270118a9afc8dbb8328", "sha256": "2c33460b4d9859ffacff32355b7effb1a922a16c1d54e8edd6452503bd8e809b" }, "downloads": -1, "filename": "goodconf-1.0.0.tar.gz", "has_sig": false, "md5_digest": "ea59c25e75495270118a9afc8dbb8328", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8880, "upload_time": "2018-07-18T21:33:12", "url": "https://files.pythonhosted.org/packages/5e/92/08363eeae5228562662b105c391dfe5c97d472a0e8ff5c43429be1b81301/goodconf-1.0.0.tar.gz" } ] }