# `yapeco`: Yet Another Python Envvar Config Object
A positively miniscule utility module to access `.env` (and otherwise environment-defined) config values in a structured way through a Python object. Created out of annoyance with not being able to autocomplete said envvars in my editor :^)
## Features & Limitations
- Case-insensitive + snake-case (i.e. `SNAKE_case`) field names
- Primitives such as `str`, `bool`, `int` and `float` are supported (no guarantees with `float` though, because, well... floating point)
- Assuming use of the above primitives, supports `Optional[*]` types (and by extension `Union[*,None]`), but no others from `typing`
- Default values through class variable assignment; assumed to be `None` for optional types
- Will (intentionally) raise a `RuntimeError` if there is no value set and no default value
- Common boolean config formats (i.e. `VAR=0/1/true/false/True/False`) work as expected
## Usage
Installation (PyPI):
```bash
pip3 install yapeco
```
A simple example:
```bash
# -- [mock environment] ---------------------------
API_KEY=abc123
DELAY_MSEC=18
FEATURE_A_ENABLED=false
FEATURE_B_ENABLED=1
```
```python
# --- contrived_config.py -------------------------
from yapeco import BaseEnvironment as Env
class Config(Env):
api_key: str
delay_msec: int
feature_a_enabled: bool
feature_a_flags: str = "-a -b -c"
feature_b_enabled: bool
feature_b_flags: Optional[str]
# --- main.py -------------------------------------
from config import Config
Config.api_key # "abc123"
Config.delay_msec # 18
Config.feature_a_enabled # False
Config.feature_a_flags # "-a -b -c"
Config.feature_b_enabled # True
Config.feature_b_flags # None
# ...
# API_KEY=def456
# FEATURE_B_ENABLED=false
Config.refresh() # update environment
Config.api_key # "def456"
Config.feature_b_enabled # False
```
## Development
Requires [poetry](https://python-poetry.org/).
```bash
poetry install # install dependencies
poetry build # build package
poetry run pytest . # run tests
poetry run pyright . # run type checks
```
## Feature Backburner
- Support implied types (type conversion currently depends on `cls.__annotations__`)
## Extra
Pedantic note:
> As in Smalltalk, classes themselves are objects.
>
> —[The Literal Python Documentation](https://docs.python.org/3/tutorial/classes.html)
Raw data
{
"_id": null,
"home_page": "https://github.com/turtlebasket/yapeco",
"name": "yapeco",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "python, config, environment, dotenv, variables",
"author": "Michael Lisano",
"author_email": "mlisano@protonmail.com",
"download_url": "https://files.pythonhosted.org/packages/cf/20/d35ff9ff81412010a8b23aaf69f836e4fe73639d22d5e80feaf2d0e4e5a3/yapeco-0.1.4.tar.gz",
"platform": null,
"description": "# `yapeco`: Yet Another Python Envvar Config Object\n\nA positively miniscule utility module to access `.env` (and otherwise environment-defined) config values in a structured way through a Python object. Created out of annoyance with not being able to autocomplete said envvars in my editor :^)\n\n## Features & Limitations\n\n- Case-insensitive + snake-case (i.e. `SNAKE_case`) field names\n- Primitives such as `str`, `bool`, `int` and `float` are supported (no guarantees with `float` though, because, well... floating point)\n- Assuming use of the above primitives, supports `Optional[*]` types (and by extension `Union[*,None]`), but no others from `typing`\n- Default values through class variable assignment; assumed to be `None` for optional types\n- Will (intentionally) raise a `RuntimeError` if there is no value set and no default value\n- Common boolean config formats (i.e. `VAR=0/1/true/false/True/False`) work as expected\n\n## Usage\n\nInstallation (PyPI):\n\n```bash\npip3 install yapeco\n```\n\nA simple example:\n\n```bash\n# -- [mock environment] ---------------------------\nAPI_KEY=abc123\nDELAY_MSEC=18\nFEATURE_A_ENABLED=false\nFEATURE_B_ENABLED=1\n```\n\n```python\n# --- contrived_config.py -------------------------\n\nfrom yapeco import BaseEnvironment as Env\n\nclass Config(Env):\n api_key: str\n delay_msec: int\n feature_a_enabled: bool\n feature_a_flags: str = \"-a -b -c\"\n feature_b_enabled: bool\n feature_b_flags: Optional[str]\n\n\n# --- main.py -------------------------------------\n\nfrom config import Config\n\nConfig.api_key # \"abc123\"\nConfig.delay_msec # 18\nConfig.feature_a_enabled # False\nConfig.feature_a_flags # \"-a -b -c\"\nConfig.feature_b_enabled # True\nConfig.feature_b_flags # None\n\n# ...\n# API_KEY=def456\n# FEATURE_B_ENABLED=false\n\nConfig.refresh() # update environment\n\nConfig.api_key # \"def456\"\nConfig.feature_b_enabled # False\n```\n\n## Development\n\nRequires [poetry](https://python-poetry.org/).\n\n```bash\npoetry install # install dependencies\npoetry build # build package\npoetry run pytest . # run tests\npoetry run pyright . # run type checks\n```\n\n## Feature Backburner\n\n- Support implied types (type conversion currently depends on `cls.__annotations__`)\n\n## Extra\n\nPedantic note:\n\n> As in Smalltalk, classes themselves are objects. \n>\n> \u2014[The Literal Python Documentation](https://docs.python.org/3/tutorial/classes.html)\n",
"bugtrack_url": null,
"license": "AGPL-3.0-or-later",
"summary": "Yet Another Python Envvar Config Object",
"version": "0.1.4",
"project_urls": {
"Homepage": "https://github.com/turtlebasket/yapeco",
"Repository": "https://github.com/turtlebasket/yapeco"
},
"split_keywords": [
"python",
" config",
" environment",
" dotenv",
" variables"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "78ab79823d8dbc053ad512baecec45a5b756ddc7e78940d02dd6ac672a7b9136",
"md5": "57656387c14f86bbe6c4f9dde2c1d92a",
"sha256": "69c4bddd72566074735a4444e0a30facedaef870f46c54ef5cc2ad31bb4ab849"
},
"downloads": -1,
"filename": "yapeco-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "57656387c14f86bbe6c4f9dde2c1d92a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 3344,
"upload_time": "2025-08-18T01:27:40",
"upload_time_iso_8601": "2025-08-18T01:27:40.302394Z",
"url": "https://files.pythonhosted.org/packages/78/ab/79823d8dbc053ad512baecec45a5b756ddc7e78940d02dd6ac672a7b9136/yapeco-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "cf20d35ff9ff81412010a8b23aaf69f836e4fe73639d22d5e80feaf2d0e4e5a3",
"md5": "d228bfa94a93d81a94766b27e4428eae",
"sha256": "948aa522c46f92afed0db8e6bcd2714b2cd59b476880fa82172f3a9c10a51be9"
},
"downloads": -1,
"filename": "yapeco-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "d228bfa94a93d81a94766b27e4428eae",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 2954,
"upload_time": "2025-08-18T01:27:41",
"upload_time_iso_8601": "2025-08-18T01:27:41.068213Z",
"url": "https://files.pythonhosted.org/packages/cf/20/d35ff9ff81412010a8b23aaf69f836e4fe73639d22d5e80feaf2d0e4e5a3/yapeco-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-18 01:27:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "turtlebasket",
"github_project": "yapeco",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "yapeco"
}