Skip to content

Deepak-coder80/env-factory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

env_factory

A flexible Python package for retrieving environment variables from multiple sources including local environment and AWS Secrets Manager.

Features

  • Multiple Sources: Support for local environment variables and AWS Secrets Manager
  • Type Safety: Full type hints and robust error handling
  • Flexible Usage: Factory pattern and convenience functions for easy integration
  • Case-Insensitive Matching: Fallback to case-insensitive key matching for AWS secrets
  • Comprehensive Logging: Debug and warning logs for troubleshooting
  • Error Recovery: Continues processing even if some keys are missing

Installation

pip install env-factory

Loading .env files

To automatically load your .env file, add this to the top of your main script:

from dotenv import load_dotenv
load_dotenv()  # This loads variables from .env file

# Now you can use env_factory
from env_factory import get_env_variables

Quick Start

Step 1: Create your .env file (MANDATORY)

Create a .env file in your project root directory:

# .env file - Place in your project root
API_KEY=my-secret-api-key
DATABASE_URL=postgresql://localhost:5432/myapp
DEBUG=true

# For AWS functionality (REQUIRED)
AWS_ACCOUNT_ID=123456789012

Step 2: Simple Examples

Example 1: Get Local Environment Variables

from env_factory import get_env_variables

# This will read from your .env file
config = get_env_variables(['API_KEY', 'DATABASE_URL'])
print(config)
# Output: {'API_KEY': 'my-secret-api-key', 'DATABASE_URL': 'postgresql://localhost:5432/myapp'}

# Check if variables exist
api_key = config.get('API_KEY')
if api_key:
    print(f"API Key found: {api_key}")
else:
    print("API Key not found!")

Example 2: Simple AWS Secrets Manager Usage

from env_factory import get_env_variables

# Make sure AWS_ACCOUNT_ID is in your .env file!
secrets = get_env_variables(
    keys=['DB_PASSWORD', 'JWT_SECRET'],
    source='aws',
    secret_name='my-app-secrets',
    region='us-east-1',
    role_name='my-app-role'
)

print(f"Database password: {secrets.get('DB_PASSWORD')}")

Example 3: Real-World Web App Setup

from env_factory import get_env_variables

# Load all your app configuration at startup
app_config = get_env_variables([
    'API_KEY',
    'DATABASE_URL',
    'DEBUG',
    'PORT'
])

# Use the configuration
api_key = app_config['API_KEY']
database_url = app_config['DATABASE_URL']
debug_mode = app_config.get('DEBUG', 'false').lower() == 'true'
port = int(app_config.get('PORT', '8000'))

print(f"Starting app on port {port}, debug mode: {debug_mode}")

Simple Examples

Complete Working Example

Here's a complete example showing how to use the package:

# main.py
from dotenv import load_dotenv
from env_factory import get_env_variables

# Step 1: Load .env file (MANDATORY)
load_dotenv()

# Step 2: Get your environment variables
config = get_env_variables(['API_KEY', 'DATABASE_URL', 'DEBUG'])

# Step 3: Use the configuration
api_key = config.get('API_KEY')
if not api_key:
    raise ValueError("API_KEY is required but not found in .env file")

database_url = config.get('DATABASE_URL', 'sqlite:///default.db')
debug = config.get('DEBUG', 'false').lower() == 'true'

print(f"API Key: {api_key}")
print(f"Database: {database_url}")
print(f"Debug mode: {debug}")

Your .env file should look like:

# .env
API_KEY=sk-1234567890abcdef
DATABASE_URL=postgresql://user:pass@localhost/mydb
DEBUG=true

AWS Example with .env

# aws_example.py
from dotenv import load_dotenv
from env_factory import get_env_variables

# Load .env file (contains AWS_ACCOUNT_ID)
load_dotenv()

try:
    # Get secrets from AWS
    secrets = get_env_variables(
        keys=['DB_PASSWORD', 'JWT_SECRET'],
        source='aws',
        secret_name='production-secrets',
        region='us-east-1',
        role_name='app-secrets-role'
    )
    
    print("âś… Successfully retrieved AWS secrets!")
    print(f"DB Password exists: {'DB_PASSWORD' in secrets}")
    
except Exception as e:
    print(f"❌ Error: {e}")

Your .env file must include:

# .env - MANDATORY for AWS
AWS_ACCOUNT_ID=123456789012

Error Handling Example

from dotenv import load_dotenv
from env_factory import get_env_variables, ConfigurationError

load_dotenv()

try:
    config = get_env_variables(['REQUIRED_API_KEY'])
    
    api_key = config.get('REQUIRED_API_KEY')
    if not api_key:
        print("⚠️  Warning: REQUIRED_API_KEY not found in .env file")
        print("Please add it to your .env file: REQUIRED_API_KEY=your-key-here")
    else:
        print("âś… API key loaded successfully!")
        
except ConfigurationError as e:
    print(f"❌ Configuration error: {e}")
``` with Classes

```python
from env_factory import LocalEnvRetrieval, AWSEnvRetrieval

# Local environment retrieval
local_retriever = LocalEnvRetrieval()
local_vars = local_retriever.get_env_variables(['API_KEY', 'DEBUG_MODE'])

# AWS Secrets Manager retrieval
aws_retriever = AWSEnvRetrieval(
    secret_name='production-secrets',
    region='us-west-2',
    role_name='app-secrets-role'
)
aws_vars = aws_retriever.get_env_variables(['DB_PASSWORD', 'JWT_SECRET'])

Using Factory Pattern

from env_factory import EnvFactory

# Create retrievers using factory
local_retriever = EnvFactory.create_local_retriever()
aws_retriever = EnvFactory.create_aws_retriever(
    secret_name='my-secrets',
    region='eu-west-1', 
    role_name='secrets-access-role'
)

# Use the retrievers
config = local_retriever.get_env_variables(['PORT', 'HOST'])
secrets = aws_retriever.get_env_variables(['API_TOKEN', 'WEBHOOK_SECRET'])

Configuration

Environment Variables Setup (.env file)

IMPORTANT: You must store your environment variables in a .env file in your project root. This is mandatory for the package to work properly.

For Local Development

Create a .env file in your project root:

# .env file
API_KEY=your-local-api-key
DATABASE_URL=postgresql://localhost:5432/mydb
DEBUG=true
PORT=8000

For AWS Secrets Manager

MANDATORY: Your .env file must include the AWS Account ID:

# .env file - REQUIRED for AWS functionality
AWS_ACCOUNT_ID=123456789012
ENVIRONMENT=production

Additional AWS Requirements

Before using AWS functionality, ensure you have:

  1. AWS Account ID in .env: The AWS_ACCOUNT_ID must be set in your .env file (mandatory)
  2. AWS Credentials: Configure AWS credentials (via AWS CLI, IAM roles, or environment variables)
  3. IAM Permissions: Ensure your IAM role has access to the specified secrets

Required IAM permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "sts:AssumeRole"
            ],
            "Resource": "*"
        }
    ]
}

Advanced Usage

Error Handling

from env_factory import get_env_variables, ConfigurationError, SecretRetrievalError

try:
    variables = get_env_variables(
        keys=['API_KEY', 'SECRET_TOKEN'],
        source='aws',
        secret_name='app-secrets',
        region='us-east-1',
        role_name='secrets-role'
    )
except ConfigurationError as e:
    print(f"Configuration error: {e}")
except SecretRetrievalError as e:
    print(f"Failed to retrieve secrets: {e}")

Custom Implementation

from env_factory import EnvRetrieval
from typing import Dict, List, Optional

class CustomEnvRetrieval(EnvRetrieval):
    """Custom environment retrieval implementation"""
    
    def __init__(self, config_file: str):
        self.config_file = config_file
    
    def get_env_variables(self, keys: List[str]) -> Dict[str, Optional[str]]:
        # Your custom implementation here
        pass

Logging Configuration

import logging

# Configure logging to see debug information
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('env_factory')

# Now you'll see debug logs when retrieving variables
variables = get_env_variables(['API_KEY'], source='local')

API Reference

Classes

EnvRetrieval (Abstract Base Class)

Base class for all environment retrieval implementations.

Methods:

  • get_env_variables(keys: List[str]) -> Dict[str, Optional[str]]: Abstract method to retrieve environment variables

LocalEnvRetrieval

Retrieves environment variables from the local system environment.

Methods:

  • get_env_variables(keys: List[str]) -> Dict[str, Optional[str]]: Get variables from local environment

AWSEnvRetrieval

Retrieves environment variables from AWS Secrets Manager.

Constructor:

  • __init__(secret_name: str, region: str, role_name: str)

Methods:

  • get_env_variables(keys: List[str]) -> Dict[str, Optional[str]]: Get variables from AWS Secrets Manager

EnvFactory

Factory class for creating environment retrieval instances.

Static Methods:

  • create_local_retriever() -> LocalEnvRetrieval: Create local retriever
  • create_aws_retriever(secret_name: str, region: str, role_name: str) -> AWSEnvRetrieval: Create AWS retriever

Functions

get_env_variables()

Convenience function for retrieving environment variables.

Parameters:

  • keys: List[str] - List of environment variable names to retrieve
  • source: str = "local" - Environment source ('local' or 'aws')
  • **kwargs - Additional arguments for AWS (secret_name, region, role_name)

Returns:

  • Dict[str, Optional[str]] - Dictionary mapping keys to their values

Exceptions

EnvFactoryError

Base exception for the env_factory package.

ConfigurationError

Raised when configuration parameters are invalid.

SecretRetrievalError

Raised when secret retrieval from AWS fails.

Examples

Web Application Configuration

from env_factory import get_env_variables

# Load configuration for a web application
config = get_env_variables([
    'DATABASE_URL',
    'SECRET_KEY',
    'DEBUG',
    'PORT',
    'REDIS_URL'
])

# Handle missing variables
database_url = config.get('DATABASE_URL')
if not database_url:
    raise ValueError("DATABASE_URL is required")

debug_mode = config.get('DEBUG', 'false').lower() == 'true'
port = int(config.get('PORT', '8000'))

Multi-Environment Setup

import os
from env_factory import get_env_variables

# Determine environment
environment = os.getenv('ENVIRONMENT', 'development')

if environment == 'production':
    # Use AWS Secrets Manager in production
    config = get_env_variables(
        keys=['DATABASE_PASSWORD', 'API_KEY', 'JWT_SECRET'],
        source='aws',
        secret_name='prod-app-secrets',
        region='us-east-1',
        role_name='prod-secrets-role'
    )
else:
    # Use local environment variables in development
    config = get_env_variables([
        'DATABASE_PASSWORD',
        'API_KEY', 
        'JWT_SECRET'
    ])

print(f"Loaded {len([v for v in config.values() if v is not None])} variables")

Batch Processing with Multiple Sources

from env_factory import EnvFactory

# Create retrievers
local_retriever = EnvFactory.create_local_retriever()
aws_retriever = EnvFactory.create_aws_retriever(
    secret_name='shared-secrets',
    region='us-west-2',
    role_name='batch-processing-role'
)

# Get different types of configuration
app_config = local_retriever.get_env_variables([
    'LOG_LEVEL',
    'BATCH_SIZE', 
    'WORKER_COUNT'
])

sensitive_config = aws_retriever.get_env_variables([
    'DATABASE_PASSWORD',
    'API_TOKEN',
    'ENCRYPTION_KEY'
])

# Merge configurations
full_config = {**app_config, **sensitive_config}

Best Practices

  1. Always use .env files: Store all environment variables in a .env file in your project root (mandatory)
  2. Load .env at startup: Use python-dotenv to load your .env file before using env_factory
  3. AWS Account ID: Always include AWS_ACCOUNT_ID in your .env file when using AWS functionality
  4. Environment-Specific Sources: Use local environment variables for development and AWS Secrets Manager for production
  5. Error Handling: Always handle ConfigurationError and SecretRetrievalError exceptions
  6. Key Validation: Check if required environment variables are present and not None
  7. Security: Never commit your .env file to version control (add it to .gitignore)

.gitignore Example

# .gitignore
.env
.env.local
.env.production
*.env

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

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

Changelog

v1.0.0

  • Initial release
  • Support for local environment variables
  • Support for AWS Secrets Manager
  • Factory pattern implementation
  • Comprehensive error handling
  • Type hints and documentation

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages