diff --git a/.env.example b/.env.example index 081471c..366c470 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,9 @@ IMMICH_URL=http://your-immich-host:2283 IMMICH_API_KEY=your-immich-api-key +# Optional: Postgres DSN for read-only access to Immich's pgvector embeddings. +# Only needed by the pgvector spike (scripts/pgvector_spike.py) / M1.5 visual similarity. +# Format: postgresql://USER:PASSWORD@HOST:PORT/DBNAME (Immich defaults: user=postgres, db=immich) +# IMMICH_DB_URL=postgresql://postgres:your-db-password@your-immich-host:5432/immich ANTHROPIC_API_KEY= DATA_DIR=./data UID=1000 diff --git a/apps/trip-cluster/app/config.py b/apps/trip-cluster/app/config.py index 452504c..eb6c9da 100644 --- a/apps/trip-cluster/app/config.py +++ b/apps/trip-cluster/app/config.py @@ -17,6 +17,10 @@ class Config: immich_api_key: str anthropic_api_key: str data_dir: str + # Postgres DSN for read-only access to Immich's pgvector embeddings. + # Optional: only the pgvector spike / M1.5 visual-similarity work needs it; + # REST creds (immich_url/api_key) stay required. + immich_db_url: Optional[str] = None @property def db_path(self) -> str: @@ -33,9 +37,11 @@ def load_config(env: Optional[Mapping] = None) -> Config: if missing: raise ConfigError(missing) data_dir = (env.get("DATA_DIR") or "").strip() or os.path.join(os.getcwd(), "data") + immich_db_url = (env.get("IMMICH_DB_URL") or "").strip() or None return Config( immich_url=env["IMMICH_URL"].strip().rstrip("/"), immich_api_key=env["IMMICH_API_KEY"].strip(), anthropic_api_key=(env.get("ANTHROPIC_API_KEY") or "").strip(), data_dir=data_dir, + immich_db_url=immich_db_url, ) diff --git a/apps/trip-cluster/tests/test_config.py b/apps/trip-cluster/tests/test_config.py index 523280e..2a1ff14 100644 --- a/apps/trip-cluster/tests/test_config.py +++ b/apps/trip-cluster/tests/test_config.py @@ -16,3 +16,13 @@ def test_anthropic_optional_and_paths(tmp_path): assert cfg.anthropic_api_key == "" # optional in M1 assert cfg.db_path == os.path.join(str(tmp_path), "trip-cluster.db") assert cfg.thumbs_dir == os.path.join(str(tmp_path), "thumbs") + + +def test_immich_db_url_optional(): + # DSN is optional — only the pgvector spike / M1.5 need it; REST creds stay required. + cfg = load_config({"IMMICH_URL": "http://x", "IMMICH_API_KEY": "k"}) + assert cfg.immich_db_url is None + + cfg = load_config({"IMMICH_URL": "http://x", "IMMICH_API_KEY": "k", + "IMMICH_DB_URL": " postgresql://u:p@h:5432/immich "}) + assert cfg.immich_db_url == "postgresql://u:p@h:5432/immich" # trimmed diff --git a/scripts/requirements-spike.txt b/scripts/requirements-spike.txt new file mode 100644 index 0000000..c095876 --- /dev/null +++ b/scripts/requirements-spike.txt @@ -0,0 +1,5 @@ +# Dependencies for the throwaway pgvector feasibility spike (scripts/pgvector_spike.py). +# Kept out of the app's runtime deps on purpose — only the spike / M1.5 needs Postgres access. +# Install into a venv: pip install -r scripts/requirements-spike.txt +psycopg[binary]==3.3.4 +pgvector==0.4.2