Modern, schema-first environment variable loader and manager for Python.
Project description
envsmith
A modern, production-ready solution for loading, validating, and managing environment variables in Python using a schema-first approach.
๐ How It Works
envsmith is a Python package that provides a robust way to manage environment variables with the following workflow:
-
Schema Definition: You define a YAML or JSON schema that specifies:
- Which environment variables are required
- What data types they should have
- Default values for optional variables
- Validation rules
-
Environment Loading: The package loads variables from multiple sources:
.envfiles- System environment variables
- Custom dictionaries
- Priority: System > .env file > defaults
-
Validation & Type Casting: Each variable is validated against the schema:
- Required variables are checked for presence
- Values are cast to the specified types (str, int, float, bool)
- Helpful error messages for missing/invalid variables
-
Integration: Seamlessly integrates with FastAPI and Django applications
๐ง Technical Architecture
Core Processing Pipeline
class EnvSmith(dict):
def __init__(self, schema_path, env_file=".env", env=None):
# Step 1: Load .env file into environment
load_dotenv(env_file)
# Step 2: Parse schema file (YAML/JSON)
self.schema = load_schema(schema_path)
# Step 3: Get environment (system + .env merged)
self.env = env or dict(os.environ)
# Step 4: Validate and cast types
validated = validate_env(self.env, self.schema)
# Step 5: Update the dictionary
self.update(validated)
Data Flow & Priority System
- Schema Loading: YAML/JSON โ Python dict with validation rules
- Environment Merging: System env + .env files + custom dicts
- Priority Chain: System > .env > Schema defaults
- Type Casting: Automatic conversion (str, int, float, bool)
- Validation: Required checks + type validation + error collection
Key Components
core.py: Main engine that orchestrates the entire processschema_loader.py: Parses YAML/JSON schema filesvalidation.py: Type casting and validation logicintegrations/: Framework-specific adapters (FastAPI, Django)cli.py: Command-line interface for common operations
๐ Comparison with Other Tools
| Feature | envsmith | python-dotenv | pydantic-settings | dynaconf | python-decouple |
|---|---|---|---|---|---|
| Schema Validation | โ YAML/JSON | โ None | โ Pydantic models | โ TOML/YAML | โ None |
| Type Casting | โ Automatic | โ Strings only | โ Pydantic types | โ Basic | โ Strings only |
| Framework Integration | โ FastAPI/Django | โ None | โ Pydantic ecosystem | โ Multiple | โ None |
| CLI Tools | โ Built-in | โ None | โ None | โ Rich CLI | โ None |
| Priority System | โ System > .env > defaults | โ .env only | โ Environment > .env | โ Multiple sources | โ .env > env |
| Error Handling | โ Comprehensive | โ Basic | โ Pydantic errors | โ Good | โ Basic |
| Production Ready | โ Logging, testing | โ ๏ธ Basic | โ Enterprise | โ Enterprise | โ ๏ธ Basic |
Why Choose envsmith?
vs python-dotenv
- python-dotenv: Only loads
.envfiles, no validation, no type casting - envsmith: Full validation, type safety, multiple sources, framework integration
vs pydantic-settings
- pydantic-settings: Requires Pydantic knowledge, more complex setup
- envsmith: Simple YAML/JSON schemas, easier to understand and maintain
vs dynaconf
- dynaconf: More complex, multiple config formats, overkill for simple apps
- envsmith: Focused on environment variables, simple and lightweight
vs python-decouple
- python-decouple: Basic .env loading, no validation, no type safety
- envsmith: Full validation suite, type casting, production features
Performance Characteristics
- Startup Time: Fast - single pass validation
- Memory Usage: Minimal - only stores validated variables
- Runtime Overhead: Zero - all processing happens at initialization
- Error Reporting: Comprehensive - all issues reported at once
Use Cases Where envsmith Excels
โ Web Applications: FastAPI, Django, Flask โ Microservices: Environment-based configuration โ Docker Containers: Environment variable validation โ CI/CD Pipelines: Configuration validation โ Team Development: Clear schema documentation โ Production Deployments: Early error detection
โจ Features
- Schema-First: Define your environment structure in YAML/JSON
- Multiple Sources: Load from
.env, system, or custom dicts - Type Safety: Automatic type casting and validation
- Framework Integration: FastAPI and Django support
- CLI Tools: Command-line interface for common tasks
- Secrets Management: Mock interface for external secret providers
- Production Ready: Logging, error handling, and comprehensive testing
๐ฆ Installation
pip install envsmith
With optional extras:
pip install envsmith[fastapi,django]
๐ฏ Quick Start
1. Create a Schema
Create a schema.yaml file:
DATABASE_URL:
type: str
required: true
description: "Database connection string"
SECRET_KEY:
type: str
required: true
description: "Application secret key"
DEBUG:
type: bool
default: false
description: "Debug mode"
PORT:
type: int
default: 8000
description: "Server port"
API_TIMEOUT:
type: float
default: 30.0
description: "API timeout in seconds"
2. Create Environment File
Create a .env file:
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
SECRET_KEY=your-super-secret-key-here
DEBUG=true
PORT=8080
API_TIMEOUT=45.0
3. Use in Python
from envsmith import EnvSmith
# Load with schema validation
settings = EnvSmith(schema_path="schema.yaml", env_file=".env")
# Access validated variables
print(settings["DATABASE_URL"]) # postgresql://user:pass@localhost:5432/mydb
print(settings["DEBUG"]) # True (bool)
print(settings["PORT"]) # 8080 (int)
print(settings["API_TIMEOUT"]) # 45.0 (float)
# Get with default fallback
print(settings.get("NONEXISTENT", "default_value"))
๐ ๏ธ CLI Usage
Initialize Project
Create .env and schema.yaml files:
python3 -m envsmith init
Validate Environment
Check if your .env file matches the schema:
python3 -m envsmith validate
Export Environment
Export validated variables in different formats:
# Export as JSON
python3 -m envsmith export --format json
# Export as YAML
python3 -m envsmith export --format yaml
๐ Framework Integrations
FastAPI Integration
from fastapi import FastAPI, Depends
from envsmith.integrations.fastapi import get_settings
app = FastAPI()
@app.get("/config")
def get_config(settings = Depends(get_settings)):
return {
"database_url": settings["DATABASE_URL"],
"debug": settings["DEBUG"],
"port": settings["PORT"]
}
@app.get("/health")
def health_check(settings = Depends(get_settings)):
return {
"status": "healthy",
"environment": settings.get("ENV", "development")
}
Django Integration
In your settings.py:
from envsmith.integrations.django import load_envsmith
# Load environment variables with schema validation
load_envsmith(schema_path="schema.yaml")
# Now you can use them directly
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': DATABASE_NAME,
'USER': DATABASE_USER,
'PASSWORD': DATABASE_PASSWORD,
'HOST': DATABASE_HOST,
'PORT': DATABASE_PORT,
}
}
SECRET_KEY = SECRET_KEY
DEBUG = DEBUG
ALLOWED_HOSTS = ALLOWED_HOSTS.split(',') if ALLOWED_HOSTS else []
๐ Secrets Management
For production environments, you can integrate with external secret providers:
from envsmith.secrets import SecretProvider
# Mock interface (replace with actual AWS, Vault, etc.)
secrets = SecretProvider()
# Get secret from external provider
api_key = secrets.get_secret("API_KEY")
# Fallback to local secret
fallback_key = secrets.get_local_secret("API_KEY")
๐ Schema Reference
Supported Types
- str: String values
- int: Integer values
- float: Floating-point values
- bool: Boolean values (accepts: true/false, yes/no, 1/0, on/off)
Schema Structure
VARIABLE_NAME:
type: str|int|float|bool
required: true|false
default: "default_value"
description: "Human-readable description"
Example Schema
# Database Configuration
DATABASE_URL:
type: str
required: true
description: "PostgreSQL connection string"
DATABASE_POOL_SIZE:
type: int
default: 10
description: "Database connection pool size"
# Application Settings
DEBUG:
type: bool
default: false
description: "Enable debug mode"
LOG_LEVEL:
type: str
default: "INFO"
description: "Logging level"
# API Configuration
API_TIMEOUT:
type: float
default: 30.0
description: "API request timeout in seconds"
MAX_REQUESTS:
type: int
default: 1000
description: "Maximum concurrent requests"
๐งช Testing
Run the test suite:
# Install test dependencies
pip install pytest pytest-cov
# Run tests with coverage
python3 -m pytest --cov=envsmith
# Run specific test file
python3 -m pytest tests/test_core.py
๐ Development
Project Structure
envsmith/
โโโ envsmith/ # Main package
โ โโโ __init__.py # Package initialization
โ โโโ core.py # Core loader and validation
โ โโโ cli.py # Command-line interface
โ โโโ validation.py # Schema validation logic
โ โโโ schema_loader.py # YAML/JSON schema loading
โ โโโ secrets.py # Secrets management
โ โโโ _types.py # Type definitions
โ โโโ integrations/ # Framework integrations
โ โโโ fastapi.py # FastAPI integration
โ โโโ django.py # Django integration
โโโ tests/ # Test suite
โโโ examples/ # Usage examples
โโโ docs/ # Documentation
Adding New Features
- Type Support: Add new types in
validation.py - Framework Integration: Create new integration modules
- CLI Commands: Extend
cli.pywith new subcommands - Secrets Providers: Implement actual secret provider interfaces
๐ Examples
Check the examples/ directory for complete working examples:
demo_fastapi.py- FastAPI application with envsmithdemo_django.py- Django settings with envsmithenv.example- Example environment file
๐ค Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Development Setup
# Clone the repository
git clone https://github.com/PeymanSohi/envsmith.git
cd envsmith
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in development mode
pip install -e ".[fastapi,django]"
# Install test dependencies
pip install pytest pytest-cov
# Run tests
python3 -m pytest
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Support
- Issues: GitHub Issues
- Documentation: README
- Examples: Check the
examples/directory
๐ Changelog
See CHANGELOG.md for a detailed history of changes and releases.
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 envsmith-0.1.0.tar.gz.
File metadata
- Download URL: envsmith-0.1.0.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7da6d8e50bde173156d4d55e4e83ceb5b3ff4a0f0c5e334021ea4421b7d6f108
|
|
| MD5 |
6e0127f9815a66889b4198c6f1b726df
|
|
| BLAKE2b-256 |
afdd9f7841e9b8268bc69d82b3d6e4eda5035e827000dc701edb5f28381e0f14
|
File details
Details for the file envsmith-0.1.0-py3-none-any.whl.
File metadata
- Download URL: envsmith-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
817ad2255819c5c27a935f215391df3182c0a11f06185b108da6b20c19452121
|
|
| MD5 |
609665f2d46278e7ae5fcfa7aa6c942a
|
|
| BLAKE2b-256 |
1588197e895ca84cd632a8df67320cc423d750abde9eb3fafc2d6bbcc93a5c9a
|