// Environment configuration and secrets management skill using UV for Python projects. Handles .env files, environment variables, secrets encryption, multi-environment setups, and secure configuration patterns. Use when setting up project environments, managing API keys, or implementing configuration best practices.
| name | env-config |
| description | Environment configuration and secrets management skill using UV for Python projects. Handles .env files, environment variables, secrets encryption, multi-environment setups, and secure configuration patterns. Use when setting up project environments, managing API keys, or implementing configuration best practices. |
This skill provides comprehensive guidance for managing environment configurations, secrets, and environment variables in Python projects using UV (the modern Python package and project manager). It covers secure configuration patterns, multi-environment setups, .env file management, and secrets handling with encryption support.
Environment configuration is critical for separating configuration from code (12-factor app principles), managing secrets securely across environments, preventing credential leaks, and supporting team collaboration.
Use this skill when you need to:
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or with pip
pip install uv
# Verify installation
uv --version
# Create new project
uv init my-project
cd my-project
# Create virtual environment
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Add dependencies
uv add python-dotenv cryptography pydantic
# Add dev dependencies
uv add --dev pytest pytest-env black ruff
1. Create Project Structure
# Initialize UV project
uv init your-project-name
cd your-project-name
uv venv
source .venv/bin/activate
2. Install Configuration Dependencies
uv add python-dotenv # For .env file loading
uv add cryptography # For secrets encryption (optional)
uv add pydantic # For config validation (optional)
uv add --dev pytest pytest-env
3. Create Configuration Files
Essential files to create:
.env.template - Template showing required variables (commit this).env - Actual secrets (add to .gitignore).env.development - Development-specific config.env.production - Production-specific configconfig.py - Configuration loading module4. Update .gitignore
# Add to .gitignore
cat >> .gitignore << 'EOF'
# Environment files
.env
.env.local
.env.*.local
secrets.json
# UV
.venv/
__pycache__/
*.pyc
.pytest_cache/
.ruff_cache/
EOF
1. Create .env.template
# .env.template - Commit this file
# Copy to .env and fill in actual values
# Application Settings
APP_NAME=MyApp
APP_ENV=development
DEBUG=true
LOG_LEVEL=INFO
# Database Configuration
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DATABASE_POOL_SIZE=5
# API Keys (Replace with actual keys)
ANTHROPIC_API_KEY=sk-ant-api03-xxx
OPENAI_API_KEY=sk-xxx
OPENROUTER_API_KEY=sk-or-v1-xxx
# Security
SECRET_KEY=generate-random-secret-key-here
JWT_SECRET=another-random-secret
# Feature Flags
ENABLE_ANALYTICS=false
ENABLE_CACHING=true
2. Create Config Loading Module
Create config.py - see references/api-reference.md for complete implementation:
import os
from pathlib import Path
from dotenv import load_dotenv
class ConfigError(Exception):
"""Raised when required configuration is missing."""
pass
class Config:
"""Application configuration from environment variables."""
def __init__(self, env: str = None):
self.env = env or os.getenv('APP_ENV', 'development')
self._load_env_file()
self._validate_required()
def _load_env_file(self):
"""Load appropriate .env file based on environment."""
env_file = Path(f'.env.{self.env}')
if env_file.exists():
load_dotenv(env_file, override=True)
if Path('.env').exists():
load_dotenv('.env', override=False)
@property
def app_name(self) -> str:
return os.getenv('APP_NAME', 'MyApp')
@property
def debug(self) -> bool:
return os.getenv('DEBUG', 'false').lower() in ('true', '1', 'yes')
# Add more properties as needed...
# Global config instance
config = Config()
For complete Config class with all properties and validation, see references/api-reference.md.
3. Use Config in Application
from config import config
def main():
print(f"Starting {config.app_name} in {config.app_env} mode")
if config.anthropic_api_key:
# Use API key
print("โ API key loaded")
1. Create Environment-Specific Files
.env.development:
APP_ENV=development
DEBUG=true
LOG_LEVEL=DEBUG
DATABASE_URL=postgresql://localhost:5432/myapp_dev
.env.production:
APP_ENV=production
DEBUG=false
LOG_LEVEL=WARNING
DATABASE_URL=postgresql://prod-host:5432/myapp_prod
SECRET_KEY=super-secure-random-key
2. Switch Between Environments
# Development (default)
uv run python main.py
# Production
export APP_ENV=production
uv run python main.py
1. Using JSON Secrets (Alternative Pattern)
Create secrets_template.json:
{
"anthropic_api_key": "sk-ant-api03-xxx",
"openai_api_key": "sk-xxx",
"database_password": "your-password-here",
"comment": "Copy to secrets.json and fill in real values"
}
2. Load JSON Secrets
See references/api-reference.md for complete implementation:
import json
from pathlib import Path
def load_secrets(secrets_file: str = 'secrets.json') -> dict:
"""Load secrets from JSON with fallback to env vars."""
if Path(secrets_file).exists():
return json.load(open(secrets_file))
# Fallback to environment variables
return {
'anthropic_api_key': os.getenv('ANTHROPIC_API_KEY', '')
}
3. Encrypted Secrets
For encryption utilities and advanced secrets management, see:
references/advanced-topics.md - Encryption, rotation, auditingscripts/env_helper.py - Encryption/decryption utilitiesfrom pydantic import BaseSettings, Field, validator
class Settings(BaseSettings):
app_name: str = Field(default='MyApp', env='APP_NAME')
app_env: str = Field(default='development', env='APP_ENV')
database_url: str = Field(..., env='DATABASE_URL') # Required
@validator('app_env')
def validate_env(cls, v):
allowed = ['development', 'staging', 'production']
if v not in allowed:
raise ValueError(f'app_env must be one of {allowed}')
return v
class Config:
env_file = '.env'
settings = Settings()
For complete Pydantic configuration examples, see references/api-reference.md.
Always add to .gitignore:
.env
.env.local
.env.*.local
secrets.json
.env.production
.venv/
Implement regular API key rotation:
def rotate_api_key(old_key: str, new_key: str):
"""Rotate API key gracefully with backup."""
# Implementation in references/advanced-topics.md
Regular security audits:
def audit_environment():
"""Check for security issues in environment variables."""
# Implementation in references/advanced-topics.md
For complete security implementations, see references/advanced-topics.md.
# conftest.py
import pytest
import os
@pytest.fixture
def test_env():
"""Set up test environment variables."""
original = os.environ.copy()
os.environ['APP_ENV'] = 'testing'
os.environ['DEBUG'] = 'true'
yield
os.environ.clear()
os.environ.update(original)
@pytest.fixture
def config(test_env):
from config import Config
return Config(env='testing')
def test_config_loading(config):
assert config.app_env == 'testing'
assert config.debug is True
def test_missing_required_var():
from config import ConfigError
with pytest.raises(ConfigError):
Config() # Missing required vars
For comprehensive testing guide, see references/testing-guide.md.
# Dependency management
uv sync # Install all dependencies
uv add requests # Add dependency
uv add --dev pytest # Add dev dependency
uv remove requests # Remove dependency
# Environment management
uv venv # Create virtual environment
uv lock --upgrade # Update dependencies
# Running scripts
uv run python main.py # Run with UV environment
uv run pytest # Run tests
# Compatibility
uv pip compile pyproject.toml -o requirements.txt
This skill provides utility scripts in scripts/:
env_helper.py - Core utilities for env management
Usage:
# Validate .env file
python scripts/env_helper.py validate .env
# Encrypt secrets
python scripts/env_helper.py encrypt secrets.json secrets.encrypted
# Compare environments
python scripts/env_helper.py compare .env.development .env.production
curl -LsSf https://astral.sh/uv/install.sh | shuv init project-nameuv venvuv add python-dotenv.env.template from examples.env and fill in secrets.env to .gitignoreconfig.py moduleUse consistent naming:
APP_* - Application settingsDATABASE_* - Database configuration*_API_KEY - API keys and tokens*_SECRET - Secret keysENABLE_* - Feature flags*_URL - Service endpoints.env in .gitignorereferences/api-reference.md - Complete Config class implementation, Pydantic validation, JSON secrets loadingreferences/advanced-topics.md - Encryption, secret rotation, auditing, multi-tenant config, cloud integrationreferences/testing-guide.md - pytest setup, mocking, validation testing, CI/CD examplesreferences/troubleshooting.md - Common issues, environment-specific problems, debugging techniques.env.example - Comprehensive .env templatepyproject.toml - UV project configurationsecrets_template.json - JSON secrets templateFor common issues and solutions, see references/troubleshooting.md:
Quick debug:
from dotenv import load_dotenv
load_dotenv(verbose=True) # Shows loading process