{ "info": { "author": "Artur Tamborski", "author_email": "tamborskiartur@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development" ], "description": "## cklass\n\n**Hierarchical config loader from files and env variables to class.**\n\nThis module takes care of loading configuration files, secret files \nand environment variables to single configuration class without a hassle!\n\n\n### Features:\n\n- easy to use (just one function!) and configure\n- comes with sane defaults\n- logical hierarchical order of importance\n- supports infinite number of file formats via custom format loaders\n- automatic lookup of config and secret files in specified directories\n\n\n### Constraints:\n\n- all keys are case-insensitive\n\n\n### Installation\n```bash\npip install cklass\n```\n\n### Usage\n\nAll you have to do is to create a class and call function\n`cklass.load_config()` with it as an argument.\n\n\n#### Case Sensitivity\n\nClass name (and nested classes which represent dictionaries)\nhave to be upper-cased or title-cased, eg. `Config` or `CONFIG`\nwill work, but `config` won't.\n\nAll variables that you want to search and match have to be upper-cased.\nThis also means that all keys are **not** case sensitive.\n\nFor example:\n```yaml\n# config.yaml\nlogin: 'this will be ignored'\npassword: 'this will be ignored'\n\nuSER:\n logIN: 'pi'\n paSSwoRD: 'raspberry'\n```\n```yaml\n# secret.yaml\nUser:\n # this will overwrite `logIN` and `pasSSwoRD` from above\n login: 'root' \n password: 'yrrebpsar'\n```\n```bash\n# env variable\nEXPORT USER__PASSWORD='mytopsecretpassword'\n```\n```python\n# python\nimport cklass \n\nclass User:\n LOGIN = 'this string will be overwritten'\n password = 'this will NOT be overwritten'\n Password = 'this will NOT be overwritten'\n PASSWORD = 'default password, will be overwritten'\n\n other_variable_kinda_like_private = 42\n\ncklass.load_config(User)\n``` \n\n\n#### Hierarchy\n\nEvery class-level keys have to be nested in top-level dictionary named\nsame as the class. Only class attributes will be overwritten,\nthere is _no_ possibility to add new attributes only by defining\nthem in configuration files.\n\nEach class loaded by `cklass.load_config()` will have it's attributes\noverwritten according to order specified below:\n\n1. All values defined in class code are considered as default\n2. Function will look for first config file with filename defined in \n`_config_filename` and found in `_config_filepath` list of dirs \nwill be taken into account and overwrite the values set in (1).\n3. Function will look for first secret file with filename defined in \n`_secret_filename` and found in `_secret_filepath` list of dirs \nwill be taken into account and overwrite the values set in (1) and (2).\n4. Function will look for matching environment variables of type `str`\nwith optional prefix defined in `_environ_prefix` and overwrite the values\nset in (1), (2) and (3).\n\n\n```python\n# python\nimport cklass\n\n# any name will work\nclass Config:\n\n PATH_TO_SOMETHING = '/etc/default/path/'\n\n class User:\n NAME = ''\n EMAIL = ''\n PASS = ''\n\n DEBUG = False\n\n class SERVER:\n OPEN_PORTS = ['80']\n\n SECRET_KEY = ''\n\n _type_safe = True\n _environ_prefix = 'MYAPP'\n _config_filename = 'config.yaml'\n _secret_filename = 'secret.json'\n _config_filepath = ['/etc/myapp/conf/']\n _secret_filepath = ['.']\n _format_loaders = {\n 'json': ['jsonlib', 'read'],\n 'yaml': ['metayaml', 'read'],\n }\n\n\ncklass.load_config(Config)\n```\n```yaml\n# config.yaml\nconfig:\n path-to-something: /etc/app/\n debug: True\n\n server:\n open-ports:\n - '22'\n - '80'\n - '443'\n```\n```yaml\n# secret.yaml\nconfig:\n user:\n name: Your Secret Name\n email: example@example.com\n```\n```bash\n# envvars.sh\nexport MYAPP__CONFIG__SECRET_KEY=\"supersecretkey\"\nexport MYAPP__CONFIG__USER__PASS=\"secretpassword\"\n```\n\n\n#### Default Values\n\nEvery class passed to `cklass.load_config()` can define below variables with appropriate\ntype for some manipulating it's behaviour.\n\nAll values specified below are considered as default. Any of these variables can be omitted.\n\n\n##### Type Safety\n\n```python\n_type_safe = True\n```\nThis will compare and ensure that all keys overwritten in config/secret file have the same\ntype as the variables defined in class except `None`. If set to `False` this check \nwill be skipped.\nExample: \n`Config.VALIDATE_ME = True` will match only `bool` type from config file. \n`Config.DOESNT_MATTER = None` will match any type from config file and environment variable\n`CONFIG__DOESNT_MATTER`.\n\n\n##### Environment Prefix\n\n```python\n_environ_prefix = ''\n```\nThis allows you to define custom environment variable prefix to act as a namespace.\nYou could for example set this to `'MYAPP'` which would cause to look up only\nenvironment variables starting with such prefix, like `MYAPP__CONFIG__HOME_DIR`.\nClass and nesting is defined with two underscores `__`, hence key names may contain\nonly single underscores - eg. `CORRECT_NAME`, `INCORRECT___NAME`.\n\nEnvironment variables support three types: bool converted from string `TRUE` / `FALSE`,\nnumbers converted from string with numbers and string if two previous conversions failed.\n\n\n##### Config / Secret File Names\n\n```python\n_config_filename = 'config.yaml'\n_secret_filename = 'secret.yaml'\n```\nFile name of the config. Extension has to match the defined one in `_format_loaders`.\n\n\n##### Config / Secret File Paths\n\n```python\n_config_filepath = ['.']\n_secret_filepath = ['.']\n```\nList of paths where function will look for `_config__filename` and `_secret_filename`.\nFor example, You could change it to `['~', '.']` which would cause the function to \nsearch for `config.yaml` in `$HOME/config.yaml` and then in `$PWD/config.yaml`.\nOnly the first file which will be successfully opened will be taken into account.\n\n\n##### Format Loaders\n```python\n_format_loaders = {\n 'ini': ['ini', 'load'],\n 'json': ['json', 'load'],\n 'toml': ['toml', 'load'],\n 'yaml': ['yaml', 'safe_load'],\n}\n```\n\nFormat loaders consists of a nested dictionary with key matching file extension\nand value defined as a two-element list. Default format loader enables the usage\nof `ini`, `json`, `toml` and `yaml` file types.\nIn order for this to work you need to have installed appropriate python packages\nspecified in the list. \nExample: `yaml: ['metayaml', 'read']` says that for any config/secret file\nwith `yaml` extension will be loaded via `read` function defined in `metayaml` module.\n\n\n#### Real-Live Example\n\nSee [examples](https://github.com/arturtamborski/cklass/tree/master/examples) directory.\n\n```python\n# config.py\nimport cklass\n\nclass Root:\n _environ_prefix = 'SIMPLEWEBAPP'\n _config_filepath = ['./conf']\n _secret_filepath = ['./conf']\n\nclass Common(Root):\n NAME = 'Simple Web App'\n DEBUG = True\n DATE = ''\n\n BASE_DIR = '/app'\n SRC_DIR = './src'\n\n ALLOWED_HOSTS = []\n\n class Secret:\n KEY = ''\n\n _config_filename = 'common.yaml'\n _secret_filename = 'common.json'\n\nclass Database(Root):\n ENGINE = 'sqlite3'\n HOST = 'localhost'\n NAME = 'simplewebapp_db'\n PORT = 1111\n\n class Credentials:\n USER = 'readonly'\n PASS = 'readonly'\n\n _config_filename = 'database.yaml'\n _secret_filename = 'database.json'\n\ncklass.load_config(Common)\ncklass.load_config(Database)\n\n\nprint(f'''\nCommon:\n NAME = '{Common.NAME}'\n DEBUG = {Common.DEBUG}\n DATE = '{Common.DATE}'\n\n BASE_DIR = '{Common.BASE_DIR}'\n SRC_DIR = '.{Common.SRC_DIR}'\n\n ALLOWED_HOSTS = {Common.ALLOWED_HOSTS}\n\n Secret:\n KEY = '{Common.Secret.KEY}'\n\n\nDatabase:\n ENGINE = '{Database.ENGINE}'\n HOST = '{Database.HOST}'\n NAME = '{Database.NAME}'\n PORT = {Database.PORT}\n\n Credentials:\n USER = {Database.Credentials.USER}'\n PASS = '{Database.Credentials.PASS}'\n''')\n``` \n```yaml\n# conf/common.yaml \nCommon:\n debug: no\n allowed-hosts:\n - 'localhost'\n - '127.0.0.1'\n - 'mydomain.local'\n```\n```json\n# conf/common.json\n{\n \"Common\": {\n \"Secret\": {\n \"key\": \"AAAAAAAA\"\n }\n }\n} \n``` \n```yaml\n# conf/database.yaml\nDatabase:\n engine: postgresql\n host: psql://localhost\n``` \n```json\n# conf/database.json\n{\n \"database\": {\n \"credentials\": {\n \"user\": \"dbuser\",\n \"pass\": \"pbpass\"\n }\n }\n} \n``` \n```bash\n# conf/environment.sh\n#!/bin/bash\n\nexport SIMPLEWEBAPP__COMMON__DEBUG=TRUE\nexport SIMPLEWEBAPP__COMMON__DATE=\"$(date)\"\nexport SIMPLEWEBAPP__COMMON__SECRET__KEY=\"seckey\"\n\nexport SIMPLEWEBAPP__DATABASE__PORT=6621\nexport SIMPLEWEBAPP__DATABASE__CREDENTIALS__PASS=\"supersecretdbpass\"\n```\n\n##### Result\n```bash\nsource conf/environment.sh\npython3 config.py\n```\n```python\nCommon:\n NAME = 'Simple Web App'\n\n # overwritten in conf/common.yaml\n # then overwritten by environment variable\n DEBUG = True\n\n # overwritten by environment variable\n DATE = 'Mon Apr 15 12:35:39 CEST 2019'\n\n BASE_DIR = '/app'\n SRC_DIR = './src'\n\n # overwritten in conf/common.yaml\n ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'mydomain.local']\n\n class Secret:\n # overwritten in conf/common.json\n # then overwritten by environment variable\n KEY = 'seckey'\n\nDatabase:\n # overwritten in conf/database.yaml\n ENGINE = 'postgresql'\n HOST = 'psql://localhost'\n NAME = 'simplewebapp_db'\n\n # overwritten by environment variable\n PORT = 6621\n\n class Credentials:\n # overwritten in conf/database.json\n USER = 'dbuser'\n\n # overwritten in conf/database.json\n # then overwritten by environment variable\n PASS = 'supersecretdbpass'\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/arturtamborski/cklass/archive/0.0.8.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/arturtamborski/cklass", "keywords": "configuration config loader", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "cklass", "package_url": "https://pypi.org/project/cklass/", "platform": "", "project_url": "https://pypi.org/project/cklass/", "project_urls": { "Download": "https://github.com/arturtamborski/cklass/archive/0.0.8.tar.gz", "Homepage": "https://github.com/arturtamborski/cklass" }, "release_url": "https://pypi.org/project/cklass/0.0.8/", "requires_dist": null, "requires_python": "", "summary": "Python module for loading config from files and env variables to class", "version": "0.0.8" }, "last_serial": 5245996, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "3587f11b22d8eb74b91896493adc6f20", "sha256": "08502de174a88ee90f9d5e092a7fc543bbb3e62bf02bd03e5fd7df6e89d4a87c" }, "downloads": -1, "filename": "cklass-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3587f11b22d8eb74b91896493adc6f20", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5860, "upload_time": "2019-04-15T10:54:45", "url": "https://files.pythonhosted.org/packages/77/07/0be2b3eb0cc984578dec52f99045728f44f154e9d601b0b440147f34609a/cklass-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6579d11ebcafb26b05702417f50a694f", "sha256": "ce608bfcc4565a6dfb25901e009ba7c5ec533b8dc20e1791e64adb6784fbfdd8" }, "downloads": -1, "filename": "cklass-0.0.1.tar.gz", "has_sig": false, "md5_digest": "6579d11ebcafb26b05702417f50a694f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5814, "upload_time": "2019-04-15T10:54:47", "url": "https://files.pythonhosted.org/packages/fe/f8/292c7e98475e1b8123344124f5e53babae8efbe79c5be849516d29535057/cklass-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "4fe6680759aaadaebd966819ffeccfde", "sha256": "f57993c4eb3a77319a113686fdd3774e3c8cf7b4697c828dfcc2acafd1156a37" }, "downloads": -1, "filename": "cklass-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4fe6680759aaadaebd966819ffeccfde", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5888, "upload_time": "2019-04-16T07:05:52", "url": "https://files.pythonhosted.org/packages/06/eb/ce38e1fa32e1b50eebfd622a99bbb81337b1a5a3294afccbd6890ea70c82/cklass-0.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4d9e2df572538eac0e221e3a78a5b332", "sha256": "49f4bde4cc10b6b23feb9a28002989aec98e6048a99330d207db46c156963b06" }, "downloads": -1, "filename": "cklass-0.0.2.tar.gz", "has_sig": false, "md5_digest": "4d9e2df572538eac0e221e3a78a5b332", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5841, "upload_time": "2019-04-16T07:05:53", "url": "https://files.pythonhosted.org/packages/17/1a/7e56115a77d411384ef767182037a74156b5311df6f4c0005dc572e7eed5/cklass-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "eb2ddeb05074cc4daee628988c76af3e", "sha256": "9b67cd76aaaf6ad3d8fe283aeafbd7fe8c8e3e9d64050aa8185e2f880fde6844" }, "downloads": -1, "filename": "cklass-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "eb2ddeb05074cc4daee628988c76af3e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6022, "upload_time": "2019-04-16T07:55:51", "url": "https://files.pythonhosted.org/packages/69/41/f989c5af11368336ea9a3855aeae5297284bebde3bb8f73cced4f60f5f93/cklass-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "61472b44a4cfcfb28526fb33c2a6d48e", "sha256": "3010a8ef1bcbf4c3b2a673f92a3a500d9d22599d43164792e0b74a84d624ea84" }, "downloads": -1, "filename": "cklass-0.0.3.tar.gz", "has_sig": false, "md5_digest": "61472b44a4cfcfb28526fb33c2a6d48e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5978, "upload_time": "2019-04-16T07:55:52", "url": "https://files.pythonhosted.org/packages/b6/15/fc47b35467203d4f68eb8d13533f7b58a5bf26a1b17ed27ffcff5c3fadad/cklass-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "ab971bcb2ecd77c6eb7debb6b967559b", "sha256": "099b9d734af305fbf9109f50b0b08a58ef9ec01342f83ac08823959dceb2d13f" }, "downloads": -1, "filename": "cklass-0.0.4.tar.gz", "has_sig": false, "md5_digest": "ab971bcb2ecd77c6eb7debb6b967559b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5973, "upload_time": "2019-04-23T01:55:52", "url": "https://files.pythonhosted.org/packages/d5/63/146c348de12ab0ca0299255d5343d633d77cd39ee08b52097032ef3b7fa7/cklass-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "9143049fc5cc01a3be924507e159c525", "sha256": "3ba1bc244eb7eb7af1c24bad56b2541f38e1bc000ec249e77ba18753ed0d46cb" }, "downloads": -1, "filename": "cklass-0.0.5.tar.gz", "has_sig": false, "md5_digest": "9143049fc5cc01a3be924507e159c525", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5970, "upload_time": "2019-04-23T02:02:50", "url": "https://files.pythonhosted.org/packages/61/9e/246c07174a94653c6afa619c04fdd1e75f498bf2f0aae1ae21f7f16ce33e/cklass-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "8e15f95034d7ab112c9812f99967c746", "sha256": "5b39ad7d6b830190506f22c04a5d4c4672a98b5e409b6a173b0e2f0f968d87d1" }, "downloads": -1, "filename": "cklass-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "8e15f95034d7ab112c9812f99967c746", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6019, "upload_time": "2019-04-23T02:12:48", "url": "https://files.pythonhosted.org/packages/cd/3d/1630c58bdf695064c2178f2e35bd0972a3727cb7d833c0fbecbd120e28e8/cklass-0.0.6-py3-none-any.whl" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "7a108cc11f60ae998466c3e5d8902b79", "sha256": "9054b291277b6bb3954d50c444a174b1f87054bdf9b9a8577c2f83280065cc9b" }, "downloads": -1, "filename": "cklass-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "7a108cc11f60ae998466c3e5d8902b79", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6206, "upload_time": "2019-05-07T17:44:00", "url": "https://files.pythonhosted.org/packages/79/c2/14b4de2266e29c9fbb21abd6fccb357a0249340f85626d8ad6ad35977bed/cklass-0.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5bdf5500db3df71a6968f2f775eb9f96", "sha256": "7812efd0b69ca02face23d2d422d43c51711ede50ba0fe946afa7bfa075d9287" }, "downloads": -1, "filename": "cklass-0.0.7.tar.gz", "has_sig": false, "md5_digest": "5bdf5500db3df71a6968f2f775eb9f96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6154, "upload_time": "2019-05-07T17:44:02", "url": "https://files.pythonhosted.org/packages/68/e7/dc485a991569a9257def1ec511a8a1bfa573c51b607a37b30d9194c847f1/cklass-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "4bdbc57a99b623a3880d1af23adc40ab", "sha256": "19799598bd1fac68803e00531a78be01200f492fbc9baf34429b99c7799a5303" }, "downloads": -1, "filename": "cklass-0.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "4bdbc57a99b623a3880d1af23adc40ab", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6190, "upload_time": "2019-05-09T07:21:58", "url": "https://files.pythonhosted.org/packages/03/7d/bfe9e65e4788514614c17d7be295e392778f3467aa90f74412f99430f904/cklass-0.0.8-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4bdbc57a99b623a3880d1af23adc40ab", "sha256": "19799598bd1fac68803e00531a78be01200f492fbc9baf34429b99c7799a5303" }, "downloads": -1, "filename": "cklass-0.0.8-py3-none-any.whl", "has_sig": false, "md5_digest": "4bdbc57a99b623a3880d1af23adc40ab", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6190, "upload_time": "2019-05-09T07:21:58", "url": "https://files.pythonhosted.org/packages/03/7d/bfe9e65e4788514614c17d7be295e392778f3467aa90f74412f99430f904/cklass-0.0.8-py3-none-any.whl" } ] }