-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
95 lines (77 loc) · 3.32 KB
/
config.py
File metadata and controls
95 lines (77 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""
Configuration module for the Stock Analyzer application.
This module handles loading and validating environment variables for secure configuration
management. It provides type-safe access to configuration values and ensures all required
settings are present before the application starts.
"""
import logging
import os
from pathlib import Path
from typing import Dict, Union, cast
from dotenv import load_dotenv
# Configure logging
logger = logging.getLogger(__name__)
ConfigDict = Dict[str, Union[str, int, float, bool]]
def load_config() -> ConfigDict:
"""
Load and validate application configuration from environment variables.
This function:
1. Loads environment variables from .env file if present
2. Validates all required configuration values
3. Converts and validates numeric values
4. Provides default values for optional settings
Returns:
Dict[str, Union[str, int, float, bool]]: Configuration dictionary containing:
- SECRET_KEY (str): Flask secret key for session management
- FLASK_ENV (str): Flask environment (development/production)
- FLASK_HOST (str): Host address to bind to
- FLASK_PORT (int): Port number to listen on
- CACHE_TIMEOUT (int): Cache timeout in seconds
Raises:
ValueError: If any required configuration values are missing or invalid.
TypeError: If numeric values cannot be converted properly.
"""
# Load environment variables from .env file
env_path = Path(".env")
if env_path.exists():
load_dotenv(env_path)
# Required configuration keys and their descriptions
required_configs: Dict[str, str] = {
"SECRET_KEY": "Flask secret key for session management",
"FLASK_ENV": "Flask environment (development/production)",
}
# Optional configuration keys with default values
default_configs: Dict[str, Union[str, int]] = {
"FLASK_HOST": "0.0.0.0",
"FLASK_PORT": 8000,
# Cache timeout in seconds
"CACHE_TIMEOUT": 60,
}
config: ConfigDict = {}
missing_keys: list[str] = []
# Check required configurations
for key, description in required_configs.items():
value = os.getenv(key)
if not value:
missing_keys.append(f"{key} ({description})")
config[key] = value if value else ""
# Load optional configurations with defaults
for key, default in default_configs.items():
value = os.getenv(key)
config[key] = value if value is not None else default
# Convert numeric values
try:
config["FLASK_PORT"] = int(cast(Union[str, int], config["FLASK_PORT"]))
config["CACHE_TIMEOUT"] = int(cast(Union[str, int], config["CACHE_TIMEOUT"]))
except ValueError as e:
logger.error(f"Invalid numeric configuration value: {str(e)}")
raise ValueError(f"Invalid numeric configuration value: {str(e)}")
# Validate FLASK_ENV value
if config["FLASK_ENV"] not in ["development", "production"]:
raise ValueError("FLASK_ENV must be either 'development' or 'production'")
# If any required configurations are missing, raise an error
if missing_keys:
error_msg = "Missing required configuration values:\n" + "\n".join(missing_keys)
logger.error(error_msg)
raise ValueError(error_msg)
return config