TOML-Powered Environment Injection.
Project description
🎉 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. |
-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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fetti-0.0.1.tar.gz.
File metadata
- Download URL: fetti-0.0.1.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: python-httpx/0.27.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
011664fbd274d0fd6bcdefa88c80fed707db050328491508a83f865d253b332c
|
|
| MD5 |
932116ce27858aa039c36eb5a6156d84
|
|
| BLAKE2b-256 |
d2bb78f91ad9996460fddfb6ab78c018110dc0ae56fd0346b686190e42adb834
|
File details
Details for the file fetti-0.0.1-py3-none-any.whl.
File metadata
- Download URL: fetti-0.0.1-py3-none-any.whl
- Upload date:
- Size: 7.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: python-httpx/0.27.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5332f93d77d5f80518a430b8cdefc1ead10cfbb5ec94c9496cd5335d2bc469e1
|
|
| MD5 |
36b5a3fb031b17ffe2f2e38d04a2162b
|
|
| BLAKE2b-256 |
e7668cf6d20a34be385ea2de00bf1c4478e66f53bf7092dbc92110ef89e7913a
|