User Guide¶

This guide covers the essential concepts and usage patterns for vein.

Basic Usage¶

Simple Assignment¶

vein makes configuration management as simple as variable assignment:

from vein import config

# Simple values
config.app_name = "my-service"
config.debug = True
config.max_workers = 10

# Nested configuration
config.database.host = "localhost"
config.database.port = 5432
config.database.ssl = True

# Dictionary-style access
config["api"]["key"] = "secret"
config["api"]["version"] = "v2"

Accessing Values¶

# Direct access
print(config.app_name)  # "my-service"
print(config.database.host)  # "localhost"

# Dictionary-style
print(config["api"]["key"])  # "secret"

# Get with default
timeout = config.get("timeout", 30)

The 3 Simple Rules¶

vein’s magic makes config values behave like regular Python values 99% of the time. For that 1%, here are the only rules you need:

Rule 1: Your Code → Just Use It Normally ✨¶

In your own code, vein values work exactly like regular Python values:

# Conditionals
if config.debug:
    print("Debug mode enabled")

# Math operations
if config.timeout > 30:
    config.retries = 5

# String operations
url = f"https://{config.api_host}/api/{config.version}"

# Type checking
isinstance(config.port, int)  # True ✅

Rule 2: External Libraries → Use .value 📦¶

When passing values to external libraries, use .value:

import requests
import redis

# External libraries need .value
response = requests.get(url, timeout=config.timeout.value)
r = redis.Redis(host=config.redis_host.value, port=config.redis_port.value)

# NumPy, pandas, etc.
import numpy as np
arr = np.array([config.scale_factor.value, config.offset.value])

Rule 3: When in Doubt → .value Always Works 🤷¶

If you’re unsure, .value is always safe:

# Always works
value = config.setting.value

# Useful for debugging
print(f"Current timeout: {config.timeout.value}")

Global vs Instance Configs¶

Using the Global Config (Most Common)¶

The global config is a singleton - the same instance everywhere:

# In app.py
from vein import config
config.api_key = "secret"

# In database.py
from vein import config
print(config.api_key)  # "secret" - it's the same config!

Creating Separate Instances¶

For isolated subsystems or testing:

from vein import Config

# Create independent configs
app_config = Config()
test_config = Config()
feature_flags = Config()

# They're completely independent
app_config.debug = True
test_config.debug = False  # Different value!

Type Support¶

vein preserves the types of your values:

config.port = 8080
config.ratio = 0.95
config.name = "FastAPI"
config.enabled = True
config.tags = ["api", "v2", "production"]
config.metadata = {"version": "1.0", "author": "vein"}

# Type checking works!
isinstance(config.port, int)     # True
isinstance(config.ratio, float)  # True
isinstance(config.name, str)     # True
isinstance(config.enabled, bool) # True
isinstance(config.tags, list)    # True
isinstance(config.metadata, dict)# True

Next Steps¶