Skip to content

Commit aa2f281

Browse files
Copilotpamelafox
andcommitted
Complete AzureOpenAI to OpenAI migration
Co-authored-by: pamelafox <[email protected]>
1 parent 5667a82 commit aa2f281

File tree

10 files changed

+56
-59
lines changed

10 files changed

+56
-59
lines changed

.env.sample

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ OPENAI_EMBED_HOST=azure
1212
# Needed for Azure:
1313
# You also need to `azd auth login` if running this locally
1414
AZURE_OPENAI_ENDPOINT=https://YOUR-AZURE-OPENAI-SERVICE-NAME.openai.azure.com
15-
AZURE_OPENAI_VERSION=2024-03-01-preview
1615
AZURE_OPENAI_CHAT_DEPLOYMENT=gpt-4o-mini
1716
AZURE_OPENAI_CHAT_MODEL=gpt-4o-mini
1817
AZURE_OPENAI_EMBED_DEPLOYMENT=text-embedding-3-large

evals/generate_ground_truth.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
import os
44
from collections.abc import Generator
55
from pathlib import Path
6-
from typing import Union
76

87
from azure.identity import AzureDeveloperCliCredential, get_bearer_token_provider
98
from dotenv_azd import load_azd_env
10-
from openai import AzureOpenAI, OpenAI
9+
from openai import OpenAI
1110
from openai.types.chat import ChatCompletionToolParam
1211
from sqlalchemy import create_engine, select
1312
from sqlalchemy.orm import Session
@@ -78,26 +77,32 @@ def answer_formatter(answer, source) -> str:
7877
return f"{answer} [{source['id']}]"
7978

8079

81-
def get_openai_client() -> tuple[Union[AzureOpenAI, OpenAI], str]:
80+
def get_openai_client() -> tuple[OpenAI, str]:
8281
"""Return an OpenAI client based on the environment variables"""
83-
openai_client: Union[AzureOpenAI, OpenAI]
82+
openai_client: OpenAI
8483
OPENAI_CHAT_HOST = os.getenv("OPENAI_CHAT_HOST")
8584
if OPENAI_CHAT_HOST == "azure":
8685
if api_key := os.getenv("AZURE_OPENAI_KEY"):
8786
logger.info("Using Azure OpenAI Service with API Key from AZURE_OPENAI_KEY")
88-
openai_client = AzureOpenAI(
89-
api_version=os.environ["AZURE_OPENAI_VERSION"],
90-
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
87+
azure_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
88+
azure_deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]
89+
api_version = "2024-10-21"
90+
openai_client = OpenAI(
91+
base_url=f"{azure_endpoint.rstrip('/')}/openai/deployments/{azure_deployment}?api-version={api_version}",
9192
api_key=api_key,
9293
)
9394
else:
9495
logger.info("Using Azure OpenAI Service with Azure Developer CLI Credential")
9596
azure_credential = AzureDeveloperCliCredential(process_timeout=60, tenant_id=os.environ["AZURE_TENANT_ID"])
9697
token_provider = get_bearer_token_provider(azure_credential, "https://cognitiveservices.azure.com/.default")
97-
openai_client = AzureOpenAI(
98-
api_version=os.environ["AZURE_OPENAI_VERSION"],
99-
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
100-
azure_ad_token_provider=token_provider,
98+
azure_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
99+
azure_deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]
100+
api_version = "2024-10-21"
101+
# Get the initial token from the provider
102+
initial_token = token_provider()
103+
openai_client = OpenAI(
104+
base_url=f"{azure_endpoint.rstrip('/')}/openai/deployments/{azure_deployment}?api-version={api_version}",
105+
api_key=initial_token,
101106
)
102107
model = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]
103108
elif OPENAI_CHAT_HOST == "ollama":

infra/main.bicep

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,6 @@ var webAppEnv = union(azureOpenAIKeyEnv, openAIComKeyEnv, [
325325
name: 'AZURE_OPENAI_ENDPOINT'
326326
value: !empty(azureOpenAIEndpoint) ? azureOpenAIEndpoint : (deployAzureOpenAI ? openAI.outputs.endpoint : '')
327327
}
328-
{
329-
name: 'AZURE_OPENAI_VERSION'
330-
value: openAIChatHost == 'azure' ? azureOpenAIAPIVersion : ''
331-
}
332328
])
333329

334330
module web 'web.bicep' = {
@@ -553,7 +549,6 @@ output AZURE_OPENAI_RESOURCE_GROUP string = deployAzureOpenAI ? openAIResourceGr
553549
output AZURE_OPENAI_ENDPOINT string = !empty(azureOpenAIEndpoint)
554550
? azureOpenAIEndpoint
555551
: (deployAzureOpenAI ? openAI.outputs.endpoint : '')
556-
output AZURE_OPENAI_VERSION string = azureOpenAIAPIVersion
557552
output AZURE_OPENAI_CHAT_DEPLOYMENT string = deployAzureOpenAI ? chatDeploymentName : ''
558553
output AZURE_OPENAI_CHAT_DEPLOYMENT_VERSION string = deployAzureOpenAI ? chatDeploymentVersion : ''
559554
output AZURE_OPENAI_CHAT_DEPLOYMENT_CAPACITY int = deployAzureOpenAI ? chatDeploymentCapacity : 0

src/backend/fastapi_app/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
import os
33
from collections.abc import AsyncIterator
44
from contextlib import asynccontextmanager
5-
from typing import TypedDict, Union
5+
from typing import TypedDict
66

77
import fastapi
88
from azure.monitor.opentelemetry import configure_azure_monitor
99
from dotenv import load_dotenv
10-
from openai import AsyncAzureOpenAI, AsyncOpenAI
10+
from openai import AsyncOpenAI
1111
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
1212
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
1313
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
@@ -27,8 +27,8 @@
2727
class State(TypedDict):
2828
sessionmaker: async_sessionmaker[AsyncSession]
2929
context: FastAPIAppContext
30-
chat_client: Union[AsyncOpenAI, AsyncAzureOpenAI]
31-
embed_client: Union[AsyncOpenAI, AsyncAzureOpenAI]
30+
chat_client: AsyncOpenAI
31+
embed_client: AsyncOpenAI
3232

3333

3434
@asynccontextmanager

src/backend/fastapi_app/dependencies.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import azure.identity
77
from fastapi import Depends, Request
8-
from openai import AsyncAzureOpenAI, AsyncOpenAI
8+
from openai import AsyncOpenAI
99
from pydantic import BaseModel
1010
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
1111

@@ -17,7 +17,7 @@ class OpenAIClient(BaseModel):
1717
OpenAI client
1818
"""
1919

20-
client: Union[AsyncOpenAI, AsyncAzureOpenAI]
20+
client: AsyncOpenAI
2121
model_config = {"arbitrary_types_allowed": True}
2222

2323

src/backend/fastapi_app/embeddings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from typing import Optional, TypedDict, Union
1+
from typing import Optional, TypedDict
22

3-
from openai import AsyncAzureOpenAI, AsyncOpenAI
3+
from openai import AsyncOpenAI
44

55

66
async def compute_text_embedding(
77
q: str,
8-
openai_client: Union[AsyncOpenAI, AsyncAzureOpenAI],
8+
openai_client: AsyncOpenAI,
99
embed_model: str,
1010
embed_deployment: Optional[str] = None,
1111
embedding_dimensions: Optional[int] = None,

src/backend/fastapi_app/openai_clients.py

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,22 @@
1010

1111
async def create_openai_chat_client(
1212
azure_credential: Union[azure.identity.AzureDeveloperCliCredential, azure.identity.ManagedIdentityCredential, None],
13-
) -> Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]:
14-
openai_chat_client: Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]
13+
) -> openai.AsyncOpenAI:
14+
openai_chat_client: openai.AsyncOpenAI
1515
OPENAI_CHAT_HOST = os.getenv("OPENAI_CHAT_HOST")
1616
if OPENAI_CHAT_HOST == "azure":
17-
api_version = os.environ["AZURE_OPENAI_VERSION"] or "2024-10-21"
1817
azure_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
1918
azure_deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]
19+
# Use default API version for Azure OpenAI
20+
api_version = "2024-10-21"
2021
if api_key := os.getenv("AZURE_OPENAI_KEY"):
2122
logger.info(
2223
"Setting up Azure OpenAI client for chat completions using API key, endpoint %s, deployment %s",
2324
azure_endpoint,
2425
azure_deployment,
2526
)
26-
openai_chat_client = openai.AsyncAzureOpenAI(
27-
api_version=api_version,
28-
azure_endpoint=azure_endpoint,
29-
azure_deployment=azure_deployment,
27+
openai_chat_client = openai.AsyncOpenAI(
28+
base_url=f"{azure_endpoint.rstrip('/')}/openai/deployments/{azure_deployment}?api-version={api_version}",
3029
api_key=api_key,
3130
)
3231
elif azure_credential:
@@ -38,11 +37,11 @@ async def create_openai_chat_client(
3837
token_provider = azure.identity.get_bearer_token_provider(
3938
azure_credential, "https://cognitiveservices.azure.com/.default"
4039
)
41-
openai_chat_client = openai.AsyncAzureOpenAI(
42-
api_version=api_version,
43-
azure_endpoint=azure_endpoint,
44-
azure_deployment=azure_deployment,
45-
azure_ad_token_provider=token_provider,
40+
# Get the initial token from the provider
41+
initial_token = token_provider()
42+
openai_chat_client = openai.AsyncOpenAI(
43+
base_url=f"{azure_endpoint.rstrip('/')}/openai/deployments/{azure_deployment}?api-version={api_version}",
44+
api_key=initial_token,
4645
)
4746
else:
4847
raise ValueError("Azure OpenAI client requires either an API key or Azure Identity credential.")
@@ -69,23 +68,22 @@ async def create_openai_chat_client(
6968

7069
async def create_openai_embed_client(
7170
azure_credential: Union[azure.identity.AzureDeveloperCliCredential, azure.identity.ManagedIdentityCredential, None],
72-
) -> Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]:
73-
openai_embed_client: Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]
71+
) -> openai.AsyncOpenAI:
72+
openai_embed_client: openai.AsyncOpenAI
7473
OPENAI_EMBED_HOST = os.getenv("OPENAI_EMBED_HOST")
7574
if OPENAI_EMBED_HOST == "azure":
76-
api_version = os.environ["AZURE_OPENAI_VERSION"] or "2024-03-01-preview"
7775
azure_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]
7876
azure_deployment = os.environ["AZURE_OPENAI_EMBED_DEPLOYMENT"]
77+
# Use default API version for Azure OpenAI
78+
api_version = "2024-03-01-preview"
7979
if api_key := os.getenv("AZURE_OPENAI_KEY"):
8080
logger.info(
8181
"Setting up Azure OpenAI client for embeddings using API key, endpoint %s, deployment %s",
8282
azure_endpoint,
8383
azure_deployment,
8484
)
85-
openai_embed_client = openai.AsyncAzureOpenAI(
86-
api_version=api_version,
87-
azure_endpoint=azure_endpoint,
88-
azure_deployment=azure_deployment,
85+
openai_embed_client = openai.AsyncOpenAI(
86+
base_url=f"{azure_endpoint.rstrip('/')}/openai/deployments/{azure_deployment}?api-version={api_version}",
8987
api_key=api_key,
9088
)
9189
elif azure_credential:
@@ -97,11 +95,11 @@ async def create_openai_embed_client(
9795
token_provider = azure.identity.get_bearer_token_provider(
9896
azure_credential, "https://cognitiveservices.azure.com/.default"
9997
)
100-
openai_embed_client = openai.AsyncAzureOpenAI(
101-
api_version=api_version,
102-
azure_endpoint=azure_endpoint,
103-
azure_deployment=azure_deployment,
104-
azure_ad_token_provider=token_provider,
98+
# Get the initial token from the provider
99+
initial_token = token_provider()
100+
openai_embed_client = openai.AsyncOpenAI(
101+
base_url=f"{azure_endpoint.rstrip('/')}/openai/deployments/{azure_deployment}?api-version={api_version}",
102+
api_key=initial_token,
105103
)
106104
else:
107105
raise ValueError("Azure OpenAI client requires either an API key or Azure Identity credential.")

src/backend/fastapi_app/postgres_searcher.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from typing import Optional, Union
1+
from typing import Optional
22

33
import numpy as np
4-
from openai import AsyncAzureOpenAI, AsyncOpenAI
4+
from openai import AsyncOpenAI
55
from sqlalchemy import Float, Integer, column, select, text
66
from sqlalchemy.ext.asyncio import AsyncSession
77

@@ -14,7 +14,7 @@ class PostgresSearcher:
1414
def __init__(
1515
self,
1616
db_session: AsyncSession,
17-
openai_embed_client: Union[AsyncOpenAI, AsyncAzureOpenAI],
17+
openai_embed_client: AsyncOpenAI,
1818
embed_deployment: Optional[str], # Not needed for non-Azure OpenAI or for retrieval_mode="text"
1919
embed_model: str,
2020
embed_dimensions: Optional[int],

src/backend/fastapi_app/rag_advanced.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
22
from collections.abc import AsyncGenerator
3-
from typing import Optional, Union
3+
from typing import Optional
44

55
from agents import (
66
Agent,
@@ -12,7 +12,7 @@
1212
function_tool,
1313
set_tracing_disabled,
1414
)
15-
from openai import AsyncAzureOpenAI, AsyncOpenAI
15+
from openai import AsyncOpenAI
1616
from openai.types.responses import EasyInputMessageParam, ResponseInputItemParam, ResponseTextDeltaEvent
1717

1818
from fastapi_app.api_models import (
@@ -45,7 +45,7 @@ def __init__(
4545
messages: list[ResponseInputItemParam],
4646
overrides: ChatRequestOverrides,
4747
searcher: PostgresSearcher,
48-
openai_chat_client: Union[AsyncOpenAI, AsyncAzureOpenAI],
48+
openai_chat_client: AsyncOpenAI,
4949
chat_model: str,
5050
chat_deployment: Optional[str], # Not needed for non-Azure OpenAI
5151
):

src/backend/fastapi_app/rag_simple.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from collections.abc import AsyncGenerator
2-
from typing import Optional, Union
2+
from typing import Optional
33

44
from agents import Agent, ItemHelpers, ModelSettings, OpenAIChatCompletionsModel, Runner, set_tracing_disabled
5-
from openai import AsyncAzureOpenAI, AsyncOpenAI
5+
from openai import AsyncOpenAI
66
from openai.types.responses import ResponseInputItemParam, ResponseTextDeltaEvent
77

88
from fastapi_app.api_models import (
@@ -28,7 +28,7 @@ def __init__(
2828
messages: list[ResponseInputItemParam],
2929
overrides: ChatRequestOverrides,
3030
searcher: PostgresSearcher,
31-
openai_chat_client: Union[AsyncOpenAI, AsyncAzureOpenAI],
31+
openai_chat_client: AsyncOpenAI,
3232
chat_model: str,
3333
chat_deployment: Optional[str], # Not needed for non-Azure OpenAI
3434
):

0 commit comments

Comments
 (0)