CONFIGURATION FILE READER - Reading app configuration files
Python
#!/usr/bin/env python3
"""
CONFIGURATION FILE READER - Reading app configuration files
Demonstrates parsing INI-style and key=value config files
"""
import os
import tempfile
print("=" * 60)
print("CONFIGURATION FILE READER - App Config Parsing")
print("=" * 60)
temp_dir = tempfile.gettempdir()
# Example 1: Simple key=value config
print("\n1. Simple Key=Value Configuration")
print("-" * 40)
config_file = os.path.join(temp_dir, "app.conf")
with open(config_file, 'w') as f:
f.write("host=localhost\n")
f.write("port=8080\n")
f.write("debug=true\n")
f.write("max_connections=100\n")
f.write("timeout=30\n")
print(f"Created: {config_file}\n")
config = {}
with open(config_file, 'r') as f:
for line in f:
line = line.strip()
if '=' in line and not line.startswith('#'):
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
print("Loaded configuration:")
for key, value in config.items():
print(f" {key:20s}: {value}")
# Example 2: Config with comments and blank lines
print("\n2. Config with Comments and Blank Lines")
print("-" * 40)
config2_file = os.path.join(temp_dir, "app2.conf")
with open(config2_file, 'w') as f:
f.write("# Database Configuration\n")
f.write("db_host=localhost\n")
f.write("db_port=5432\n")
f.write("\n")
f.write("# Server Settings\n")
f.write("server_port=8080\n")
f.write("server_host=0.0.0.0 # Listen on all interfaces\n")
config2 = {}
with open(config2_file, 'r') as f:
for line in f:
line = line.strip()
# Skip blank lines and comments
if not line or line.startswith('#'):
continue
# Remove inline comments
if '#' in line:
line = line.split('#')[0].strip()
if '=' in line:
key, value = line.split('=', 1)
config2[key.strip()] = value.strip()
print("Loaded configuration (ignoring comments):")
for key, value in config2.items():
print(f" {key:20s}: {value}")
# Example 3: INI-style config with sections
print("\n3. INI-Style Config with Sections")
print("-" * 40)
ini_file = os.path.join(temp_dir, "config.ini")
with open(ini_file, 'w') as f:
f.write("[database]\n")
f.write("host=localhost\n")
f.write("port=5432\n")
f.write("name=mydb\n")
f.write("\n")
f.write("[server]\n")
f.write("host=0.0.0.0\n")
f.write("port=8080\n")
f.write("debug=true\n")
f.write("\n")
f.write("[logging]\n")
f.write("level=INFO\n")
f.write("file=/var/log/app.log\n")
ini_config = {}
current_section = None
with open(ini_file, 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
# Check for section header
if line.startswith('[') and line.endswith(']'):
current_section = line[1:-1]
ini_config[current_section] = {}
elif '=' in line and current_section:
key, value = line.split('=', 1)
ini_config[current_section][key.strip()] = value.strip()
print("Loaded INI configuration:")
for section, settings in ini_config.items():
print(f"\n[{section}]")
for key, value in settings.items():
print(f" {key:15s}: {value}")
# Example 4: Type conversion
print("\n4. Configuration with Type Conversion")
print("-" * 40)
typed_config_file = os.path.join(temp_dir, "typed.conf")
with open(typed_config_file, 'w') as f:
f.write("port=8080\n")
f.write("debug=true\n")
f.write("timeout=30.5\n")
f.write("app_name=MyApp\n")
f.write("max_retries=3\n")
def parse_value(value):
"""Convert string value to appropriate type"""
# Try boolean
if value.lower() in ('true', 'yes', 'on'):
return True
if value.lower() in ('false', 'no', 'off'):
return False
# Try integer
try:
return int(value)
except ValueError:
pass
# Try float
try:
return float(value)
except ValueError:
pass
# Return as string
return value
typed_config = {}
with open(typed_config_file, 'r') as f:
for line in f:
line = line.strip()
if '=' in line:
key, value = line.split('=', 1)
typed_config[key.strip()] = parse_value(value.strip())
print("Configuration with type conversion:")
for key, value in typed_config.items():
print(f" {key:20s}: {value:15} (type: {type(value).__name__})")
# Example 5: Environment-specific config
print("\n5. Environment-Specific Configuration")
print("-" * 40)
dev_config = os.path.join(temp_dir, "config.dev")
prod_config = os.path.join(temp_dir, "config.prod")
with open(dev_config, 'w') as f:
f.write("environment=development\n")
f.write("debug=true\n")
f.write("host=localhost\n")
with open(prod_config, 'w') as f:
f.write("environment=production\n")
f.write("debug=false\n")
f.write("host=api.example.com\n")
def load_config(filename):
config = {}
with open(filename, 'r') as f:
for line in f:
line = line.strip()
if '=' in line:
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
return config
dev = load_config(dev_config)
prod = load_config(prod_config)
print("Development config:")
for key, value in dev.items():
print(f" {key:20s}: {value}")
print("\nProduction config:")
for key, value in prod.items():
print(f" {key:20s}: {value}")
# Example 6: Config validation
print("\n6. Configuration Validation")
print("-" * 40)
required_keys = ['host', 'port', 'timeout']
def validate_config(config, required):
missing = []
for key in required:
if key not in config:
missing.append(key)
return missing
missing = validate_config(config, required_keys)
if missing:
print(f" Missing required keys: {missing}")
else:
print(" ✓ All required keys present")
# Example 7: Writing config files
print("\n7. Writing Configuration Files")
print("-" * 40)
new_config_file = os.path.join(temp_dir, "generated.conf")
settings = {
'app_name': 'MyApplication',
'version': '1.0.0',
'port': 8080,
'debug': True,
'max_connections': 100
}
with open(new_config_file, 'w') as f:
f.write("# Auto-generated configuration\n")
f.write(f"# Generated on {os.path.basename(__file__)}\n\n")
for key, value in settings.items():
f.write(f"{key}={value}\n")
print(f"Generated: {new_config_file}")
with open(new_config_file, 'r') as f:
print("Content:")
print(f.read())
# Cleanup
for f in [config_file, config2_file, ini_file, typed_config_file,
dev_config, prod_config, new_config_file]:
if os.path.exists(f):
os.remove(f)
print("\n" + "=" * 60)
print("Key Points:")
print(" - Parse key=value pairs")
print(" - Handle comments and blank lines")
print(" - Support INI-style sections")
print(" - Convert types (bool, int, float)")
print(" - Validate required settings")
print("=" * 60)