🎉 fetti: TOML-Powered Environment Injection
fetti is a lightweight CLI tool that loads environment variables from a TOML
configuration file and executes any command with those variables injected. Think
of it as dotenv for your TOML files, supercharged with live command execution
and namespacing.
✨ Core Features
- TOML Configuration: Leverages the clear and structured TOML format for defining environment variables.
- Seamless Command Execution: Run any command or script, and
fettiwill provide it with the configured environment. - Variable Interpolation: Define dynamic values using
${VAR_NAME}syntax. Variables can reference:- Other values from the same (flattened) TOML configuration.
- Existing operating system environment variables.
- Namespace Scoping: Isolate specific sections of your configuration using the
-n/--namespaceoption (e.g., load only variables from a[database]section). - Automatic Key Flattening: Nested TOML tables are automatically converted into flat environment variable names. For example,
[service.db]with keyhostbecomesSERVICE_DB_HOST. Keys are uppercased, and levels are joined by underscores (_). - Verbose Mode: Use
-v/--verboseto see which variables are being injected. - Minimal & Fast: Built with Python and
click, aiming for efficiency with minimal dependencies. Requires Python 3.11+ (for built-intomllib).
📦 Installation
Ensure you have Python 3.11+ installed.
pip install fetti
(For Python versions older than 3.11, fetti will also install the toml package if tomllib is not available in the standard library.)
⚙️ CLI Usage
fetti [OPTIONS] FILE -- COMMAND [ARGS]...
Arguments:
| Name | Description |
|---|---|
FILE |
Path to your TOML configuration file. |
COMMAND |
The command to execute after loading the environment. |
ARGS... |
Any arguments for the COMMAND. |
Options:
| Flag | Description |
|---|---|
-n, --namespace NAME |
Use only a specific top-level section (table) from the TOML file. |
-k, --key NAME |
Use only a specific second-level section (subtable) from the TOML file. |
-v, --verbose |
Print the environment variables loaded from TOML before running the command. |
-h, --help |
Show the help message and exit. |
Note: The -- separator is crucial. Everything after it is considered part of the command to be executed.
🧪 Quick Start Example
Given a config.toml:
# config.toml
APP_VERSION = "1.0"
[database]
host = "localhost"
port = 5432
user = "admin"
# Interpolates other values from this 'database' scope once flattened
url = "postgres://${DATABASE_USER}@${DATABASE_HOST}:${DATABASE_PORT}/mydb"
[api_service]
# Interpolates from OS environment if API_KEY_SECRET is set there
# Otherwise, if API_KEY_SECRET is also in this config, it uses that.
key = "${API_KEY_SECRET}"
1. Load variables from the database namespace:
fetti config.toml -n database -- python my_script.py
Inside my_script.py:
import os
print(f"DB URL: {os.environ.get('DATABASE_URL')}")
# Output (example): DB URL: postgres://admin@localhost:5432/mydb
print(f"App Version (not loaded): {os.environ.get('APP_VERSION')}") # Will be None
2. Load all variables (no namespace):
# Assuming API_KEY_SECRET is "mysecret" in your OS environment
export API_KEY_SECRET="mysecret"
fetti config.toml -- env | grep -E "(DATABASE_URL|APP_VERSION|API_SERVICE_KEY)"
Output:
APP_VERSION=1.0
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=admin
DATABASE_URL=postgres://admin@localhost:5432/mydb
API_SERVICE_KEY=mysecret
🛠 Advanced: Nested Configuration & Interpolation
fetti handles nested TOML tables by flattening their keys.
Consider settings.toml:
# settings.toml
project_name = "AwesomeProject"
[service.auth]
issuer = "auth.example.com"
token_expiry_minutes = 60
[service.env.db]
host = "db.internal"
port = 5432
# Interpolation uses already flattened keys from this config:
# SERVICE_AUTH_ISSUER, PROJECT_NAME, SERVICE_ENV_DB_PORT
# It will also check os.environ if a var isn't in the TOML.
connection_string = "user@${SERVICE_ENV_DB_HOST}:${SERVICE_ENV_DB_PORT}/${PROJECT_NAME}?issuer=${SERVICE_AUTH_ISSUER}"
Run with the service namespace:
fetti settings.toml -n service -- printenv | grep -E "(SERVICE_AUTH_ISSUER|SERVICE_ENV_DB_CONNECTION_STRING)"
Expected Output:
SERVICE_AUTH_ISSUER=auth.example.com
SERVICE_ENV_DB_HOST=db.internal
SERVICE_ENV_DB_PORT=5432
SERVICE_ENV_DB_CONNECTION_STRING=user@db.internal:5432/AwesomeProject?issuer=auth.example.com
💡 How Interpolation Works
- When
fettiencounters${VAR_NAME}in a string value from your TOML file: - It first looks for
VAR_NAMEamong the other flattened keys derived from your TOML file. - If not found there, it looks for
VAR_NAMEin the existing operating system environment variables. - If
VAR_NAMEis not found in either location, it's replaced with an empty string. - The interpolation is a single pass. For chained dependencies (e.g.,
A=${B},B=${C}), ensureBappears or is processed beforeAifBitself is also defined in the TOML.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
Metadata
Release files for fetti 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fetti-0.0.2.tar.gz | 8.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fetti-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.8 kB
Release files / fetti-0.0.2.tar.gz
| Download URL | fetti-0.0.2.tar.gz |
|---|---|
| Size | 8.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a642a588dcb697e62d6d77df73e4a8aef3d07ed27a3de6dd0454b621650d5f87
|
|
BLAKE2b-256 checksum How to use checksums |
5608edca0878d868d70e70fef100fde032f644a0ed32a58cd9e6c06481a71c64
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.27.2
|
Release files / fetti-0.0.2-py3-none-any.whl
| Download URL | fetti-0.0.2-py3-none-any.whl |
|---|---|
| Size | 8.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2f82bd28459bc79f9c4617d1866caec7602264d617c0f2230cc05664cc9e93b
|
|
BLAKE2b-256 checksum How to use checksums |
fa1db21e1565e31e496c7999f578ded3efd762f50b98e1a351d237cc3939308b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-httpx/0.27.2
|