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.