106 lines
6.7 KiB
Python
106 lines
6.7 KiB
Python
"""
|
|
config.py — Central configuration loader for NAS Drive Price Tracker.
|
|
|
|
Import this module at the top of any entry-point (api/server.py,
|
|
scraper/runner.py) to load the .env file before anything else reads
|
|
os.getenv(). Every other module continues using os.getenv() unchanged.
|
|
|
|
.env file location (searched in order):
|
|
1. Path in NAS_TRACKER_ENV environment variable
|
|
2. <project_root>/.env (default)
|
|
3. Already-set environment variables are never overwritten, so
|
|
real env vars always take precedence over .env values.
|
|
|
|
All recognised variables and their defaults are documented below.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
# ── Locate the project root ───────────────────────────────────────────────
|
|
# This file lives at <root>/config.py, so its parent IS the root.
|
|
ROOT = Path(__file__).parent.resolve()
|
|
|
|
|
|
def load(env_path: str | Path | None = None, override: bool = False) -> Path | None:
|
|
"""
|
|
Load a .env file using python-dotenv.
|
|
|
|
Parameters
|
|
----------
|
|
env_path : path to a specific .env file; auto-detected if None.
|
|
override : if True, .env values overwrite existing env vars.
|
|
Default False — real env vars always win.
|
|
|
|
Returns the resolved path that was loaded, or None if no file found.
|
|
"""
|
|
try:
|
|
from dotenv import load_dotenv
|
|
except ImportError:
|
|
print(
|
|
"[config] python-dotenv is not installed. "
|
|
"Run: pip install python-dotenv\n"
|
|
"[config] Falling back to environment variables only.",
|
|
file=sys.stderr,
|
|
)
|
|
return None
|
|
|
|
# Resolve path
|
|
if env_path is not None:
|
|
candidate = Path(env_path).resolve()
|
|
elif os.getenv("NAS_TRACKER_ENV"):
|
|
candidate = Path(os.getenv("NAS_TRACKER_ENV")).resolve()
|
|
else:
|
|
candidate = ROOT / ".env"
|
|
|
|
if not candidate.is_file():
|
|
print(
|
|
f"[config] No .env file found at {candidate}. "
|
|
"Using environment variables only.",
|
|
file=sys.stderr,
|
|
)
|
|
return None
|
|
|
|
loaded = load_dotenv(candidate, override=override)
|
|
if loaded:
|
|
print(f"[config] Loaded environment from {candidate}", file=sys.stderr)
|
|
return candidate
|
|
|
|
|
|
# ── Auto-load when this module is imported ───────────────────────────────
|
|
# Calling load() here means `import config` at the top of any entry-point
|
|
# is all that's needed — no extra call required.
|
|
load()
|
|
|
|
|
|
# ── Variable reference (for documentation; not enforced here) ────────────
|
|
#
|
|
# ┌─────────────────────────┬─────────────────────────┬───────────────────────────────────────────┐
|
|
# │ Variable │ Default │ Description │
|
|
# ├─────────────────────────┼─────────────────────────┼───────────────────────────────────────────┤
|
|
# │ SMTP_HOST │ localhost │ SMTP server hostname │
|
|
# │ SMTP_PORT │ 587 │ SMTP port (587=STARTTLS, 465=SSL, 25=none)│
|
|
# │ SMTP_USER │ (none) │ SMTP login username │
|
|
# │ SMTP_PASS │ (none) │ SMTP login password / app-password │
|
|
# │ SMTP_FROM_NAME │ NAS Drive Tracker │ "From" display name in emails │
|
|
# │ SMTP_FROM_EMAIL │ SMTP_USER or noreply@.. │ "From" address in emails │
|
|
# │ APP_BASE_URL │ http://localhost:5000 │ Base URL for links in emails │
|
|
# ├─────────────────────────┼─────────────────────────┼───────────────────────────────────────────┤
|
|
# │ PORT │ 5000 │ API server port │
|
|
# │ FLASK_ENV │ (none) │ Set to "development" for debug mode │
|
|
# │ FLASK_SECRET │ random │ Flask session secret (set in production!) │
|
|
# ├─────────────────────────┼─────────────────────────┼───────────────────────────────────────────┤
|
|
# │ SCRAPE_INTERVAL_HOURS │ 6 │ Hours between scheduled scrape runs │
|
|
# │ SCRAPE_WORKERS │ 3 │ Parallel scraper threads per run │
|
|
# ├─────────────────────────┼─────────────────────────┼───────────────────────────────────────────┤
|
|
# │ ALERT_DROP_PCT │ 20 │ Alert when % off MSRP ≥ this value │
|
|
# │ ALERT_DROP_ABS │ 30 │ Alert when absolute $ drop ≥ this value │
|
|
# │ ALERT_EMAIL_TO │ (none) │ Comma-separated alert recipient addresses │
|
|
# ├─────────────────────────┼─────────────────────────┼───────────────────────────────────────────┤
|
|
# │ PROXY_URL │ (none) │ HTTP/S proxy for all scraper requests │
|
|
# │ LOG_LEVEL │ INFO │ Logging verbosity: DEBUG/INFO/WARNING │
|
|
# │ NAS_TRACKER_ENV │ (none) │ Override path to .env file │
|
|
# └─────────────────────────┴─────────────────────────┴───────────────────────────────────────────┘
|