Skip to main content

TOML-Powered Environment Injection.

Project description

🎉 fetti: TOML-Powered Environment Injection

PyPI - Version PyPI - Python Version codecov

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 fetti will 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/--namespace option (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 key host becomes SERVICE_DB_HOST. Keys are uppercased, and levels are joined by underscores (_).
  • Verbose Mode: Use -v/--verbose to 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-in tomllib).

📦 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

  1. When fetti encounters ${VAR_NAME} in a string value from your TOML file:
  2. It first looks for VAR_NAME among the other flattened keys derived from your TOML file.
  3. If not found there, it looks for VAR_NAME in the existing operating system environment variables.
  4. If VAR_NAME is not found in either location, it's replaced with an empty string.
  5. The interpolation is a single pass. For chained dependencies (e.g., A=${B}, B=${C}), ensure B appears or is processed before A if B itself is also defined in the TOML.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fetti-0.0.1.tar.gz (8.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fetti-0.0.1-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

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

Hashes for fetti-0.0.1.tar.gz
Algorithm Hash digest
SHA256 011664fbd274d0fd6bcdefa88c80fed707db050328491508a83f865d253b332c
MD5 932116ce27858aa039c36eb5a6156d84
BLAKE2b-256 d2bb78f91ad9996460fddfb6ab78c018110dc0ae56fd0346b686190e42adb834

See more details on using hashes here.

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

Hashes for fetti-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5332f93d77d5f80518a430b8cdefc1ead10cfbb5ec94c9496cd5335d2bc469e1
MD5 36b5a3fb031b17ffe2f2e38d04a2162b
BLAKE2b-256 e7668cf6d20a34be385ea2de00bf1c4478e66f53bf7092dbc92110ef89e7913a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page