From cbb127115c4d6bdb987f001acc55ce8d030ff569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D1=83=D1=80=D1=83=D0=BF=D0=BE=D0=B2=20=D0=98=D0=BB?= =?UTF-8?q?=D1=8C=D1=8F=20=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B8=D1=87?= Date: Tue, 16 Jun 2026 00:48:03 +0300 Subject: [PATCH] Auto-load .env; make --spotify-full force the cached path too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The live fetch was being skipped because creds never reached the process: Env.py only read os.environ, and .env uses `export ...`, so without a prior `source .env` the run fell to the cached branch — which then skipped on an unchanged cache signature ("Spotify cache unchanged — skipping"). - Env.py now auto-loads a project-root .env (setdefault, so an exported value still wins; tolerates `export ` and quotes). - --spotify-full now also passes force=True to ingest_spotify, so the cached fallback re-ingests instead of skipping. Co-Authored-By: Claude Opus 4.8 --- Env.py | 23 +++++++++++++++++++++++ README.md | 5 ++++- src/workflows.py | 4 ++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Env.py b/Env.py index ef038ad..cef7222 100644 --- a/Env.py +++ b/Env.py @@ -10,6 +10,29 @@ import os from pathlib import Path +def _load_dotenv(): + """Load a project-root .env into os.environ if present, so `python main.py` + works without remembering to `source .env`. Already-set environment + variables win (setdefault), so an explicit `source .env`/export still + overrides. Supports an optional leading `export ` and quoted values.""" + path = Path(__file__).with_name(".env") + if not path.exists(): + return + for raw in path.read_text().splitlines(): + line = raw.strip() + if not line or line.startswith("#"): + continue + if line.startswith("export "): + line = line[len("export "):] + key, sep, value = line.partition("=") + if not sep: + continue + os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'")) + + +_load_dotenv() + + def _path(env, default): return Path(os.environ.get(env, default)).expanduser() diff --git a/README.md b/README.md index 4d8c7bf..c6cf02c 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,12 @@ pip install -r requirements.txt ### Configure (`.env`) ```bash -cp .env.example .env # then edit and `source .env` +cp .env.example .env # then edit — it's auto-loaded (no `source` needed) ``` +The project root `.env` is read automatically on startup; any variable already +exported in your shell still takes precedence. + Three things you point at your own data: | Variable | What | diff --git a/src/workflows.py b/src/workflows.py index a65cbd7..afb4bce 100644 --- a/src/workflows.py +++ b/src/workflows.py @@ -50,10 +50,10 @@ def run_fetch(enrich_limit=None, enrich=True, spotify_full=False, include_top=Fa fetch_spotify_incremental(full=spotify_full, include_top=include_top) except Exception as exc: # keep going on cached data log.error("live fetch failed (%s); falling back to cached responses", exc) - ingest_spotify(include_top=include_top) + ingest_spotify(include_top=include_top, force=spotify_full) else: log.info("no SPOTIFY_CLIENT_ID/SECRET -> using cached responses") - ingest_spotify(include_top=include_top) + ingest_spotify(include_top=include_top, force=spotify_full) _step("iTunes") ingest_itunes()