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 1/4] 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({ From c6909ddc1453dfaaab6e31f9969c91339a8df653 Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Sat, 12 Sep 2026 01:33:03 -0700 Subject: [PATCH 2/4] test: run HTTPX upload regressions in CI Signed-off-by: 1fanwang <1fannnw@gmail.com> --- .github/workflows/import.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 8a110616b..7d6e0ee28 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -33,4 +33,9 @@ jobs: - name: Run import test run: | - pytest google/genai/tests/imports/test_no_optional_imports.py \ No newline at end of file + pytest google/genai/tests/imports/test_no_optional_imports.py + + - name: Run HTTPX upload regression tests + run: | + pip install -c requirements.txt pytest-asyncio + pytest google/genai/tests/client/test_upload_errors.py --mode=replay \ No newline at end of file From 60fa8b372d56d16ffb9609cc5f7d849ac9542898 Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Sat, 12 Sep 2026 02:18:07 -0700 Subject: [PATCH 3/4] ci: pin existing import workflow action versions Signed-off-by: 1fanwang <1fannnw@gmail.com> --- .github/workflows/import.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 7d6e0ee28..5135f7c86 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -17,10 +17,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ matrix.python-version }} From 98ba9b6e5919ae9b058c9c97794facba4aac7fe3 Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Sat, 12 Sep 2026 02:27:29 -0700 Subject: [PATCH 4/4] ci: restrict upload test job to read-only contents Signed-off-by: 1fanwang <1fannnw@gmail.com> --- .github/workflows/import.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 5135f7c86..2324c595c 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -10,6 +10,8 @@ on: jobs: test-import: runs-on: ubuntu-latest + permissions: + contents: read strategy: matrix: