Spaces:
Sleeping
Sleeping
| """List all watsonx.ai projects in the account, with their compute associations. | |
| The "right" project for our app is one in au-syd that has a watsonx.ai Runtime | |
| attached. The script highlights that. | |
| Run from api/: | |
| uv run python scripts/list_projects.py | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import subprocess | |
| import sys | |
| from dotenv import load_dotenv | |
| import httpx | |
| load_dotenv() | |
| def iam_token() -> str: | |
| api_key = os.environ.get("WATSONX_API_KEY", "") | |
| try: | |
| out = subprocess.check_output( | |
| ["ibmcloud", "iam", "oauth-tokens", "--output", "json"], | |
| text=True, | |
| stderr=subprocess.DEVNULL, | |
| ) | |
| return json.loads(out)["iam_token"] | |
| except Exception: | |
| pass | |
| res = httpx.post( | |
| "https://iam.cloud.ibm.com/identity/token", | |
| data={ | |
| "grant_type": "urn:ibm:params:oauth:grant-type:apikey", | |
| "apikey": api_key, | |
| }, | |
| timeout=15, | |
| ) | |
| res.raise_for_status() | |
| return f"Bearer {res.json()['access_token']}" | |
| def main() -> int: | |
| token = iam_token() | |
| # Try both global and regional endpoints | |
| endpoints = [ | |
| ("global v2", "https://api.dataplatform.cloud.ibm.com/v2/projects"), | |
| ("au-syd v2", "https://api.au-syd.dataplatform.cloud.ibm.com/v2/projects"), | |
| ("au-syd dai v2", "https://au-syd.dai.cloud.ibm.com/v2/projects"), | |
| ] | |
| projects: list = [] | |
| for name, url in endpoints: | |
| try: | |
| res = httpx.get(url, headers={"Authorization": token}, params={"limit": 100}, timeout=20) | |
| print(f" {name}: HTTP {res.status_code}", end="") | |
| if res.status_code == 200: | |
| got = res.json().get("resources", []) | |
| print(f" β {len(got)} project(s)") | |
| projects.extend(got) | |
| if got: | |
| break | |
| else: | |
| print(f" β {res.text[:80]}") | |
| except Exception as e: | |
| print(f" {name}: {type(e).__name__} {str(e)[:80]}") | |
| print() | |
| if not projects: | |
| print("No projects found.") | |
| print() | |
| print("Create a watsonx.ai project at:") | |
| print(" https://au-syd.dai.cloud.ibm.com/projects/?context=cpdaas") | |
| print("Then click '+ New service' in its Manage > Services & integrations page,") | |
| print("pick 'watsonx.ai Runtime' Lite plan in au-syd, and re-run this script.") | |
| return 1 | |
| print(f"Found {len(projects)} project(s) in your account:\n") | |
| candidate: dict | None = None | |
| for p in projects: | |
| meta = p.get("metadata", {}) | |
| ent = p.get("entity", {}) | |
| pid = meta.get("guid", "") | |
| region = meta.get("region", "?") | |
| name = ent.get("name", "") | |
| compute = ent.get("compute") or [] | |
| wml = [c for c in compute if "wml" in (c.get("type") or "").lower() or "machine_learning" in (c.get("type") or "").lower() or "watsonx" in (c.get("name") or "").lower()] | |
| marker = "β" if wml and region == "au-syd" else " " | |
| print(f" [{marker}] {name}") | |
| print(f" id: {pid}") | |
| print(f" region: {region}") | |
| print(f" compute: {', '.join(c.get('name','?') for c in compute) or 'NONE'}") | |
| print() | |
| if marker == "β" and candidate is None: | |
| candidate = p | |
| if candidate: | |
| cid = candidate["metadata"]["guid"] | |
| print(f"USE THIS ONE β set WATSONX_PROJECT_ID={cid} in api/.env") | |
| else: | |
| print("No project has a watsonx.ai Runtime attached in au-syd yet.") | |
| print() | |
| print("Pick one of the projects above (or create a new one), open it in the browser,") | |
| print("then click '+ New service' on its Services & integrations page, pick") | |
| print("'watsonx.ai Runtime' Lite plan in au-syd. Re-run this script after.") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |