diff --git a/pyproject.toml b/pyproject.toml index 3af138122..9d90bad8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "redo>=2.0", "requests>=2.25", "slugid>=2.0", - "taskcluster>=91.0,<92.0", + "taskcluster>=92.0", "taskcluster-urls>=11.0", "voluptuous>=0.12.1", ] diff --git a/src/taskgraph/util/taskcluster.py b/src/taskgraph/util/taskcluster.py index e313c5bd3..b997f8a52 100644 --- a/src/taskgraph/util/taskcluster.py +++ b/src/taskgraph/util/taskcluster.py @@ -71,21 +71,9 @@ def get_taskcluster_client(service: str): def _handle_artifact( - path: str, response: Union[requests.Response, dict[str, Any]] + path: str, + response: requests.Response, ) -> Any: - # When taskcluster client returns non-JSON responses, it wraps them in {"response": } - if ( - isinstance(response, dict) - and "response" in response - and isinstance(response["response"], requests.Response) - ): - response = response["response"] - - if not isinstance(response, requests.Response): - # At this point, if we don't have a response object, it's already parsed, return it - return response - - # We have a response object, load the content based on the path extension. if path.endswith(".json"): return response.json() @@ -159,6 +147,7 @@ def get_artifact(task_id, path): """ queue = get_taskcluster_client("queue") response = queue.getLatestArtifact(task_id, path) + response = get_session().get(response["url"]) return _handle_artifact(path, response) @@ -231,6 +220,8 @@ def pagination_handler(response): def get_artifact_from_index(index_path, artifact_path): index = get_taskcluster_client("index") response = index.findArtifactFromTask(index_path, artifact_path) + assert 300 <= response["response"].status_code < 400 + response = get_session().get(response["response"].headers["location"]) return _handle_artifact(artifact_path, response) diff --git a/test/test_util_taskcluster.py b/test/test_util_taskcluster.py index d6c8c00b6..72ae6ed37 100644 --- a/test/test_util_taskcluster.py +++ b/test/test_util_taskcluster.py @@ -237,8 +237,10 @@ def test_get_artifact_from_index(responses, root_url): responses.get( f"{root_url}/api/index/v1/task/{index}/artifacts/{path}", - body=b"foobar", + status=303, + headers={"Location": f"http://foo.bar/{path}"}, ) + responses.get(f"http://foo.bar/{path}", body="foobar") result = tc.get_artifact_from_index(index, path) assert result.read() == b"foobar" @@ -252,6 +254,11 @@ def test_get_artifact_from_index_uses_artifact_path_for_parsing(responses, root_ responses.get( f"{root_url}/api/index/v1/task/{index_path}/artifacts/{artifact_path}", + status=303, + headers={"Location": f"http://foo.bar/{artifact_path}"}, + ) + responses.get( + f"http://foo.bar/{artifact_path}", body=b"key: value", ) diff --git a/uv.lock b/uv.lock index 57152f59c..b4980e641 100644 --- a/uv.lock +++ b/uv.lock @@ -2002,7 +2002,7 @@ wheels = [ [[package]] name = "taskcluster" -version = "91.1.2" +version = "95.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -2013,9 +2013,9 @@ dependencies = [ { name = "slugid" }, { name = "taskcluster-urls" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/dc/dd750c279a9a1fe8637da98c4474e5c389ac9d0673a2e55668ce05f66e75/taskcluster-91.1.2.tar.gz", hash = "sha256:ac9cb0c6b63367601a896d2724a9f62e15cf455191e5c0b533a2d8149340bf39", size = 252539, upload-time = "2025-10-30T16:03:55.827Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/2d/2f217e253294943ec9d33e4d8c6796ad2cf0d5f5a1e9f713c0cf6460426f/taskcluster-95.1.1.tar.gz", hash = "sha256:06e007d2dd54b62fd55957db2f004e8c750632cce8b6a48a9bcd2c02494e1311", size = 253100, upload-time = "2026-01-12T18:06:29.269Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/20/4de71e67cf7f9821cf85ad654dba4a2192272ee64c0449c08e9666a55bd4/taskcluster-91.1.2-py3-none-any.whl", hash = "sha256:fc588922305a0ba586d8eac8b8cb3a8479324d49ee37a176d34a3bf9a152963d", size = 147172, upload-time = "2025-10-30T16:03:53.933Z" }, + { url = "https://files.pythonhosted.org/packages/00/bb/887d9209176685e6ce717253ba158b67e1caf363c8fcb77ea26763d90181/taskcluster-95.1.1-py3-none-any.whl", hash = "sha256:f10a90f961a908270ff1b1239abaf708f5adf2bca31c910bdeba4a1f35358f71", size = 147869, upload-time = "2026-01-12T18:06:31.624Z" }, ] [[package]] @@ -2079,7 +2079,7 @@ requires-dist = [ { name = "redo", specifier = ">=2.0" }, { name = "requests", specifier = ">=2.25" }, { name = "slugid", specifier = ">=2.0" }, - { name = "taskcluster", specifier = ">=91.0,<92.0" }, + { name = "taskcluster", specifier = ">=92.0" }, { name = "taskcluster-urls", specifier = ">=11.0" }, { name = "voluptuous", specifier = ">=0.12.1" }, { name = "zstandard", marker = "extra == 'load-image'" },