Skip to content

Commit 5409392

Browse files
fix: dev to main - Private Networking for Web Apps, Improve CI Test Reporting, and Strengthen Error Handling
2 parents 3ba223d + c5b0c3d commit 5409392

84 files changed

Lines changed: 4330 additions & 4068 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ on:
3131
permissions:
3232
contents: read
3333
actions: read
34+
pull-requests: write
3435

3536
jobs:
3637
# frontend_tests:
@@ -106,7 +107,19 @@ jobs:
106107
- name: Run Backend Tests with Coverage
107108
if: env.skip_backend_tests == 'false'
108109
run: |
109-
pytest --cov=. --cov-report=term-missing --cov-report=xml ./src/tests/api
110+
pytest --cov=. --cov-report=term-missing --cov-report=xml --junitxml=pytest.xml ./src/tests/api
111+
112+
- name: Pytest Coverage Comment
113+
if: |
114+
always() &&
115+
github.event_name == 'pull_request' &&
116+
github.event.pull_request.head.repo.fork == false &&
117+
env.skip_backend_tests == 'false'
118+
uses: MishaKav/pytest-coverage-comment@26f986d2599c288bb62f623d29c2da98609e9cd4 # v1.6.0
119+
with:
120+
pytest-xml-coverage-path: coverage.xml
121+
junitxml-path: pytest.xml
122+
report-only-changed-files: true
110123

111124
- name: Skip Backend Tests
112125
if: env.skip_backend_tests == 'true'

azure.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ name: conversation-knowledge-mining
88

99
requiredVersions:
1010
azd: ">= 1.18.0 != 1.23.9"
11-
bicep: ">= 0.33.0"
1211

1312
metadata:
1413
template: conversation-knowledge-mining@1.0

docs/workshop/docs/workshop/Challenge-5/python/utility.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def schema_to_tool(schema: Any):
242242
return json.loads(
243243
assistant_message.tool_calls[0].function.arguments, strict=False
244244
)
245-
except:
245+
except Exception:
246246
return assistant_message.tool_calls[0].function.arguments
247247

248248
def get_structured_output_answer(
@@ -348,7 +348,6 @@ def generate_scenes(
348348
scene_generation_prompt = Template(SCENE_GENERATION_PROMPT).substitute(
349349
descriptions=next_segment_content
350350
)
351-
scence_response = VideoSceneResponse(scenes=[])
352351
scence_response = openai_assistant.get_structured_output_answer(
353352
"", scene_generation_prompt, VideoSceneResponse
354353
)
@@ -433,7 +432,6 @@ def generate_chapters(
433432
chapter_generation_prompt = Template(CHAPTER_GENERATION_PROMPT).substitute(
434433
descriptions=scene_descriptions
435434
)
436-
chapter_response = VideoChapterResponse(chapters=[])
437435
chapter_response = openai_assistant.get_structured_output_answer(
438436
"", chapter_generation_prompt, VideoChapterResponse
439437
)
@@ -460,7 +458,6 @@ def aggregate_tags(
460458
tags_dedup = set(map(lambda x: re.sub(r'^ ', '', x), tags))
461459
tag_dedup_prompt = Template(DEDUP_PROMPT).substitute(tag_list=tags_dedup)
462460

463-
tag_response = VideoTagResponse(tags=[])
464461
tag_response = openai_assistant.get_structured_output_answer(
465462
"", tag_dedup_prompt, VideoTagResponse
466463
)

infra/main.bicep

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ var privateDnsZones = [
445445
'privatelink.documents.azure.com'
446446
'privatelink${environment().suffixes.sqlServerHostname}'
447447
'privatelink.search.windows.net'
448+
'privatelink.azurewebsites.net'
448449
]
449450

450451
// DNS Zone Index Constants
@@ -459,6 +460,7 @@ var dnsZoneIndex = {
459460
cosmosDB: 7
460461
sqlServer: 8
461462
search: 9
463+
webApp: 10
462464
}
463465

464466
// ===================================================
@@ -1361,7 +1363,22 @@ module webSiteBackend 'modules/web-sites.bicep' = {
13611363
vnetRouteAllEnabled: enablePrivateNetworking ? true : false
13621364
vnetImagePullEnabled: enablePrivateNetworking ? true : false
13631365
virtualNetworkSubnetId: enablePrivateNetworking ? virtualNetwork!.outputs.webSubnetResourceId : null
1364-
publicNetworkAccess: 'Enabled'
1366+
publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled'
1367+
privateEndpoints: enablePrivateNetworking
1368+
? [
1369+
{
1370+
name: 'pep-${backendWebSiteResourceName}'
1371+
customNetworkInterfaceName: 'nic-${backendWebSiteResourceName}'
1372+
privateDnsZoneGroup: {
1373+
privateDnsZoneGroupConfigs: [
1374+
{ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.webApp]!.outputs.resourceId }
1375+
]
1376+
}
1377+
service: 'sites'
1378+
subnetResourceId: virtualNetwork!.outputs.pepsSubnetResourceId
1379+
}
1380+
]
1381+
: []
13651382
}
13661383
}
13671384

@@ -1388,7 +1405,8 @@ module webSiteFrontend 'modules/web-sites.bicep' = {
13881405
{
13891406
name: 'appsettings'
13901407
properties: {
1391-
APP_API_BASE_URL: 'https://api-${solutionSuffix}.azurewebsites.net'
1408+
APP_API_BASE_URL: enablePrivateNetworking ? '' : 'https://api-${solutionSuffix}.azurewebsites.net'
1409+
BACKEND_API_HOST: enablePrivateNetworking ? 'api-${solutionSuffix}.azurewebsites.net' : ''
13921410
}
13931411
applicationInsightResourceId: enableMonitoring ? applicationInsights!.outputs.resourceId : null
13941412
}

infra/main.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"_generator": {
77
"name": "bicep",
88
"version": "0.41.2.15936",
9-
"templateHash": "949305639975172329"
9+
"templateHash": "18133262101573574086"
1010
}
1111
},
1212
"parameters": {
@@ -408,7 +408,7 @@
408408
"sqlServerResourceName": "[format('sql-{0}', variables('solutionSuffix'))]",
409409
"sqlDbModuleName": "[format('sqldb-{0}', variables('solutionSuffix'))]",
410410
"webServerFarmResourceName": "[format('asp-{0}', variables('solutionSuffix'))]",
411-
"reactAppLayoutConfig": "{\r\n \"appConfig\": {\r\n \"THREE_COLUMN\": {\r\n \"DASHBOARD\": 50,\r\n \"CHAT\": 33,\r\n \"CHATHISTORY\": 17\r\n },\r\n \"TWO_COLUMN\": {\r\n \"DASHBOARD_CHAT\": {\r\n \"DASHBOARD\": 65,\r\n \"CHAT\": 35\r\n },\r\n \"CHAT_CHATHISTORY\": {\r\n \"CHAT\": 80,\r\n \"CHATHISTORY\": 20\r\n }\r\n }\r\n },\r\n \"charts\": [\r\n {\r\n \"id\": \"SATISFIED\",\r\n \"name\": \"Satisfied\",\r\n \"type\": \"card\",\r\n \"layout\": { \"row\": 1, \"column\": 1, \"height\": 11 }\r\n },\r\n {\r\n \"id\": \"TOTAL_CALLS\",\r\n \"name\": \"Total Calls\",\r\n \"type\": \"card\",\r\n \"layout\": { \"row\": 1, \"column\": 2, \"span\": 1 }\r\n },\r\n {\r\n \"id\": \"AVG_HANDLING_TIME\",\r\n \"name\": \"Average Handling Time\",\r\n \"type\": \"card\",\r\n \"layout\": { \"row\": 1, \"column\": 3, \"span\": 1 }\r\n },\r\n {\r\n \"id\": \"SENTIMENT\",\r\n \"name\": \"Topics Overview\",\r\n \"type\": \"donutchart\",\r\n \"layout\": { \"row\": 2, \"column\": 1, \"width\": 40, \"height\": 44.5 }\r\n },\r\n {\r\n \"id\": \"AVG_HANDLING_TIME_BY_TOPIC\",\r\n \"name\": \"Average Handling Time By Topic\",\r\n \"type\": \"bar\",\r\n \"layout\": { \"row\": 2, \"column\": 2, \"row-span\": 2, \"width\": 60 }\r\n },\r\n {\r\n \"id\": \"TOPICS\",\r\n \"name\": \"Trending Topics\",\r\n \"type\": \"table\",\r\n \"layout\": { \"row\": 3, \"column\": 1, \"span\": 2 }\r\n },\r\n {\r\n \"id\": \"KEY_PHRASES\",\r\n \"name\": \"Key Phrases\",\r\n \"type\": \"wordcloud\",\r\n \"layout\": { \"row\": 3, \"column\": 2, \"height\": 44.5 }\r\n }\r\n ]\r\n}",
411+
"reactAppLayoutConfig": "{\n \"appConfig\": {\n \"THREE_COLUMN\": {\n \"DASHBOARD\": 50,\n \"CHAT\": 33,\n \"CHATHISTORY\": 17\n },\n \"TWO_COLUMN\": {\n \"DASHBOARD_CHAT\": {\n \"DASHBOARD\": 65,\n \"CHAT\": 35\n },\n \"CHAT_CHATHISTORY\": {\n \"CHAT\": 80,\n \"CHATHISTORY\": 20\n }\n }\n },\n \"charts\": [\n {\n \"id\": \"SATISFIED\",\n \"name\": \"Satisfied\",\n \"type\": \"card\",\n \"layout\": { \"row\": 1, \"column\": 1, \"height\": 11 }\n },\n {\n \"id\": \"TOTAL_CALLS\",\n \"name\": \"Total Calls\",\n \"type\": \"card\",\n \"layout\": { \"row\": 1, \"column\": 2, \"span\": 1 }\n },\n {\n \"id\": \"AVG_HANDLING_TIME\",\n \"name\": \"Average Handling Time\",\n \"type\": \"card\",\n \"layout\": { \"row\": 1, \"column\": 3, \"span\": 1 }\n },\n {\n \"id\": \"SENTIMENT\",\n \"name\": \"Topics Overview\",\n \"type\": \"donutchart\",\n \"layout\": { \"row\": 2, \"column\": 1, \"width\": 40, \"height\": 44.5 }\n },\n {\n \"id\": \"AVG_HANDLING_TIME_BY_TOPIC\",\n \"name\": \"Average Handling Time By Topic\",\n \"type\": \"bar\",\n \"layout\": { \"row\": 2, \"column\": 2, \"row-span\": 2, \"width\": 60 }\n },\n {\n \"id\": \"TOPICS\",\n \"name\": \"Trending Topics\",\n \"type\": \"table\",\n \"layout\": { \"row\": 3, \"column\": 1, \"span\": 2 }\n },\n {\n \"id\": \"KEY_PHRASES\",\n \"name\": \"Key Phrases\",\n \"type\": \"wordcloud\",\n \"layout\": { \"row\": 3, \"column\": 2, \"height\": 44.5 }\n }\n ]\n}",
412412
"backendWebSiteResourceName": "[format('api-{0}', variables('solutionSuffix'))]",
413413
"webSiteResourceName": "[format('app-{0}', variables('solutionSuffix'))]"
414414
},
@@ -28296,9 +28296,9 @@
2829628296
},
2829728297
"dependsOn": [
2829828298
"aiFoundryAiServices",
28299-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
28300-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]",
2830128299
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]",
28300+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]",
28301+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
2830228302
"virtualNetwork"
2830328303
]
2830428304
},
@@ -41907,10 +41907,10 @@
4190741907
}
4190841908
},
4190941909
"dependsOn": [
41910-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]",
41911-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]",
41912-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageDfs)]",
4191341910
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]",
41911+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageDfs)]",
41912+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]",
41913+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]",
4191441914
"userAssignedIdentity",
4191541915
"virtualNetwork"
4191641916
]

infra/main_custom.bicep

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ var privateDnsZones = [
446446
'privatelink.documents.azure.com'
447447
'privatelink${environment().suffixes.sqlServerHostname}'
448448
'privatelink.search.windows.net'
449+
'privatelink.azurewebsites.net'
449450
]
450451

451452
// DNS Zone Index Constants
@@ -460,6 +461,7 @@ var dnsZoneIndex = {
460461
cosmosDB: 7
461462
sqlServer: 8
462463
search: 9
464+
webApp: 10
463465
}
464466

465467
// ===================================================
@@ -1363,7 +1365,22 @@ module webSiteBackend 'modules/web-sites.bicep' = {
13631365
vnetRouteAllEnabled: enablePrivateNetworking ? true : false
13641366
vnetImagePullEnabled: enablePrivateNetworking ? true : false
13651367
virtualNetworkSubnetId: enablePrivateNetworking ? virtualNetwork!.outputs.webSubnetResourceId : null
1366-
publicNetworkAccess: 'Enabled'
1368+
publicNetworkAccess: enablePrivateNetworking ? 'Disabled' : 'Enabled'
1369+
privateEndpoints: enablePrivateNetworking
1370+
? [
1371+
{
1372+
name: 'pep-${backendWebSiteResourceName}'
1373+
customNetworkInterfaceName: 'nic-${backendWebSiteResourceName}'
1374+
privateDnsZoneGroup: {
1375+
privateDnsZoneGroupConfigs: [
1376+
{ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.webApp]!.outputs.resourceId }
1377+
]
1378+
}
1379+
service: 'sites'
1380+
subnetResourceId: virtualNetwork!.outputs.pepsSubnetResourceId
1381+
}
1382+
]
1383+
: []
13671384
}
13681385
}
13691386

@@ -1391,9 +1408,10 @@ module webSiteFrontend 'modules/web-sites.bicep' = {
13911408
properties: {
13921409
SCM_DO_BUILD_DURING_DEPLOYMENT: 'true'
13931410
ENABLE_ORYX_BUILD: 'true'
1394-
REACT_APP_API_BASE_URL: 'https://api-${solutionSuffix}.azurewebsites.net'
1411+
REACT_APP_API_BASE_URL: enablePrivateNetworking ? '' : 'https://api-${solutionSuffix}.azurewebsites.net'
13951412
WEBSITE_NODE_DEFAULT_VERSION: '~20'
1396-
APP_API_BASE_URL: 'https://api-${solutionSuffix}.azurewebsites.net'
1413+
APP_API_BASE_URL: enablePrivateNetworking ? '' : 'https://api-${solutionSuffix}.azurewebsites.net'
1414+
BACKEND_API_HOST: enablePrivateNetworking ? 'api-${solutionSuffix}.azurewebsites.net' : ''
13971415
}
13981416
applicationInsightResourceId: enableMonitoring ? applicationInsights!.outputs.resourceId : null
13991417
}

infra/scripts/fabric_scripts/create_fabric_items.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from azure.identity import ManagedIdentityCredential
21
import base64
32
import json
43
import requests
5-
import pandas as pd
64
import os
75
from glob import iglob
86
import zipfile
@@ -98,11 +96,11 @@
9896
# upload extracted folder
9997
file_names = [f for f in iglob(os.path.join(local_path, "**", "*"), recursive=True) if os.path.isfile(f)]
10098
# print('file_names ex', file_names)
101-
for file_name in file_names:
102-
upload_file_name = os.path.basename(file_name)
99+
for extracted_file in file_names:
100+
upload_file_name = os.path.basename(extracted_file)
103101
file_client = directory_client.get_file_client("cu_audio_files_all/" + upload_file_name)
104-
# with open(file=os.path.join(extract_dir, file_name), mode="rb") as data:
105-
with open(file=file_name, mode="rb") as data:
102+
# with open(file=os.path.join(extract_dir, extracted_file), mode="rb") as data:
103+
with open(file=extracted_file, mode="rb") as data:
106104
# print('data', data)
107105
file_client.upload_data(data, overwrite=True)
108106

@@ -127,7 +125,7 @@
127125
env_res = requests.get(fabric_env_url, headers=fabric_headers)
128126
env_res_id = env_res.json()['value'][0]['id']
129127
# print(env_res.json())
130-
except:
128+
except Exception: # Environments may not be provisioned yet
131129
env_res_id = ''
132130

133131
#create notebook items
@@ -150,14 +148,14 @@
150148
notebook_json['metadata']['dependencies']['lakehouse']['default_lakehouse'] = lakehouse_res.json()['id']
151149
notebook_json['metadata']['dependencies']['lakehouse']['default_lakehouse_name'] = lakehouse_res.json()['displayName']
152150
notebook_json['metadata']['dependencies']['lakehouse']['default_lakehouse_workspace_id'] = lakehouse_res.json()['workspaceId']
153-
except:
151+
except Exception: # Lakehouse metadata may not be available
154152
pass
155153

156154
if env_res_id != '':
157155
try:
158156
notebook_json['metadata']['dependencies']['environment']['environmentId'] = env_res_id
159157
notebook_json['metadata']['dependencies']['environment']['workspaceId'] = lakehouse_res.json()['workspaceId']
160-
except:
158+
except Exception: # Environment metadata may not be available
161159
pass
162160

163161

@@ -178,8 +176,7 @@
178176
}
179177
}
180178

181-
fabric_response = requests.post(fabric_items_url, headers=fabric_headers, json=notebook_data)
182-
#print(fabric_response.json())
179+
requests.post(fabric_items_url, headers=fabric_headers, json=notebook_data)
183180

184181
time.sleep(120)
185182

infra/scripts/index_scripts/02_create_cu_template_audio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
analyzer = client.get_analyzer_detail_by_id(ANALYZER_ID)
3737
if analyzer is not None:
3838
client.delete_analyzer(ANALYZER_ID)
39-
except Exception:
39+
except Exception: # Analyzer may not exist yet, safe to ignore
4040
pass
4141

4242
response = client.begin_create_analyzer(ANALYZER_ID, analyzer_template_path=ANALYZER_TEMPLATE_FILE)

infra/scripts/index_scripts/02_create_cu_template_text.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
analyzer = client.get_analyzer_detail_by_id(ANALYZER_ID)
3232
if analyzer is not None:
3333
client.delete_analyzer(ANALYZER_ID)
34-
except Exception:
34+
except Exception: # Analyzer may not exist yet, safe to ignore
3535
pass
3636

3737
response = client.begin_create_analyzer(ANALYZER_ID, analyzer_template_path=ANALYZER_TEMPLATE_FILE)

infra/scripts/index_scripts/03_cu_process_data_text.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,10 @@ async def process_files():
381381

382382
docs.extend(await prepare_search_doc(content, conversation_id, path.name, embeddings_client))
383383
counter += 1
384-
except Exception:
384+
except Exception: # Skip files that fail processing
385385
pass
386386
if docs != [] and counter % 10 == 0:
387-
result = search_client.upload_documents(documents=docs)
387+
search_client.upload_documents(documents=docs)
388388
docs = []
389389
if docs:
390390
search_client.upload_documents(documents=docs)
@@ -533,7 +533,6 @@ async def call_topic_mining_agent(topics_str1):
533533
column_names = [i[0] for i in cursor.description]
534534
df_topics = pd.DataFrame(rows, columns=column_names)
535535
mined_topics_list = df_topics['label'].tolist()
536-
mined_topics = ", ".join(mined_topics_list)
537536
print(f"✓ Mined {len(mined_topics_list)} topics")
538537

539538
async def call_topic_mapping_agent(agent, input_text, list_of_topics):

0 commit comments

Comments
 (0)