<h2>
<p style="text-align: center;">
TomlEv - Open-source Python framework to manage environment variables
</p>
</h2>
---
[](https://pypi.python.org/pypi/tomlev/)
[](https://github.com/thesimj/tomlev/actions/workflows/main.yml)
[](https://coveralls.io/github/thesimj/tomlev?branch=main)

[](https://github.com/astral-sh/ruff)
[](LICENSE)
[](https://pepy.tech/project/tomlev)
### Motivation
TomlEv is a lightweight Python framework designed to simplify environment variable management using TOML configuration
files with type-safe configuration models. It allows you to:
- **Type-safe configuration**: Define configuration schemas using Python classes with type hints
- **Automatic type conversion**: Convert environment variables to appropriate types (bool, int, float, str, lists,
dicts)
- **Nested configuration**: Support for complex nested configuration structures
- **Environment variable substitution**: Reference environment variables in TOML files with `${VAR|-default}` syntax
- **Validation**: Automatic validation of configuration structure and types
- **IDE support**: Full IDE autocompletion and type checking support
### Install
```shell
# pip
pip install tomlev
```
```shell
# uv
uv add tomlev
```
```shell
# poetry
poetry add tomlev
```
### Basic usage
#### 1. Define Configuration Models
Create configuration model classes that inherit from `BaseConfigModel`:
```python
from tomlev import BaseConfigModel, TomlEv
class DatabaseConfig(BaseConfigModel):
host: str
port: int
user: str
password: str
name: str
class RedisConfig(BaseConfigModel):
host: str
port: int
class AppConfig(BaseConfigModel):
app_name: str
debug: bool
environment: str
database: DatabaseConfig
redis: RedisConfig
```
#### 2. Create a TOML configuration file
Create a TOML configuration file (`env.toml` by default):
```toml
# env.toml
app_name = "My Application"
debug = "${DEBUG|-false}"
environment = "${ENV|-development}"
[database]
host = "${DB_HOST|-localhost}"
port = "${DB_PORT|-5432}"
user = "${DB_USER}"
password = "${DB_PASSWORD}"
name = "${DB_NAME|-app_db}"
[redis]
host = "${REDIS_HOST|-127.0.0.1}"
port = "${REDIS_PORT|-6379}"
```
#### 3. Use TomlEv in your Python code
```python
from tomlev import TomlEv
# Load and validate configuration (using defaults: "env.toml" and ".env")
config: AppConfig = TomlEv(AppConfig).validate()
# Or explicitly specify files (same as defaults)
config: AppConfig = TomlEv(AppConfig, "env.toml", ".env").validate()
# Access configuration with type safety
print(f"App: {config.app_name}")
print(f"Environment: {config.environment}")
print(f"Debug mode: {config.debug}") # Automatically converted to bool
# Access nested configuration
db_host = config.database.host
db_port = config.database.port # Automatically converted to int
# All properties are type-safe and validated
redis_host = config.redis.host
redis_port = config.redis.port # Automatically converted to int
```
### Configuration Models
TomlEv uses `BaseConfigModel` to provide type-safe configuration handling. Here are the supported types:
#### Supported Types
- **Basic types**: `str`, `int`, `float`, `bool`
- **Collections**: `list[T]`, `dict[str, T]` where T is any supported type
- **Complex collections**: `list[dict[str, Any]]` for lists of dictionaries
- **Nested models**: Other `BaseConfigModel` subclasses
- **Generic types**: `typing.Any` for flexible values
#### Advanced Example
```python
from typing import Any
from tomlev import BaseConfigModel, TomlEv
class QueryConfig(BaseConfigModel):
get_version: str
get_users: str
class DatabaseConfig(BaseConfigModel):
host: str
port: int
user: str
password: str
name: str
uri: str
queries: dict[str, str] # Dictionary of queries
class RedisConfig(BaseConfigModel):
host: str
port: int
keys: list[str] # List of strings
nums: list[int] # List of integers
atts: list[dict[str, Any]] # List of dictionaries
weight: int
mass: float
class AppConfig(BaseConfigModel):
debug: bool
environment: str
temp: float
database: DatabaseConfig
redis: RedisConfig
# Usage with .env file support (uses defaults: "env.toml" and ".env")
config: AppConfig = TomlEv(
AppConfig,
"env.toml", # Default TOML file
".env" # Default .env file
).validate()
# Or simply use defaults
config: AppConfig = TomlEv(AppConfig).validate()
```
#### TOML File with Complex Types
```toml
debug = "${DEBUG|-false}"
environment = "${CI_ENVIRONMENT_SLUG|-develop}"
temp = "${TEMP_VAL|--20.5}"
[database]
host = "${DB_HOST|-localhost}"
port = "${DB_PORT|-5432}"
user = "${DB_USER}"
password = "${DB_PASSWORD}"
name = "${DB_NAME|-app_db}"
uri = "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST|-localhost}:${DB_PORT|-5432}/${DB_NAME|-app_db}"
[database.queries]
get_version = """SELECT version();"""
get_users = """SELECT * FROM "users";"""
[redis]
host = "${REDIS_HOST|-127.0.0.1}"
port = "${REDIS_PORT|-6379}"
keys = ["one", "two", "three"]
nums = [10, 12, 99]
atts = [{ name = "one", age = 10 }, { name = "two", age = 12 }]
weight = 0.98
mass = 0.78
```
### Strict mode
By default, TomlEv operates in strict mode, which means it will raise a `ValueError` if:
1. An environment variable referenced in the TOML file is not defined and has no default value
2. The same variable is defined multiple times in the .env file
This helps catch configuration errors early. You can disable strict mode in two ways:
```python
# Method 1: Set the environment variable TOMLEV_STRICT_DISABLE
import os
os.environ["TOMLEV_STRICT_DISABLE"] = "true"
config = TomlEv(AppConfig).validate() # Uses defaults: "env.toml" and ".env"
# Method 2: Pass strict=False when creating the TomlEv instance
config = TomlEv(AppConfig, strict=False).validate() # Uses defaults with strict=False
```
When strict mode is disabled, TomlEv will not raise errors for missing environment variables or duplicate definitions.
### Support
If you like **TomlEv**, please give it a star ⭐ https://github.com/thesimj/tomlev
### License
MIT licensed. See the [LICENSE](LICENSE) file for more details.
Raw data
{
"_id": null,
"home_page": null,
"name": "tomlev",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "config-management, configuration, environment-variables, python311, settings, toml, type-hints, type-safety, validation",
"author": null,
"author_email": "Nick Bubelich <m+github@bubelich.com>",
"download_url": "https://files.pythonhosted.org/packages/86/8a/77c3dd19bc3882dc0c5a04f5c621aa9c41e8b61e4b71b0a3e4c64ba13db9/tomlev-1.0.1.tar.gz",
"platform": null,
"description": "<h2>\n <p style=\"text-align: center;\">\n TomlEv - Open-source Python framework to manage environment variables\n </p>\n</h2>\n\n---\n[](https://pypi.python.org/pypi/tomlev/)\n[](https://github.com/thesimj/tomlev/actions/workflows/main.yml)\n[](https://coveralls.io/github/thesimj/tomlev?branch=main)\n\n[](https://github.com/astral-sh/ruff)\n[](LICENSE)\n[](https://pepy.tech/project/tomlev)\n\n### Motivation\n\nTomlEv is a lightweight Python framework designed to simplify environment variable management using TOML configuration\nfiles with type-safe configuration models. It allows you to:\n\n- **Type-safe configuration**: Define configuration schemas using Python classes with type hints\n- **Automatic type conversion**: Convert environment variables to appropriate types (bool, int, float, str, lists,\n dicts)\n- **Nested configuration**: Support for complex nested configuration structures\n- **Environment variable substitution**: Reference environment variables in TOML files with `${VAR|-default}` syntax\n- **Validation**: Automatic validation of configuration structure and types\n- **IDE support**: Full IDE autocompletion and type checking support\n\n### Install\n\n```shell\n# pip\npip install tomlev\n```\n\n```shell\n# uv\nuv add tomlev\n```\n\n```shell\n# poetry\npoetry add tomlev\n```\n\n### Basic usage\n\n#### 1. Define Configuration Models\n\nCreate configuration model classes that inherit from `BaseConfigModel`:\n\n```python\nfrom tomlev import BaseConfigModel, TomlEv\n\n\nclass DatabaseConfig(BaseConfigModel):\n host: str\n port: int\n user: str\n password: str\n name: str\n\n\nclass RedisConfig(BaseConfigModel):\n host: str\n port: int\n\n\nclass AppConfig(BaseConfigModel):\n app_name: str\n debug: bool\n environment: str\n\n database: DatabaseConfig\n redis: RedisConfig\n```\n\n#### 2. Create a TOML configuration file\n\nCreate a TOML configuration file (`env.toml` by default):\n\n```toml\n# env.toml\napp_name = \"My Application\"\ndebug = \"${DEBUG|-false}\"\nenvironment = \"${ENV|-development}\"\n\n[database]\nhost = \"${DB_HOST|-localhost}\"\nport = \"${DB_PORT|-5432}\"\nuser = \"${DB_USER}\"\npassword = \"${DB_PASSWORD}\"\nname = \"${DB_NAME|-app_db}\"\n\n[redis]\nhost = \"${REDIS_HOST|-127.0.0.1}\"\nport = \"${REDIS_PORT|-6379}\"\n```\n\n#### 3. Use TomlEv in your Python code\n\n```python\nfrom tomlev import TomlEv\n\n# Load and validate configuration (using defaults: \"env.toml\" and \".env\")\nconfig: AppConfig = TomlEv(AppConfig).validate()\n\n# Or explicitly specify files (same as defaults)\nconfig: AppConfig = TomlEv(AppConfig, \"env.toml\", \".env\").validate()\n\n# Access configuration with type safety\nprint(f\"App: {config.app_name}\")\nprint(f\"Environment: {config.environment}\")\nprint(f\"Debug mode: {config.debug}\") # Automatically converted to bool\n\n# Access nested configuration\ndb_host = config.database.host\ndb_port = config.database.port # Automatically converted to int\n\n# All properties are type-safe and validated\nredis_host = config.redis.host\nredis_port = config.redis.port # Automatically converted to int\n```\n\n### Configuration Models\n\nTomlEv uses `BaseConfigModel` to provide type-safe configuration handling. Here are the supported types:\n\n#### Supported Types\n\n- **Basic types**: `str`, `int`, `float`, `bool`\n- **Collections**: `list[T]`, `dict[str, T]` where T is any supported type\n- **Complex collections**: `list[dict[str, Any]]` for lists of dictionaries\n- **Nested models**: Other `BaseConfigModel` subclasses\n- **Generic types**: `typing.Any` for flexible values\n\n#### Advanced Example\n\n```python\nfrom typing import Any\nfrom tomlev import BaseConfigModel, TomlEv\n\n\nclass QueryConfig(BaseConfigModel):\n get_version: str\n get_users: str\n\n\nclass DatabaseConfig(BaseConfigModel):\n host: str\n port: int\n user: str\n password: str\n name: str\n uri: str\n queries: dict[str, str] # Dictionary of queries\n\n\nclass RedisConfig(BaseConfigModel):\n host: str\n port: int\n keys: list[str] # List of strings\n nums: list[int] # List of integers\n atts: list[dict[str, Any]] # List of dictionaries\n weight: int\n mass: float\n\n\nclass AppConfig(BaseConfigModel):\n debug: bool\n environment: str\n temp: float\n\n database: DatabaseConfig\n redis: RedisConfig\n\n\n# Usage with .env file support (uses defaults: \"env.toml\" and \".env\")\nconfig: AppConfig = TomlEv(\n AppConfig,\n \"env.toml\", # Default TOML file\n \".env\" # Default .env file\n).validate()\n\n# Or simply use defaults\nconfig: AppConfig = TomlEv(AppConfig).validate()\n```\n\n#### TOML File with Complex Types\n\n```toml\ndebug = \"${DEBUG|-false}\"\nenvironment = \"${CI_ENVIRONMENT_SLUG|-develop}\"\ntemp = \"${TEMP_VAL|--20.5}\"\n\n[database]\nhost = \"${DB_HOST|-localhost}\"\nport = \"${DB_PORT|-5432}\"\nuser = \"${DB_USER}\"\npassword = \"${DB_PASSWORD}\"\nname = \"${DB_NAME|-app_db}\"\nuri = \"postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST|-localhost}:${DB_PORT|-5432}/${DB_NAME|-app_db}\"\n\n[database.queries]\nget_version = \"\"\"SELECT version();\"\"\"\nget_users = \"\"\"SELECT * FROM \"users\";\"\"\"\n\n[redis]\nhost = \"${REDIS_HOST|-127.0.0.1}\"\nport = \"${REDIS_PORT|-6379}\"\nkeys = [\"one\", \"two\", \"three\"]\nnums = [10, 12, 99]\natts = [{ name = \"one\", age = 10 }, { name = \"two\", age = 12 }]\nweight = 0.98\nmass = 0.78\n```\n\n### Strict mode\n\nBy default, TomlEv operates in strict mode, which means it will raise a `ValueError` if:\n\n1. An environment variable referenced in the TOML file is not defined and has no default value\n2. The same variable is defined multiple times in the .env file\n\nThis helps catch configuration errors early. You can disable strict mode in two ways:\n\n```python\n# Method 1: Set the environment variable TOMLEV_STRICT_DISABLE\nimport os\n\nos.environ[\"TOMLEV_STRICT_DISABLE\"] = \"true\"\nconfig = TomlEv(AppConfig).validate() # Uses defaults: \"env.toml\" and \".env\"\n\n# Method 2: Pass strict=False when creating the TomlEv instance\nconfig = TomlEv(AppConfig, strict=False).validate() # Uses defaults with strict=False\n```\n\nWhen strict mode is disabled, TomlEv will not raise errors for missing environment variables or duplicate definitions.\n\n### Support\n\nIf you like **TomlEv**, please give it a star \u2b50 https://github.com/thesimj/tomlev\n\n### License\n\nMIT licensed. See the [LICENSE](LICENSE) file for more details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Type-safe TOML configuration management with environment variable substitution and automatic validation for modern Python applications.",
"version": "1.0.1",
"project_urls": {
"Bug Tracker": "https://github.com/thesimj/tomlev/issues",
"Changelog": "https://github.com/thesimj/tomlev/blob/main/CHANGELOG.md",
"Discussions": "https://github.com/thesimj/tomlev/discussions",
"Documentation": "https://github.com/thesimj/tomlev/blob/main/README.md",
"Funding": "https://github.com/sponsors/thesimj",
"Homepage": "https://github.com/thesimj/tomlev",
"Repository": "https://github.com/thesimj/tomlev",
"Security": "https://github.com/thesimj/tomlev/security"
},
"split_keywords": [
"config-management",
" configuration",
" environment-variables",
" python311",
" settings",
" toml",
" type-hints",
" type-safety",
" validation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "9a8adfb00125923d21b5a025dbadbc5e3b43285ddc13759224a806532d8b4f57",
"md5": "49a39a816dbdf590f22be2a868c0b74e",
"sha256": "7518eadce552273e2d965bdf9fc9fbb8d4ce2958efcf1a6159574e31fd9e1d46"
},
"downloads": -1,
"filename": "tomlev-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "49a39a816dbdf590f22be2a868c0b74e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 13079,
"upload_time": "2025-09-08T23:12:45",
"upload_time_iso_8601": "2025-09-08T23:12:45.468798Z",
"url": "https://files.pythonhosted.org/packages/9a/8a/dfb00125923d21b5a025dbadbc5e3b43285ddc13759224a806532d8b4f57/tomlev-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "868a77c3dd19bc3882dc0c5a04f5c621aa9c41e8b61e4b71b0a3e4c64ba13db9",
"md5": "7622423b27a79c264b2e5392316ad4d8",
"sha256": "e4e4dbb47ef4990fdaa36d7d43b5fc806cf3e28d7222bf3023cfe05577702660"
},
"downloads": -1,
"filename": "tomlev-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "7622423b27a79c264b2e5392316ad4d8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 37321,
"upload_time": "2025-09-08T23:12:46",
"upload_time_iso_8601": "2025-09-08T23:12:46.747544Z",
"url": "https://files.pythonhosted.org/packages/86/8a/77c3dd19bc3882dc0c5a04f5c621aa9c41e8b61e4b71b0a3e4c64ba13db9/tomlev-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-08 23:12:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "thesimj",
"github_project": "tomlev",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "tomlev"
}