"""Staged constraint discovery for s2s-reforecasts: progressively fix fields and read back the EXACT valid values (untruncated), so the minimal request uses real model-version days, hindcast dates and leadtime windows -- no guessing.""" import json import os import datapi ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ECDS_URL = "https://ecds.ecmwf.int/api" DATASET = "s2s-reforecasts" def _get_key(): k = os.environ.get("CDSAPI_KEY") if k: return k rc = os.environ.get("CDSAPI_RC", os.path.expanduser("~/.cdsapirc")) if os.path.exists(rc): for line in open(rc): if line.strip().startswith("key"): return line.split(":", 1)[1].strip() return None c = datapi.ApiClient(url=ECDS_URL, key=_get_key()) proc = c.get_process(DATASET) KEYS = ["year", "month", "day", "hyear", "hmonth", "hday", "leadtime_hour", "variable"] stages = { "base": {"origin": "ecmwf", "forecast_type": "control_forecast", "level_type": "single_level"}, "var_2t": {"origin": "ecmwf", "forecast_type": "control_forecast", "level_type": "single_level", "variable": ["2_m_temperature"]}, "var_2t_2015_01": {"origin": "ecmwf", "forecast_type": "control_forecast", "level_type": "single_level", "variable": ["2_m_temperature"], "year": "2015", "month": "01"}, } out = {} for name, sel in stages.items(): try: con = proc.apply_constraints(sel) out[name] = {"selection": sel, "valid": {k: con.get(k) for k in KEYS if k in con}} print(f"\n===== {name} =====", flush=True) for k in KEYS: if k in con: v = con[k] print(f" {k}: {v if not isinstance(v,list) or len(v)<=40 else v[:40]+['...']}", flush=True) except Exception as e: out[name] = {"selection": sel, "error": f"{type(e).__name__}: {e}"} print(f"{name}: ERROR {e}", flush=True) with open(os.path.join(ROOT, "metadata", "ecds_constraints_staged.json"), "w") as f: json.dump(out, f, indent=2, default=str) print("\nwrote metadata/ecds_constraints_staged.json", flush=True)