From 287926e4c0920b930af2b9d3d8b46a24e78e2979 Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Tue, 9 Jul 2024 19:03:49 +0100 Subject: [PATCH 1/3] fix(azure): refresh auth token during retries (#1533) --- tests/lib/test_azure.py | 88 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/tests/lib/test_azure.py b/tests/lib/test_azure.py index 9360b2925a..a9d3478350 100644 --- a/tests/lib/test_azure.py +++ b/tests/lib/test_azure.py @@ -1,7 +1,9 @@ -from typing import Union -from typing_extensions import Literal +from typing import Union, cast +from typing_extensions import Literal, Protocol +import httpx import pytest +from respx import MockRouter from openai._models import FinalRequestOptions from openai.lib.azure import AzureOpenAI, AsyncAzureOpenAI @@ -22,6 +24,10 @@ ) +class MockRequestCall(Protocol): + request: httpx.Request + + @pytest.mark.parametrize("client", [sync_client, async_client]) def test_implicit_deployment_path(client: Client) -> None: req = client._build_request( @@ -64,3 +70,81 @@ def test_client_copying_override_options(client: Client) -> None: api_version="2022-05-01", ) assert copied._custom_query == {"api-version": "2022-05-01"} + + +@pytest.mark.respx() +def test_client_token_provider_refresh_sync(respx_mock: MockRouter) -> None: + respx_mock.post( + "https://example-resource.azure.openai.com/openai/deployments/gpt-4/chat/completions?api-version=2024-02-01" + ).mock( + side_effect=[ + httpx.Response(500, json={"error": "server error"}), + httpx.Response(200, json={"foo": "bar"}), + ] + ) + + counter = 0 + + def token_provider() -> str: + nonlocal counter + + counter += 1 + + if counter == 1: + return "first" + + return "second" + + client = AzureOpenAI( + api_version="2024-02-01", + azure_ad_token_provider=token_provider, + azure_endpoint="https://example-resource.azure.openai.com", + ) + client.chat.completions.create(messages=[], model="gpt-4") + + calls = cast("list[MockRequestCall]", respx_mock.calls) + + assert len(calls) == 2 + + assert calls[0].request.headers.get("Authorization") == "Bearer first" + assert calls[1].request.headers.get("Authorization") == "Bearer second" + + +@pytest.mark.asyncio +@pytest.mark.respx() +async def test_client_token_provider_refresh_async(respx_mock: MockRouter) -> None: + respx_mock.post( + "https://example-resource.azure.openai.com/openai/deployments/gpt-4/chat/completions?api-version=2024-02-01" + ).mock( + side_effect=[ + httpx.Response(500, json={"error": "server error"}), + httpx.Response(200, json={"foo": "bar"}), + ] + ) + + counter = 0 + + def token_provider() -> str: + nonlocal counter + + counter += 1 + + if counter == 1: + return "first" + + return "second" + + client = AsyncAzureOpenAI( + api_version="2024-02-01", + azure_ad_token_provider=token_provider, + azure_endpoint="https://example-resource.azure.openai.com", + ) + + await client.chat.completions.create(messages=[], model="gpt-4") + + calls = cast("list[MockRequestCall]", respx_mock.calls) + + assert len(calls) == 2 + + assert calls[0].request.headers.get("Authorization") == "Bearer first" + assert calls[1].request.headers.get("Authorization") == "Bearer second" From 64da888ca4d13f0b4b6d9e22ec93a897b2d6bb24 Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Tue, 9 Jul 2024 19:13:30 +0100 Subject: [PATCH 2/3] fix(tests): fresh_env() now resets new environment values --- tests/test_module_client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_module_client.py b/tests/test_module_client.py index 05b5f81111..6bab33a1d7 100644 --- a/tests/test_module_client.py +++ b/tests/test_module_client.py @@ -110,6 +110,7 @@ def fresh_env() -> Iterator[None]: _os.environ.clear() yield finally: + _os.environ.clear() _os.environ.update(old) From 16cb477fceffb35ca2f930f3fedca342ce4cef03 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:13:54 +0000 Subject: [PATCH 3/3] release: 1.35.12 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ pyproject.toml | 2 +- src/openai/_version.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f0ed4549e0..7ac9c7d661 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.35.11" + ".": "1.35.12" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 52c8216f28..7e0be66b84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.35.12 (2024-07-09) + +Full Changelog: [v1.35.11...v1.35.12](https://github.com/openai/openai-python/compare/v1.35.11...v1.35.12) + +### Bug Fixes + +* **azure:** refresh auth token during retries ([#1533](https://github.com/openai/openai-python/issues/1533)) ([287926e](https://github.com/openai/openai-python/commit/287926e4c0920b930af2b9d3d8b46a24e78e2979)) +* **tests:** fresh_env() now resets new environment values ([64da888](https://github.com/openai/openai-python/commit/64da888ca4d13f0b4b6d9e22ec93a897b2d6bb24)) + ## 1.35.11 (2024-07-09) Full Changelog: [v1.35.10...v1.35.11](https://github.com/openai/openai-python/compare/v1.35.10...v1.35.11) diff --git a/pyproject.toml b/pyproject.toml index 3098d4c24f..b81031b1fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openai" -version = "1.35.11" +version = "1.35.12" description = "The official Python library for the openai API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/openai/_version.py b/src/openai/_version.py index 237442ec47..d7cdffe676 100644 --- a/src/openai/_version.py +++ b/src/openai/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "openai" -__version__ = "1.35.11" # x-release-please-version +__version__ = "1.35.12" # x-release-please-version