From 3338e1165f7ef72ad3723779ff437b42a1d0fa87 Mon Sep 17 00:00:00 2001 From: Pete Steward Date: Wed, 24 Jun 2026 16:39:16 +0300 Subject: [PATCH 1/2] docs: improve Earth Engine setup guidance --- README.md | 71 ++++++++++--------- .../source_data/sources/xee_common.py | 9 ++- tests/test_fetch_pipeline.py | 2 + tests/test_xee_common.py | 13 ++++ 4 files changed, 60 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index f791929..c7a7383 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,44 @@ normal user workflows. ## Quick Start +### Earth Engine setup + +Most historical gridded defaults and all current NEX-GDDP real-access paths use +Earth Engine-backed retrieval. Do this first. + +Important: + +- `YOUR_PROJECT_ID` below is placeholder text +- replace it with your real Google Cloud **Project ID** +- do not paste literal string `YOUR_PROJECT_ID` + +```bash +python -c "import ee; ee.Authenticate()" +export GCP_PROJECT_ID=YOUR_PROJECT_ID +python -c "import ee; ee.Initialize(project='$GCP_PROJECT_ID'); print('EE init OK')" +``` + +Windows PowerShell: + +```powershell +python -c "import ee; ee.Authenticate()" +$env:GCP_PROJECT_ID="YOUR_PROJECT_ID" +python -c "import ee; ee.Initialize(project='$env:GCP_PROJECT_ID'); print('EE init OK')" +``` + +Required in `.env.example`: + +- `GCP_PROJECT_ID` +- optional `EARTHDATA_USERNAME` / `EARTHDATA_PASSWORD` for sources that still + use Earthdata-backed access + +If you see: + +- `Earth Engine project ID missing` -> set `GCP_PROJECT_ID` +- `Project 'projects/YOUR_PROJECT_ID' not found or deleted` -> placeholder was + not replaced with real project ID +- auth refresh / DNS errors -> refresh Earth Engine auth and check internet/DNS + ### Installation 1. Clone repository @@ -165,39 +203,6 @@ Reference note: - `docs/distribution_workflow.md` -### Earth Engine setup - -Most historical gridded defaults and all current NEX-GDDP real-access paths use -Earth Engine-backed retrieval. Before running those sources, authenticate Earth -Engine and set project ID. - -```bash -python -c "import ee; ee.Authenticate()" -python -c "import ee; ee.Initialize(project='YOUR_PROJECT_ID')" -export GCP_PROJECT_ID=YOUR_PROJECT_ID -``` - -Windows PowerShell: - -```powershell -python -c "import ee; ee.Authenticate()" -python -c "import ee; ee.Initialize(project='YOUR_PROJECT_ID')" -$env:GCP_PROJECT_ID="YOUR_PROJECT_ID" -``` - -Required in `.env.example`: - -- `GCP_PROJECT_ID` -- optional `EARTHDATA_USERNAME` / `EARTHDATA_PASSWORD` for sources that still - use Earthdata-backed access - -If you see: - -- `Earth Engine project ID missing` -> set `GCP_PROJECT_ID` -- `Project 'projects/your-ee-project-id' not found or deleted` -> you left - placeholder value in environment or auth init command -- auth refresh / DNS errors -> refresh Earth Engine auth and check internet/DNS - ### Recommended starting point For historical daily climate workflows, start with: diff --git a/climate_tookit/fetch_data/source_data/sources/xee_common.py b/climate_tookit/fetch_data/source_data/sources/xee_common.py index c4e7e1c..e65003d 100644 --- a/climate_tookit/fetch_data/source_data/sources/xee_common.py +++ b/climate_tookit/fetch_data/source_data/sources/xee_common.py @@ -17,6 +17,9 @@ DEFAULT_EE_OPT_URL = "https://earthengine-highvolume.googleapis.com" METERS_PER_DEGREE = 111_320.0 MISSING_EE_PROJECT_ID_PREFIX = "Earth Engine project ID is required." +EARTH_ENGINE_SETUP_URL = ( + "https://github.com/CGIAR-Climate-Data-Hub/climate-toolkit#earth-engine-setup" +) def import_xee_stack(required_for: str = "xee_common"): @@ -59,7 +62,8 @@ def format_ee_setup_error(exc: Exception) -> str: return ( "Earth Engine project ID missing. Set GCP_PROJECT_ID " "(or GOOGLE_CLOUD_PROJECT / EE_PROJECT_ID) and retry. " - "Example: export GCP_PROJECT_ID=your-ee-project-id" + "Example: export GCP_PROJECT_ID=your-ee-project-id. " + f"Setup guide: {EARTH_ENGINE_SETUP_URL}" ) lowered = message.lower() if ( @@ -71,7 +75,8 @@ def format_ee_setup_error(exc: Exception) -> str: return ( "Earth Engine auth refresh failed. Check internet/DNS access, then " "refresh auth if needed with: " - ".venv/bin/python -c \"import ee; ee.Authenticate(); ee.Initialize(project='YOUR_PROJECT_ID')\"" + ".venv/bin/python -c \"import ee; ee.Authenticate(); ee.Initialize(project='YOUR_PROJECT_ID')\". " + f"Setup guide: {EARTH_ENGINE_SETUP_URL}" ) return message diff --git a/tests/test_fetch_pipeline.py b/tests/test_fetch_pipeline.py index acf5df8..7f39ac1 100644 --- a/tests/test_fetch_pipeline.py +++ b/tests/test_fetch_pipeline.py @@ -802,6 +802,7 @@ def test_main_prints_simple_message_when_ee_project_id_missing(self): self.assertEqual(1, exit_code) self.assertIn("Earth Engine project ID missing.", output) self.assertIn("GCP_PROJECT_ID", output) + self.assertIn("earth-engine-setup", output) def test_source_data_main_prints_simple_message_when_ee_project_id_missing(self): argv = [ @@ -845,6 +846,7 @@ def download(self): self.assertEqual(1, exit_code) self.assertIn("Earth Engine project ID missing.", output) self.assertIn("GCP_PROJECT_ID", output) + self.assertIn("earth-engine-setup", output) def test_source_data_main_accepts_project_id_option(self): argv = [ diff --git a/tests/test_xee_common.py b/tests/test_xee_common.py index ea6aed9..a6b9156 100644 --- a/tests/test_xee_common.py +++ b/tests/test_xee_common.py @@ -70,6 +70,19 @@ def test_format_ee_setup_error_simplifies_auth_refresh_network_failures(self): self.assertIn("Earth Engine auth refresh failed.", message) self.assertIn("ee.Authenticate()", message) + self.assertIn(xee_common.EARTH_ENGINE_SETUP_URL, message) + + def test_format_ee_setup_error_adds_setup_guide_for_missing_project_id(self): + message = xee_common.format_ee_setup_error( + ValueError( + "Earth Engine project ID is required. Pass ee_project_id or set one of " + "GCP_PROJECT_ID, GOOGLE_CLOUD_PROJECT, or EE_PROJECT_ID." + ) + ) + + self.assertIn("Earth Engine project ID missing.", message) + self.assertIn("GCP_PROJECT_ID", message) + self.assertIn(xee_common.EARTH_ENGINE_SETUP_URL, message) if __name__ == "__main__": From 0b0681d14c6e91af27387580e09e44166022fbfc Mon Sep 17 00:00:00 2001 From: Pete Steward Date: Wed, 24 Jun 2026 16:42:24 +0300 Subject: [PATCH 2/2] docs: add issue templates and repro helper --- .github/ISSUE_TEMPLATE/bug_report.yml | 72 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/feature_request.yml | 62 +++++++++++++++++++ demo_issue_69.sh | 50 +++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100755 demo_issue_69.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..55c9ee8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,72 @@ +name: Bug report +description: Report broken behavior, runtime errors, or incorrect outputs. +title: "[bug] " +labels: + - bug +body: + - type: markdown + attributes: + value: | + Before submitting: + - add labels for `type`, `area`, `priority`, and `provenance` + - if this is GEE-related, note whether Earth Engine auth and `GCP_PROJECT_ID` were set + - include exact CLI command or minimal repro + + Recommended labels: + - type: `bug` + - area: e.g. `gee`, `fetch-data`, `historical-cli`, `nex-gddp`, `weather-station`, `hazards` + - priority: `priority:high|medium|low` + - provenance: `sammy`, `michel`, `codex`, or `user-feedback` + - type: textarea + id: summary + attributes: + label: Problem summary + description: What broke? + placeholder: Clear one-paragraph description of problem. + validations: + required: true + - type: textarea + id: repro + attributes: + label: Exact command or minimal repro + description: Paste exact CLI command, Python snippet, or steps. + render: bash + validations: + required: true + - type: textarea + id: observed + attributes: + label: Observed behavior + description: Include exact error text, traceback, or wrong output. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What should have happened instead? + validations: + required: true + - type: textarea + id: context + attributes: + label: Environment and context + description: OS, Python version, auth state, source, date range, cache status, etc. + placeholder: | + OS: + Python: + Source: + Date range: + Earth Engine auth: + GCP_PROJECT_ID set: + Cold-cache or warm-cache: + validations: + required: false + - type: textarea + id: labels + attributes: + label: Labels to apply + description: List labels you think fit if you cannot apply them yourself. + placeholder: bug, gee, fetch-data, priority:high, michel + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..d798d40 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: README setup and usage guide + url: https://github.com/CGIAR-Climate-Data-Hub/climate-toolkit#readme + about: Check installation, Earth Engine setup, and CLI usage before opening a new issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..4765eda --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,62 @@ +name: Feature or enhancement +description: Propose new capability, UX improvement, research task, or refactor slice. +title: "[enhancement] " +labels: + - enhancement +body: + - type: markdown + attributes: + value: | + Before submitting: + - add labels for `type`, `area`, `priority`, and `provenance` + - use `research` / `methodology` when issue depends on external evidence + - use `needs-docs` when user-facing behavior or CLI changes are expected + + Recommended labels: + - type: `enhancement`, `research`, `methodology`, `performance`, `refactor`, `documentation` + - area: e.g. `gee`, `fetch-data`, `historical-cli`, `nex-gddp`, `weather-station`, `hazards`, `packaging`, `readme` + - priority: `priority:high|medium|low` + - provenance: `sammy`, `michel`, `codex`, or `user-feedback` + - type: textarea + id: summary + attributes: + label: Proposal summary + description: What should be added or changed? + validations: + required: true + - type: textarea + id: problem + attributes: + label: Problem or motivation + description: Why does this matter? + validations: + required: true + - type: textarea + id: scope + attributes: + label: Suggested scope + description: What should be in scope? What can wait? + validations: + required: false + - type: textarea + id: acceptance + attributes: + label: Acceptance ideas + description: How should we know this is done? + validations: + required: false + - type: textarea + id: references + attributes: + label: References or related issues + description: Literature, docs, issue links, screenshots, prior discussion. + validations: + required: false + - type: textarea + id: labels + attributes: + label: Labels to apply + description: List labels you think fit if you cannot apply them yourself. + placeholder: enhancement, ux, historical-cli, priority:medium, codex + validations: + required: false diff --git a/demo_issue_69.sh b/demo_issue_69.sh new file mode 100755 index 0000000..7dc0b36 --- /dev/null +++ b/demo_issue_69.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# Demo for issue #69: NEX-GDDP batch "Earth Engine project ID missing". +# Shows the failure (no project id) then a cold-start live fetch (project id set, +# cache refreshed, fresh cache dir => no cached data used). +# +# Usage: +# ./demo_issue_69.sh +# ./demo_issue_69.sh ee-peetmate +# +# Requires: .venv with earthengine-api, and EE auth already done +# (~/.config/earthengine/credentials). If not authed: +# .venv/bin/python -c "import ee; ee.Authenticate()" + +set -u + +PROJECT_ID="${1:-}" +PY=".venv/bin/python" +CACHE_DIR="/tmp/nexgddp_coldtest" + +CMD_ARGS=( + -m climate_tookit.fetch_data.nex_gddp_batch + --variables precipitation,max_temperature,min_temperature + --from 2050-01-01 --to 2050-01-10 + --lon 36.817 --lat -1.286 + --model GFDL-ESM4 --scenario ssp245 + --stage raw +) + +echo "==============================================================" +echo " STEP 1: reproduce the bug — no project id set" +echo "==============================================================" +env -u GCP_PROJECT_ID -u GOOGLE_CLOUD_PROJECT -u EE_PROJECT_ID \ + "$PY" "${CMD_ARGS[@]}" +echo +echo "(expected: 'Error: Earth Engine project ID missing.')" +echo + +if [ -z "$PROJECT_ID" ]; then + echo "No EE project id passed. Re-run with: ./demo_issue_69.sh " + exit 1 +fi + +echo "==============================================================" +echo " STEP 2: cold-start live fetch — project id set, cache wiped" +echo "==============================================================" +rm -rf "$CACHE_DIR" # cold start: no cached data +GCP_PROJECT_ID="$PROJECT_ID" \ + "$PY" "${CMD_ARGS[@]}" --refresh-cache --cache-dir "$CACHE_DIR" +echo +echo "(expected: 'fetched' (not 'cache hit') + 10 rows of data)"