Skip to content

Commit d0a211f

Browse files
committed
Merge branch 'main' into refactor/shared-settings-component
2 parents 94a5fed + fa9a638 commit d0a211f

37 files changed

+1139
-1495
lines changed

.azdo/pipelines/azure-dev.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ steps:
101101
AZURE_SPEECH_SERVICE_RESOURCE_GROUP: $(AZURE_SPEECH_SERVICE_RESOURCE_GROUP)
102102
AZURE_SPEECH_SERVICE_LOCATION: $(AZURE_SPEECH_SERVICE_LOCATION)
103103
AZURE_SPEECH_SERVICE_SKU: $(AZURE_SPEECH_SERVICE_SKU)
104+
AZURE_SPEECH_SERVICE_VOICE: $(AZURE_SPEECH_SERVICE_VOICE)
104105
AZURE_KEY_VAULT_NAME: $(AZURE_KEY_VAULT_NAME)
105106
AZURE_USE_AUTHENTICATION: $(AZURE_USE_AUTHENTICATION)
106107
AZURE_ENFORCE_ACCESS_CONTROL: $(AZURE_ENFORCE_ACCESS_CONTROL)

.github/workflows/azure-dev.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ jobs:
8787
AZURE_SPEECH_SERVICE_RESOURCE_GROUP: ${{ vars.AZURE_SPEECH_RESOURCE_GROUP }}
8888
AZURE_SPEECH_SERVICE_LOCATION: ${{ vars.AZURE_SPEECH_SERVICE_LOCATION }}
8989
AZURE_SPEECH_SERVICE_SKU: ${{ vars.AZURE_SPEECH_SERVICE_SKU }}
90+
AZURE_SPEECH_SERVICE_VOICE: ${{ vars.AZURE_SPEECH_SERVICE_VOICE }}
9091
AZURE_KEY_VAULT_NAME: ${{ vars.AZURE_KEY_VAULT_NAME }}
9192
AZURE_USE_AUTHENTICATION: ${{ vars.AZURE_USE_AUTHENTICATION }}
9293
AZURE_ENFORCE_ACCESS_CONTROL: ${{ vars.AZURE_ENFORCE_ACCESS_CONTROL }}

.vscode/launch.json

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"version": "0.2.0",
66
"configurations": [
77
{
8-
"name": "Python: Quart",
8+
"name": "Backend (Python)",
99
"type": "debugpy",
1010
"request": "launch",
1111
"module": "quart",
@@ -22,18 +22,17 @@
2222
"-p 50505"
2323
],
2424
"console": "integratedTerminal",
25-
"justMyCode": false,
26-
"envFile": "${input:dotEnvFilePath}",
25+
"justMyCode": false
2726
},
2827
{
29-
"name": "Frontend: watch",
28+
"name": "Frontend",
3029
"type": "node-terminal",
3130
"request": "launch",
3231
"command": "npm run dev",
3332
"cwd": "${workspaceFolder}/app/frontend",
3433
},
3534
{
36-
"name": "Python: Debug Tests",
35+
"name": "Tests (Python)",
3736
"type": "debugpy",
3837
"request": "launch",
3938
"program": "${file}",
@@ -42,11 +41,11 @@
4241
"justMyCode": false
4342
}
4443
],
45-
"inputs": [
44+
"compounds": [
4645
{
47-
"id": "dotEnvFilePath",
48-
"type": "command",
49-
"command": "azure-dev.commands.getDotEnvFilePath"
46+
"name": "Frontend & Backend",
47+
"configurations": ["Backend (Python)", "Frontend"],
48+
"stopAll": true
5049
}
5150
]
5251
}

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,25 @@
1-
# ChatGPT-like app with your data using Azure OpenAI and Azure AI Search (Python)
1+
<!--
2+
---
3+
name: RAG chat app with your data (Python)
4+
description: Chat with your domain data using Azure OpenAI and Azure AI Search.
5+
languages:
6+
- python
7+
- typescript
8+
- bicep
9+
- azdeveloper
10+
products:
11+
- azure-openai
12+
- azure-cognitive-search
13+
- azure-app-service
14+
- azure
15+
page_type: sample
16+
urlFragment: azure-search-openai-demo
17+
---
18+
-->
19+
20+
# RAG chat app with Azure OpenAI and Azure AI Search (Python)
21+
22+
This solution creates a ChatGPT-like frontend experience over your own documents using RAG (Retrieval Augmented Generation). It uses Azure OpenAI Service to access GPT models, and Azure AI Search for data indexing and retrieval.
223

324
This solution's backend is written in Python. There are also [**JavaScript**](https://aka.ms/azai/js/code), [**.NET**](https://aka.ms/azai/net/code), and [**Java**](https://aka.ms/azai/java/code) samples based on this one. Learn more about [developing AI apps using Azure AI Services](https://aka.ms/azai).
425

app/backend/app.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ async def setup_clients():
420420
)
421421
AZURE_OPENAI_EMB_DEPLOYMENT = os.getenv("AZURE_OPENAI_EMB_DEPLOYMENT") if OPENAI_HOST.startswith("azure") else None
422422
AZURE_OPENAI_CUSTOM_URL = os.getenv("AZURE_OPENAI_CUSTOM_URL")
423+
# https://learn.microsoft.com/azure/ai-services/openai/api-version-deprecation#latest-ga-api-release
424+
AZURE_OPENAI_API_VERSION = os.getenv("AZURE_OPENAI_API_VERSION") or "2024-06-01"
423425
AZURE_VISION_ENDPOINT = os.getenv("AZURE_VISION_ENDPOINT", "")
424426
# Used only with non-Azure OpenAI deployments
425427
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
@@ -444,7 +446,7 @@ async def setup_clients():
444446

445447
AZURE_SPEECH_SERVICE_ID = os.getenv("AZURE_SPEECH_SERVICE_ID")
446448
AZURE_SPEECH_SERVICE_LOCATION = os.getenv("AZURE_SPEECH_SERVICE_LOCATION")
447-
AZURE_SPEECH_VOICE = os.getenv("AZURE_SPEECH_VOICE", "en-US-AndrewMultilingualNeural")
449+
AZURE_SPEECH_SERVICE_VOICE = os.getenv("AZURE_SPEECH_SERVICE_VOICE") or "en-US-AndrewMultilingualNeural"
448450

449451
USE_GPT4V = os.getenv("USE_GPT4V", "").lower() == "true"
450452
USE_USER_UPLOAD = os.getenv("USE_USER_UPLOAD", "").lower() == "true"
@@ -547,6 +549,7 @@ async def setup_clients():
547549
openai_custom_url=AZURE_OPENAI_CUSTOM_URL,
548550
openai_deployment=AZURE_OPENAI_EMB_DEPLOYMENT,
549551
openai_dimensions=OPENAI_EMB_DIMENSIONS,
552+
openai_api_version=AZURE_OPENAI_API_VERSION,
550553
openai_key=clean_key_if_exists(OPENAI_API_KEY),
551554
openai_org=OPENAI_ORGANIZATION,
552555
disable_vectors=os.getenv("USE_VECTORS", "").lower() == "false",
@@ -567,13 +570,12 @@ async def setup_clients():
567570
raise ValueError("Azure speech resource not configured correctly, missing AZURE_SPEECH_SERVICE_LOCATION")
568571
current_app.config[CONFIG_SPEECH_SERVICE_ID] = AZURE_SPEECH_SERVICE_ID
569572
current_app.config[CONFIG_SPEECH_SERVICE_LOCATION] = AZURE_SPEECH_SERVICE_LOCATION
570-
current_app.config[CONFIG_SPEECH_SERVICE_VOICE] = AZURE_SPEECH_VOICE
573+
current_app.config[CONFIG_SPEECH_SERVICE_VOICE] = AZURE_SPEECH_SERVICE_VOICE
571574
# Wait until token is needed to fetch for the first time
572575
current_app.config[CONFIG_SPEECH_SERVICE_TOKEN] = None
573576
current_app.config[CONFIG_CREDENTIAL] = azure_credential
574577

575578
if OPENAI_HOST.startswith("azure"):
576-
api_version = os.getenv("AZURE_OPENAI_API_VERSION") or "2024-03-01-preview"
577579
if OPENAI_HOST == "azure_custom":
578580
current_app.logger.info("OPENAI_HOST is azure_custom, setting up Azure OpenAI custom client")
579581
if not AZURE_OPENAI_CUSTOM_URL:
@@ -586,12 +588,14 @@ async def setup_clients():
586588
endpoint = f"https://{AZURE_OPENAI_SERVICE}.openai.azure.com"
587589
if api_key := os.getenv("AZURE_OPENAI_API_KEY_OVERRIDE"):
588590
current_app.logger.info("AZURE_OPENAI_API_KEY_OVERRIDE found, using as api_key for Azure OpenAI client")
589-
openai_client = AsyncAzureOpenAI(api_version=api_version, azure_endpoint=endpoint, api_key=api_key)
591+
openai_client = AsyncAzureOpenAI(
592+
api_version=AZURE_OPENAI_API_VERSION, azure_endpoint=endpoint, api_key=api_key
593+
)
590594
else:
591595
current_app.logger.info("Using Azure credential (passwordless authentication) for Azure OpenAI client")
592596
token_provider = get_bearer_token_provider(azure_credential, "https://cognitiveservices.azure.com/.default")
593597
openai_client = AsyncAzureOpenAI(
594-
api_version=api_version,
598+
api_version=AZURE_OPENAI_API_VERSION,
595599
azure_endpoint=endpoint,
596600
azure_ad_token_provider=token_provider,
597601
)

app/backend/prepdocs.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ def setup_embeddings_service(
115115
openai_custom_url: Union[str, None],
116116
openai_deployment: Union[str, None],
117117
openai_dimensions: int,
118+
openai_api_version: str,
118119
openai_key: Union[str, None],
119120
openai_org: Union[str, None],
120121
disable_vectors: bool = False,
@@ -134,6 +135,7 @@ def setup_embeddings_service(
134135
open_ai_deployment=openai_deployment,
135136
open_ai_model_name=openai_model_name,
136137
open_ai_dimensions=openai_dimensions,
138+
open_ai_api_version=openai_api_version,
137139
credential=azure_open_ai_credential,
138140
disable_batch=disable_batch_vectors,
139141
)
@@ -366,6 +368,8 @@ async def main(strategy: Strategy, setup_index: bool = True):
366368
openai_service=os.getenv("AZURE_OPENAI_SERVICE"),
367369
openai_custom_url=os.getenv("AZURE_OPENAI_CUSTOM_URL"),
368370
openai_deployment=os.getenv("AZURE_OPENAI_EMB_DEPLOYMENT"),
371+
# https://learn.microsoft.com/azure/ai-services/openai/api-version-deprecation#latest-ga-api-release
372+
openai_api_version=os.getenv("AZURE_OPENAI_API_VERSION") or "2024-06-01",
369373
openai_dimensions=openai_dimensions,
370374
openai_key=clean_key_if_exists(openai_key),
371375
openai_org=os.getenv("OPENAI_ORGANIZATION"),

app/backend/prepdocslib/embeddings.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def __init__(
163163
open_ai_deployment: Union[str, None],
164164
open_ai_model_name: str,
165165
open_ai_dimensions: int,
166+
open_ai_api_version: str,
166167
credential: Union[AsyncTokenCredential, AzureKeyCredential],
167168
open_ai_custom_url: Union[str, None] = None,
168169
disable_batch: bool = False,
@@ -176,6 +177,7 @@ def __init__(
176177
else:
177178
raise ValueError("Either open_ai_service or open_ai_custom_url must be provided")
178179
self.open_ai_deployment = open_ai_deployment
180+
self.open_ai_api_version = open_ai_api_version
179181
self.credential = credential
180182

181183
async def create_client(self) -> AsyncOpenAI:
@@ -196,7 +198,7 @@ class AuthArgs(TypedDict, total=False):
196198
return AsyncAzureOpenAI(
197199
azure_endpoint=self.open_ai_endpoint,
198200
azure_deployment=self.open_ai_deployment,
199-
api_version="2023-05-15",
201+
api_version=self.open_ai_api_version,
200202
**auth_args,
201203
)
202204

app/backend/requirements.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ python-dateutil==2.9.0.post0
350350
# time-machine
351351
python-dotenv==1.0.1
352352
# via -r requirements.in
353-
quart==0.19.6
353+
quart==0.19.7
354354
# via
355355
# -r requirements.in
356356
# quart-cors
@@ -403,6 +403,7 @@ typing-extensions==4.12.2
403403
# azure-ai-documentintelligence
404404
# azure-core
405405
# azure-identity
406+
# azure-search-documents
406407
# azure-storage-blob
407408
# azure-storage-file-datalake
408409
# openai
@@ -415,7 +416,7 @@ urllib3==2.2.2
415416
# via requests
416417
uvicorn==0.30.6
417418
# via -r requirements.in
418-
werkzeug==3.0.4
419+
werkzeug==3.0.6
419420
# via
420421
# flask
421422
# quart

0 commit comments

Comments
 (0)