From 5a3be2f708fe4431436f233f21cbd9c01e2f730b Mon Sep 17 00:00:00 2001 From: Dmitry Meyer Date: Mon, 4 May 2026 09:19:32 +0000 Subject: [PATCH] Runpod: update `RunpodApiClient` * Use `requests.Session` * Pass API token as a header, not a query param. Prevents token leakage through logs: requests.exceptions.ConnectionError: Max retries exceeded with url: /graphql?api_key=rpa_xxxxx (Caused by ...) --- src/dstack/_internal/core/backends/runpod/api_client.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dstack/_internal/core/backends/runpod/api_client.py b/src/dstack/_internal/core/backends/runpod/api_client.py index 11eca19e72..6ded322399 100644 --- a/src/dstack/_internal/core/backends/runpod/api_client.py +++ b/src/dstack/_internal/core/backends/runpod/api_client.py @@ -22,7 +22,8 @@ def __init__(self, errors: List[Dict]): class RunpodApiClient: def __init__(self, api_key: str): - self.api_key = api_key + self._session = requests.Session() + self._session.headers.update({"Authorization": f"Bearer {api_key}"}) def validate_api_key(self) -> bool: try: @@ -353,9 +354,9 @@ def delete_cluster(self, cluster_id: str) -> bool: def _make_request(self, data: Optional[Dict[str, Any]] = None) -> Response: try: - response = requests.request( + response = self._session.request( method="POST", - url=f"{API_URL}?api_key={self.api_key}", + url=API_URL, json=data, timeout=120, )