Configuration Management
Gmail Cleanup โ Practical Scripting
Course 1 ยท Chapter 2 ยท Configuration Management
๐ง Configuration Management
Configuration should never be hardcoded! This chapter teaches you how to load settings from environment variables using
.env files, validate them, and handle errors gracefully. This is a critical skill for secure, portable applications.
๐ Why Configuration Management Matters
Consider this dangerous code:
# โ BAD: Hardcoded credentials! GMAIL_USER = "my-email@gmail.com" API_TIMEOUT = 10
Problems:
- Email is visible in the code
- Can't change settings without editing the code
- Different values needed for development vs. production
- Easy to accidentally commit secrets to Git
The solution: .env files + load_dotenv()
๐ The .env Pattern
Create a config.py module:
import os from pathlib import Path from dotenv import load_dotenv # Load .env file from same directory as this script ENV_FILE = Path(__file__).parent / ".env" load_dotenv(ENV_FILE) class Config: """Application configuration.""" def __init__(self): # Gmail settings self.gmail_user = os.environ.get('GMAIL_USER') self.api_timeout = int(os.environ.get('API_REQUEST_TIMEOUT', '10')) self.max_results = int(os.environ.get('MAX_RESULTS', '100')) # Cleanup settings self.days_old = int(os.environ.get('DELETE_OLDER_THAN_DAYS', '365')) self.min_attachment_mb = int(os.environ.get('MIN_ATTACHMENT_SIZE_MB', '10')) def validate(self) -> bool: """Validate required configuration.""" if not self.gmail_user: print("โ Missing GMAIL_USER in .env") return False if '@' not in self.gmail_user: print("โ GMAIL_USER must be a valid email") return False return True
๐ Using Configuration in Your Script
from config import Config def main(): # Load configuration config = Config() # Validate it if not config.validate(): return False # Use it print(f"Cleaning emails from: {config.gmail_user}") print(f"Deleting emails older than: {config.days_old} days") return True if __name__ == "__main__": main()
โ ๏ธ Common Configuration Errors
Error 1: .env file not found
Cause: File is in wrong directory or has wrong name
Fix: Make sure .env is in the same folder as config.py
Error 2: Variables are None
Cause: Variable name in code doesn't match .env
Fix: Case matters! Use exact same names
Error 3: Type conversion errors
Cause: Trying to convert non-numeric value to int
Fix: Validate that .env values are correct type
๐ป Coding Challenges
Challenge 1: Create config.py
Build a Config class that:
- Loads .env file from current directory
- Reads GMAIL_USER, API_REQUEST_TIMEOUT, MAX_RESULTS
- Uses defaults for timeout (10) and max_results (100)
- Returns all values
Goal: Create reusable configuration module.
Challenge 2: Configuration Validation
Extend Config.validate() to check:
- GMAIL_USER is not empty
- GMAIL_USER contains @ symbol (valid email)
- API_REQUEST_TIMEOUT is positive number
- Return True if all valid, False otherwise
Goal: Practice data validation.
Challenge 3: Error Handling & Logging
Enhance config loading with error handling:
- Catch missing .env file gracefully
- Handle type conversion errors
- Print helpful error messages (what's wrong, how to fix)
- Test with missing/invalid values
Goal: Build robust configuration system.