From e802b5f889b5599c19ea09af75cb65da0a7e6041 Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Thu, 3 Sep 2026 03:34:36 -0400 Subject: [PATCH] fix: keep async upload retries cancellable Signed-off-by: 1fanwang <1fannnw@gmail.com> --- google/genai/_api_client.py | 2 +- .../genai/tests/client/test_upload_errors.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/google/genai/_api_client.py b/google/genai/_api_client.py index 27adcf813..1baf712c0 100644 --- a/google/genai/_api_client.py +++ b/google/genai/_api_client.py @@ -2315,7 +2315,7 @@ async def _async_upload_fd( break delay_seconds = INITIAL_RETRY_DELAY * (DELAY_MULTIPLIER**retry_count) retry_count += 1 - time.sleep(delay_seconds) + await asyncio.sleep(delay_seconds) offset += chunk_size if ( diff --git a/google/genai/tests/client/test_upload_errors.py b/google/genai/tests/client/test_upload_errors.py index 897913ca7..2362d055c 100644 --- a/google/genai/tests/client/test_upload_errors.py +++ b/google/genai/tests/client/test_upload_errors.py @@ -132,6 +132,34 @@ async def test_async_upload_url_rewrite_httpx(client: api_client.BaseApiClient): ) +@pytest.mark.asyncio +async def test_async_upload_retry_uses_async_sleep( + client: api_client.BaseApiClient, +): + mock_async_httpx_client = mock.MagicMock(spec=httpx.AsyncClient) + mock_async_httpx_client.request = mock.AsyncMock(side_effect=[ + _httpx_response(200), + _httpx_response(200, headers={"X-Goog-Upload-Status": "final"}), + ]) + client._async_httpx_client = mock_async_httpx_client + + with ( + mock.patch.object(client, "_use_aiohttp", return_value=False), + mock.patch.object( + api_client.asyncio, "sleep", new=mock.AsyncMock() + ) as sleep, + io.BytesIO(b"test") as f, + ): + await client._async_upload_fd( + f, + "http://fake/upload", + 4, + http_options=types.HttpOptions(), + ) + + sleep.assert_awaited_once_with(api_client.INITIAL_RETRY_DELAY) + + @pytest.mark.asyncio async def test_async_upload_fd_error_httpx(client: api_client.BaseApiClient): error_content = json.dumps({