From 135498cb8c206ab385cc91f2089e20e3f0ec4cfb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Sep 2025 21:51:13 +0000 Subject: [PATCH 1/3] Initial plan From a4ccbd27166b7d29546349702909a0ebc458d111 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Sep 2025 22:01:10 +0000 Subject: [PATCH 2/3] Migrate from AsyncAzureOpenAI to AsyncOpenAI client Co-authored-by: pamelafox <297042+pamelafox@users.noreply.github.com> --- .env.sample | 1 - =1.108.1 | 17 +++++++++++++ infra/aca.bicep | 5 ---- infra/main.bicep | 3 --- src/pyproject.toml | 2 +- src/quartapp/chat.py | 11 ++++---- src/requirements.txt | 60 ++++++++++++++++++++++---------------------- tests/test_app.py | 3 +-- 8 files changed, 54 insertions(+), 48 deletions(-) create mode 100644 =1.108.1 diff --git a/.env.sample b/.env.sample index 331045a4..8d821001 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,3 @@ -AZURE_OPENAI_API_VERSION=2024-02-15-preview AZURE_OPENAI_ENDPOINT=https://YOUR-ENDPOINT-HERE.openai.azure.com/ # Name of the Azure OpenAI GPT deployment (different from the model name) AZURE_OPENAI_CHAT_DEPLOYMENT=gpt4o-mini diff --git a/=1.108.1 b/=1.108.1 new file mode 100644 index 00000000..a43f52fb --- /dev/null +++ b/=1.108.1 @@ -0,0 +1,17 @@ +Defaulting to user installation because normal site-packages is not writeable +Requirement already satisfied: openai in /home/runner/.local/lib/python3.12/site-packages (1.107.2) +Requirement already satisfied: anyio<5,>=3.5.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (4.10.0) +Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai) (1.9.0) +Requirement already satisfied: httpx<1,>=0.23.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (0.28.1) +Requirement already satisfied: jiter<1,>=0.4.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (0.10.0) +Requirement already satisfied: pydantic<3,>=1.9.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (2.11.9) +Requirement already satisfied: sniffio in /home/runner/.local/lib/python3.12/site-packages (from openai) (1.3.1) +Requirement already satisfied: tqdm>4 in /home/runner/.local/lib/python3.12/site-packages (from openai) (4.67.1) +Requirement already satisfied: typing-extensions<5,>=4.11 in /home/runner/.local/lib/python3.12/site-packages (from openai) (4.15.0) +Requirement already satisfied: idna>=2.8 in /home/runner/.local/lib/python3.12/site-packages (from anyio<5,>=3.5.0->openai) (3.10) +Requirement already satisfied: certifi in /home/runner/.local/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (2025.8.3) +Requirement already satisfied: httpcore==1.* in /home/runner/.local/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (1.0.9) +Requirement already satisfied: h11>=0.16 in /home/runner/.local/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai) (0.16.0) +Requirement already satisfied: annotated-types>=0.6.0 in /home/runner/.local/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (0.7.0) +Requirement already satisfied: pydantic-core==2.33.2 in /home/runner/.local/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (2.33.2) +Requirement already satisfied: typing-inspection>=0.4.0 in /home/runner/.local/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (0.4.1) diff --git a/infra/aca.bicep b/infra/aca.bicep index e842ce0d..79a4664d 100644 --- a/infra/aca.bicep +++ b/infra/aca.bicep @@ -9,7 +9,6 @@ param serviceName string = 'aca' param exists bool param openAiDeploymentName string param openAiEndpoint string -param openAiApiVersion string resource acaIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: identityName @@ -25,10 +24,6 @@ var env = [ name: 'AZURE_OPENAI_ENDPOINT' value: openAiEndpoint } - { - name: 'AZURE_OPENAI_API_VERSION' - value: openAiApiVersion - } { name: 'RUNNING_IN_PRODUCTION' value: 'true' diff --git a/infra/main.bicep b/infra/main.bicep index a28ba4f0..ee565806 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -55,7 +55,6 @@ param openAiResourceGroupName string = '' }) param openAiResourceLocation string param openAiSkuName string = '' -param openAiApiVersion string = '' // Used by the SDK in the app code param disableKeyBasedAuth bool = true // Parameters for the specific Azure OpenAI deployment: @@ -152,7 +151,6 @@ module aca 'aca.bicep' = { containerRegistryName: containerApps.outputs.registryName openAiDeploymentName: openAiDeploymentName openAiEndpoint: createAzureOpenAi ? openAi.outputs.endpoint : openAiEndpoint - openAiApiVersion: openAiApiVersion exists: acaExists } } @@ -185,7 +183,6 @@ output AZURE_TENANT_ID string = tenant().tenantId output AZURE_OPENAI_RESOURCE_GROUP string = openAiResourceGroup.name output AZURE_OPENAI_RESOURCE_NAME string = openAi.outputs.name output AZURE_OPENAI_CHAT_DEPLOYMENT string = openAiDeploymentName -output AZURE_OPENAI_API_VERSION string = openAiApiVersion output AZURE_OPENAI_ENDPOINT string = createAzureOpenAi ? openAi.outputs.endpoint : openAiEndpoint output SERVICE_ACA_IDENTITY_PRINCIPAL_ID string = aca.outputs.SERVICE_ACA_IDENTITY_PRINCIPAL_ID diff --git a/src/pyproject.toml b/src/pyproject.toml index 541b8d17..7267ad51 100644 --- a/src/pyproject.toml +++ b/src/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "httptools", # Used by uvicorn for reload functionality "watchfiles", - "openai", + "openai>=1.108.1", "azure-identity", "aiohttp>=3.11.0", "python-dotenv", diff --git a/src/quartapp/chat.py b/src/quartapp/chat.py index 29bd5423..c3198b64 100644 --- a/src/quartapp/chat.py +++ b/src/quartapp/chat.py @@ -7,7 +7,7 @@ ManagedIdentityCredential, get_bearer_token_provider, ) -from openai import AsyncAzureOpenAI +from openai import AsyncOpenAI from quart import ( Blueprint, Response, @@ -47,11 +47,10 @@ async def configure_openai(): if not os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT"): raise ValueError("AZURE_OPENAI_CHAT_DEPLOYMENT is required for Azure OpenAI") - # Create the Asynchronous Azure OpenAI client - bp.openai_client = AsyncAzureOpenAI( - api_version=os.getenv("AZURE_OPENAI_API_VERSION") or "2024-02-15-preview", - azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"), - azure_ad_token_provider=token_provider, + # Create the Asynchronous OpenAI client + bp.openai_client = AsyncOpenAI( + base_url=os.getenv("AZURE_OPENAI_ENDPOINT"), + api_key=token_provider, ) # Set the model name to the Azure OpenAI model deployment name bp.openai_model = os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT") diff --git a/src/requirements.txt b/src/requirements.txt index 9c3bd59e..b8cf3f40 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,15 +1,15 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile pyproject.toml +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --output-file=src/requirements.txt src/pyproject.toml # aiofiles==24.1.0 # via quart aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.12.15 - # via quartapp (pyproject.toml) +aiohttp==3.12.15 + # via quartapp (src/pyproject.toml) aiosignal==1.4.0 # via aiohttp annotated-types==0.7.0 @@ -24,7 +24,7 @@ attrs==25.3.0 azure-core==1.35.1 # via azure-identity azure-identity==1.25.0 - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) blinker==1.9.0 # via # flask @@ -57,26 +57,26 @@ frozenlist==1.7.0 # aiohttp # aiosignal gunicorn==23.0.0 - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) h11==0.16.0 # via # httpcore # hypercorn # uvicorn # wsproto -h2==4.3.0 - # via hypercorn -hpack==4.1.0 +h2==4.3.0 + # via hypercorn +hpack==4.1.0 # via h2 httpcore==1.0.9 # via httpx httptools==0.6.4 - # via quartapp (pyproject.toml) -httpx==0.28.1 + # via quartapp (src/pyproject.toml) +httpx==0.28.1 # via openai hypercorn==0.17.3 # via quart -hyperframe==6.1.0 +hyperframe==6.1.0 # via h2 idna==3.10 # via @@ -110,13 +110,13 @@ multidict==6.6.4 # via # aiohttp # yarl -openai==1.107.2 - # via quartapp (pyproject.toml) +openai==1.109.0 + # via quartapp (src/pyproject.toml) packaging==25.0 # via gunicorn priority==2.0.0 # via hypercorn -propcache==0.3.2 +propcache==0.3.2 # via # aiohttp # yarl @@ -126,16 +126,16 @@ pydantic==2.11.9 # via openai pydantic-core==2.33.2 # via pydantic -pyjwt[crypto]==2.10.1 - # via - # msal - # pyjwt -python-dotenv==1.1.1 - # via quartapp (pyproject.toml) +pyjwt[crypto]==2.10.1 + # via + # msal + # pyjwt +python-dotenv==1.1.1 + # via quartapp (src/pyproject.toml) pyyaml==6.0.2 - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) quart==0.20.0 - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) requests==2.32.5 # via # azure-core @@ -163,16 +163,16 @@ typing-inspection==0.4.1 urllib3==2.5.0 # via requests uvicorn==0.36.0 - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) uvloop==0.21.0 ; sys_platform != "win32" and (sys_platform != "cygwin" and platform_python_implementation != "PyPy") - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) watchfiles==1.1.0 - # via quartapp (pyproject.toml) + # via quartapp (src/pyproject.toml) werkzeug==3.1.3 # via # flask # quart - # quartapp (pyproject.toml) + # quartapp (src/pyproject.toml) wsproto==1.2.0 # via hypercorn yarl==1.20.1 diff --git a/tests/test_app.py b/tests/test_app.py index b8de7a65..f0d508ab 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -48,11 +48,10 @@ async def test_openai_managedidentity(monkeypatch): monkeypatch.setenv("AZURE_OPENAI_CLIENT_ID", "test-client-id") monkeypatch.setenv("AZURE_OPENAI_ENDPOINT", "test-openai-service.openai.azure.com") monkeypatch.setenv("AZURE_OPENAI_CHAT_DEPLOYMENT", "test-chatgpt") - monkeypatch.setenv("AZURE_OPENAI_VERSION", "2023-10-01-preview") monkeypatch.setattr("azure.identity.aio.ManagedIdentityCredential", mock_cred.MockAzureCredential) quart_app = quartapp.create_app(testing=True) async with quart_app.test_app(): - assert quart_app.blueprints["chat"].openai_client._azure_ad_token_provider is not None + assert quart_app.blueprints["chat"].openai_client.api_key is not None From 5fb0831fd12f37d54a09ebd19b4ed760d7561acb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Sep 2025 22:02:43 +0000 Subject: [PATCH 3/3] Clean up gitignore and finalize migration Co-authored-by: pamelafox <297042+pamelafox@users.noreply.github.com> --- .gitignore | 3 +++ =1.108.1 | 17 ----------------- 2 files changed, 3 insertions(+), 17 deletions(-) delete mode 100644 =1.108.1 diff --git a/.gitignore b/.gitignore index a9b542e9..1aec4f7a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ venv/ # Bicep build artifacts (exclude .json files except parameters) infra/**/*.json !infra/**/main.parameters.json + +# Pip artifacts and temporary files +=* diff --git a/=1.108.1 b/=1.108.1 deleted file mode 100644 index a43f52fb..00000000 --- a/=1.108.1 +++ /dev/null @@ -1,17 +0,0 @@ -Defaulting to user installation because normal site-packages is not writeable -Requirement already satisfied: openai in /home/runner/.local/lib/python3.12/site-packages (1.107.2) -Requirement already satisfied: anyio<5,>=3.5.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (4.10.0) -Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai) (1.9.0) -Requirement already satisfied: httpx<1,>=0.23.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (0.28.1) -Requirement already satisfied: jiter<1,>=0.4.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (0.10.0) -Requirement already satisfied: pydantic<3,>=1.9.0 in /home/runner/.local/lib/python3.12/site-packages (from openai) (2.11.9) -Requirement already satisfied: sniffio in /home/runner/.local/lib/python3.12/site-packages (from openai) (1.3.1) -Requirement already satisfied: tqdm>4 in /home/runner/.local/lib/python3.12/site-packages (from openai) (4.67.1) -Requirement already satisfied: typing-extensions<5,>=4.11 in /home/runner/.local/lib/python3.12/site-packages (from openai) (4.15.0) -Requirement already satisfied: idna>=2.8 in /home/runner/.local/lib/python3.12/site-packages (from anyio<5,>=3.5.0->openai) (3.10) -Requirement already satisfied: certifi in /home/runner/.local/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (2025.8.3) -Requirement already satisfied: httpcore==1.* in /home/runner/.local/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai) (1.0.9) -Requirement already satisfied: h11>=0.16 in /home/runner/.local/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai) (0.16.0) -Requirement already satisfied: annotated-types>=0.6.0 in /home/runner/.local/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (0.7.0) -Requirement already satisfied: pydantic-core==2.33.2 in /home/runner/.local/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (2.33.2) -Requirement already satisfied: typing-inspection>=0.4.0 in /home/runner/.local/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai) (0.4.1)