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.
-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

  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.2.tar.gz (8.4 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.2-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file fetti-0.0.2.tar.gz.

File metadata

  • Download URL: fetti-0.0.2.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.27.2

File hashes

Hashes for fetti-0.0.2.tar.gz
Algorithm Hash digest
SHA256 a642a588dcb697e62d6d77df73e4a8aef3d07ed27a3de6dd0454b621650d5f87
MD5 453c6e99c47f0babbb8a6e93ab5a6caf
BLAKE2b-256 5608edca0878d868d70e70fef100fde032f644a0ed32a58cd9e6c06481a71c64

See more details on using hashes here.

File details

Details for the file fetti-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: fetti-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.27.2

File hashes

Hashes for fetti-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a2f82bd28459bc79f9c4617d1866caec7602264d617c0f2230cc05664cc9e93b
MD5 e09b081d79ad924beb10ffab0d8d4901
BLAKE2b-256 fa1db21e1565e31e496c7999f578ded3efd762f50b98e1a351d237cc3939308b

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