![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.8|%203.9|%203.10|%203.11&color=blue?style=flat-square&logo=python)
![PyPI version](https://badge.fury.io/py/xsettings.svg?)
- [Introduction](#introduction)
- [Documentation](#documentation)
- [Install](#install)
- [Quick Start](#quick-start)
- [Licensing](#licensing)
# Introduction
Helps document and centralizing settings in a python project/library.
Facilitates looking up BaseSettings from `retrievers`, such as an environmental variable retriever.
Converts and standardizes any retrieved values to the type-hint on the setting attribute (such as bool, int, datetime, etc).
Interface to provide own custom retrievers, to grab settings/configuration from wherever you want.
Retrievers can be stacked, so multiple ones can be consulted when retrieving a setting.
See **[xsettings docs](https://xyngular.github.io/py-xsettings/latest/)**.
# Documentation
**[📄 Detailed Documentation](https://xyngular.github.io/py-xsettings/latest/)** | **[🐍 PyPi](https://pypi.org/project/xsettings/)**
# Install
```bash
# via pip
pip install xsettings
# via poetry
poetry add xsettings
```
# Quick Start
```python
from xsettings import EnvVarSettings, SettingsField
from xsettings.errors import SettingsValueError
from typing import Optional
import dataclasses
import os
# Used to showcase looking up env-vars automatically:
os.environ['app_version'] = '1.2.3'
# Used to showcase complex setting types:
@dataclasses.dataclass
class DBConfig:
@classmethod
def from_dict(cls, values: dict):
return DBConfig(**values)
user: str
host: str
password: str
# Some defined settings:
class MySettings(EnvVarSettings):
app_env: str = 'dev'
app_version: str
api_endpoint_url: str
some_number: int
# For Full Customization, allocate SettingsField,
# In this case an alternate setting lookup-name
# if you want the attribute name to differ from lookup name:
token: Optional[str] = SettingsField(name='API_TOKEN')
# Or if you wanted a custom-converter for a more complex obj:
db_config: DBConfig = SettingsField(
converter=DBConfig.from_dict
)
# BaseSettings subclasses are singleton-like dependencies that are
# also injectables and lazily-created on first-use.
# YOu can use a special `BaseSettings.grab()` class-method to
# get the current settings object.
#
# So you can grab the current MySettings object lazily via
# its `grab` class method:
MySettings.grab().some_number = 3
assert MySettings.grab().some_number == 3
# You can also use a proxy-object, it will lookup and use
# the current settings object each time its used:
my_settings = MySettings.proxy()
# Here I showcase setting a dict here and using the converter
# I defined on the SettingsField to convert it for me:
my_settings.db_config = {
'user': 'my-user',
'password': 'my-password',
'host': 'my-host'
}
expected = DBConfig(
user='my-user',
password='my-password',
host='my-host'
)
# The dict gets converted automatically to the DBConfig obj:
assert MySettings.grab().db_config == expected
# If you set a setting with the same/exact type as
# it's type-hint, then it won't call the converter:
my_settings.db_config = expected
# It's the same exact object-instance still (ie: not changed/converted):
assert my_settings.db_config is expected
# Will use the default value of `dev` (default value on class)
# since it was not set to anything else and there is no env-var for it:
assert my_settings.app_env == 'dev'
# EnvVarSettings (superclass) is configured to use the EnvVar retriever,
# and so it will find this in the environmental vars since it was not
# explicitly set to anything on settings object:
assert my_settings.app_version == '1.2.3'
# Any BaseSettings subclass can use dependency-injection:
assert my_settings.token is None
with MySettings(token='my-token'):
assert my_settings.token == 'my-token'
# Parent is still consulted for any settings unset on child but set on parent:
assert my_settings.db_config == expected
# Can set settings like you expect,
# this will go into the child created in above `with` statement:
my_settings.app_env = 'prod'
assert my_settings.app_env == 'prod'
# After `with` child is not the current settings object anymore,
# reverts back to what it was before:
assert my_settings.token is None
try:
# If a setting is undefined and required (ie: not-optional),
# and it was not set to anything nor is there a default or an env-var for it;
# BaseSettings will raise an exception when getting it:
print(my_settings.api_endpoint_url)
except SettingsValueError as e:
assert True
else:
assert False
try:
# `SettingsValueError` inherits from both AttributeError and ValueError,
# as the error could be due to either aspect; so you can also do an except
# for either standard error:
print(my_settings.api_endpoint_url)
except ValueError as e:
assert True
else:
assert False
```
# Licensing
This library is licensed under the MIT-0 License. See the LICENSE file.
Raw data
{
"_id": null,
"home_page": "https://github.com/xyngular/py-xsettings",
"name": "xsettings",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "settings,lazy,configuration",
"author": "Josh Orr",
"author_email": "josh@orr.blue",
"download_url": "https://files.pythonhosted.org/packages/08/64/ec581d934b4b2ae2ce79b593cdb0eb2a7431dd470e75ac830e2b6efd74e6/xsettings-1.4.0.tar.gz",
"platform": null,
"description": "![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.8|%203.9|%203.10|%203.11&color=blue?style=flat-square&logo=python)\n![PyPI version](https://badge.fury.io/py/xsettings.svg?)\n\n- [Introduction](#introduction)\n- [Documentation](#documentation)\n- [Install](#install)\n- [Quick Start](#quick-start)\n- [Licensing](#licensing)\n\n# Introduction\n\nHelps document and centralizing settings in a python project/library.\n\nFacilitates looking up BaseSettings from `retrievers`, such as an environmental variable retriever.\n\nConverts and standardizes any retrieved values to the type-hint on the setting attribute (such as bool, int, datetime, etc).\n\nInterface to provide own custom retrievers, to grab settings/configuration from wherever you want.\n\nRetrievers can be stacked, so multiple ones can be consulted when retrieving a setting.\n\nSee **[xsettings docs](https://xyngular.github.io/py-xsettings/latest/)**.\n\n# Documentation\n\n**[\ud83d\udcc4 Detailed Documentation](https://xyngular.github.io/py-xsettings/latest/)** | **[\ud83d\udc0d PyPi](https://pypi.org/project/xsettings/)**\n\n# Install\n\n```bash\n# via pip\npip install xsettings\n\n# via poetry\npoetry add xsettings\n```\n\n# Quick Start\n\n```python\nfrom xsettings import EnvVarSettings, SettingsField\nfrom xsettings.errors import SettingsValueError\nfrom typing import Optional\nimport dataclasses\nimport os\n\n# Used to showcase looking up env-vars automatically:\nos.environ['app_version'] = '1.2.3'\n\n# Used to showcase complex setting types:\n@dataclasses.dataclass\nclass DBConfig:\n @classmethod\n def from_dict(cls, values: dict):\n return DBConfig(**values)\n\n user: str\n host: str\n password: str\n\n\n# Some defined settings:\nclass MySettings(EnvVarSettings):\n app_env: str = 'dev'\n app_version: str\n api_endpoint_url: str\n \n some_number: int\n\n # For Full Customization, allocate SettingsField,\n # In this case an alternate setting lookup-name\n # if you want the attribute name to differ from lookup name:\n token: Optional[str] = SettingsField(name='API_TOKEN')\n\n # Or if you wanted a custom-converter for a more complex obj:\n db_config: DBConfig = SettingsField(\n converter=DBConfig.from_dict\n )\n\n# BaseSettings subclasses are singleton-like dependencies that are\n# also injectables and lazily-created on first-use.\n# YOu can use a special `BaseSettings.grab()` class-method to\n# get the current settings object.\n#\n# So you can grab the current MySettings object lazily via\n# its `grab` class method:\nMySettings.grab().some_number = 3\n\nassert MySettings.grab().some_number == 3\n\n# You can also use a proxy-object, it will lookup and use\n# the current settings object each time its used:\nmy_settings = MySettings.proxy()\n\n# Here I showcase setting a dict here and using the converter\n# I defined on the SettingsField to convert it for me:\nmy_settings.db_config = {\n 'user': 'my-user',\n 'password': 'my-password',\n 'host': 'my-host'\n}\n\n\nexpected = DBConfig(\n user='my-user',\n password='my-password',\n host='my-host'\n)\n\n# The dict gets converted automatically to the DBConfig obj:\nassert MySettings.grab().db_config == expected\n\n# If you set a setting with the same/exact type as\n# it's type-hint, then it won't call the converter:\nmy_settings.db_config = expected\n\n# It's the same exact object-instance still (ie: not changed/converted):\nassert my_settings.db_config is expected\n\n\n# Will use the default value of `dev` (default value on class)\n# since it was not set to anything else and there is no env-var for it:\nassert my_settings.app_env == 'dev'\n\n# EnvVarSettings (superclass) is configured to use the EnvVar retriever,\n# and so it will find this in the environmental vars since it was not\n# explicitly set to anything on settings object:\nassert my_settings.app_version == '1.2.3'\n\n# Any BaseSettings subclass can use dependency-injection:\nassert my_settings.token is None\n\nwith MySettings(token='my-token'):\n assert my_settings.token == 'my-token'\n\n # Parent is still consulted for any settings unset on child but set on parent:\n assert my_settings.db_config == expected\n\n # Can set settings like you expect,\n # this will go into the child created in above `with` statement:\n my_settings.app_env = 'prod'\n\n assert my_settings.app_env == 'prod'\n\n# After `with` child is not the current settings object anymore,\n# reverts back to what it was before:\nassert my_settings.token is None\n\ntry:\n # If a setting is undefined and required (ie: not-optional),\n # and it was not set to anything nor is there a default or an env-var for it;\n # BaseSettings will raise an exception when getting it:\n print(my_settings.api_endpoint_url)\nexcept SettingsValueError as e:\n assert True\nelse:\n assert False\n\ntry:\n # `SettingsValueError` inherits from both AttributeError and ValueError,\n # as the error could be due to either aspect; so you can also do an except\n # for either standard error:\n print(my_settings.api_endpoint_url)\nexcept ValueError as e:\n assert True\nelse:\n assert False\n```\n\n\n\n# Licensing\n\nThis library is licensed under the MIT-0 License. See the LICENSE file.\n",
"bugtrack_url": null,
"license": "",
"summary": "Ways to document, centeralize, retreive and validate settings.",
"version": "1.4.0",
"project_urls": {
"Homepage": "https://github.com/xyngular/py-xsettings",
"Repository": "https://github.com/xyngular/py-xsettings"
},
"split_keywords": [
"settings",
"lazy",
"configuration"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b5513c4d196b259088ff75b9b90aaa79220e052f74943b1302c3f946cfc37e07",
"md5": "8c3e2104379d6bde98374fee42e8f9ba",
"sha256": "dbba45b78670335a4e07d5d137c60a5f9e2c058d7899f7476b8e1b710bc8ad40"
},
"downloads": -1,
"filename": "xsettings-1.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8c3e2104379d6bde98374fee42e8f9ba",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 22462,
"upload_time": "2023-05-24T19:06:58",
"upload_time_iso_8601": "2023-05-24T19:06:58.498904Z",
"url": "https://files.pythonhosted.org/packages/b5/51/3c4d196b259088ff75b9b90aaa79220e052f74943b1302c3f946cfc37e07/xsettings-1.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "0864ec581d934b4b2ae2ce79b593cdb0eb2a7431dd470e75ac830e2b6efd74e6",
"md5": "5eb05845779d591ea945f1f1b0a9bed2",
"sha256": "b8eb46add0ea378aa284ed983c23c3e9c0eea65c9199529b53bab285fff2a60e"
},
"downloads": -1,
"filename": "xsettings-1.4.0.tar.gz",
"has_sig": false,
"md5_digest": "5eb05845779d591ea945f1f1b0a9bed2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 21385,
"upload_time": "2023-05-24T19:07:00",
"upload_time_iso_8601": "2023-05-24T19:07:00.257442Z",
"url": "https://files.pythonhosted.org/packages/08/64/ec581d934b4b2ae2ce79b593cdb0eb2a7431dd470e75ac830e2b6efd74e6/xsettings-1.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-24 19:07:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "xyngular",
"github_project": "py-xsettings",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "xsettings"
}