Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,17 @@
"video_indexer_endpoint": "https://api.videoindexer.ai",
"video_indexer_location": "",
"video_indexer_account_id": "",
"video_indexer_api_key": "",
"video_indexer_resource_group": "",
"video_indexer_subscription_id": "",
"video_indexer_account_name": "",
"video_indexer_arm_api_version": "2021-11-10-preview",
"video_indexer_arm_api_version": "2025-04-01",
"video_index_timeout": 600,
"speech_service_endpoint": "https://eastus.api.cognitive.microsoft.com",
"speech_service_location": "eastus",
"speech_service_subscription_id": "",
"speech_service_resource_group": "",
"speech_service_resource_name": "",
"speech_service_resource_id": "",
"speech_service_locale": "en-US",
"speech_service_key": "",
"classification_banner_enabled": true,
Expand Down
2 changes: 1 addition & 1 deletion application/single_app/functions_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def get_video_indexer_managed_identity_token(settings, video_id=None):
rg = settings["video_indexer_resource_group"]
sub = settings["video_indexer_subscription_id"]
acct = settings["video_indexer_account_name"]
api_ver = settings.get("video_indexer_arm_api_version", "2021-11-10-preview")
api_ver = settings.get("video_indexer_arm_api_version", DEFAULT_VIDEO_INDEXER_ARM_API_VERSION)

debug_print(f"[VIDEO INDEXER AUTH] Settings extracted - Subscription: {sub}, Resource Group: {rg}, Account: {acct}, API Version: {api_ver}")

Expand Down
28 changes: 28 additions & 0 deletions application/single_app/functions_documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -6242,6 +6242,34 @@ def _get_speech_config(settings, endpoint: str, locale: str):
print(f"[Debug] Speech config obtained successfully", flush=True)
return speech_config


def get_speech_synthesis_config(settings, endpoint: str, location: str):
"""Get speech synthesis config for either key or managed identity auth."""
auth_type = settings.get("speech_service_authentication_type")

if auth_type == "managed_identity":
resource_id = (settings.get("speech_service_resource_id") or "").strip()
if not location:
raise ValueError("Speech service location is required for text-to-speech with managed identity.")
if not resource_id:
raise ValueError("Speech service resource ID is required for text-to-speech with managed identity.")

credential = DefaultAzureCredential()
token = credential.get_token(cognitive_services_scope)
authorization_token = f"aad#{resource_id}#{token.token}"
speech_config = speechsdk.SpeechConfig(auth_token=authorization_token, region=location)
else:
key = (settings.get("speech_service_key") or "").strip()
if not endpoint:
raise ValueError("Speech service endpoint is required for text-to-speech.")
if not key:
raise ValueError("Speech service key is required for text-to-speech when using key authentication.")

speech_config = speechsdk.SpeechConfig(endpoint=endpoint, subscription=key)

print(f"[Debug] Speech synthesis config obtained successfully", flush=True)
return speech_config

def process_audio_document(
document_id: str,
user_id: str,
Expand Down
4 changes: 4 additions & 0 deletions application/single_app/functions_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,10 @@ def get_settings(use_cosmos=False, include_source=False):
# Audio file settings with Azure speech service
"speech_service_endpoint": '',
"speech_service_location": '',
"speech_service_subscription_id": '',
"speech_service_resource_group": '',
"speech_service_resource_name": '',
"speech_service_resource_id": '',
"speech_service_locale": "en-US",
"speech_service_key": "",
"speech_service_authentication_type": "key", # 'key' or 'managed_identity'
Expand Down
4 changes: 2 additions & 2 deletions application/single_app/route_backend_chats.py
Original file line number Diff line number Diff line change
Expand Up @@ -3922,15 +3922,15 @@ def get_tabular_result_coverage_summary(invocations):
if total_matches is not None and returned_rows is not None:
if returned_rows >= total_matches:
coverage_summary['has_full_result_coverage'] = True
elif returned_rows < total_matches:
else:
coverage_summary['has_partial_result_coverage'] = True

distinct_count = parse_tabular_result_count(result_payload.get('distinct_count'))
returned_values = parse_tabular_result_count(result_payload.get('returned_values'))
if distinct_count is not None and returned_values is not None:
if returned_values >= distinct_count:
coverage_summary['has_full_result_coverage'] = True
elif returned_values < distinct_count:
else:
coverage_summary['has_partial_result_coverage'] = True

if result_payload.get('full_rows_included') or result_payload.get('full_values_included'):
Expand Down
34 changes: 25 additions & 9 deletions application/single_app/route_backend_tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from config import *
from functions_authentication import *
from functions_appinsights import log_event
from functions_documents import get_speech_synthesis_config
from functions_settings import *
from functions_debug import debug_print
from swagger_wrapper import swagger_route, get_auth_security
Expand Down Expand Up @@ -41,14 +43,26 @@ def synthesize_speech():
return jsonify({"error": "Text-to-speech is not enabled"}), 403

# Validate speech service configuration
speech_key = settings.get('speech_service_key', '')
speech_region = settings.get('speech_service_location', '')
speech_endpoint = (settings.get('speech_service_endpoint') or '').strip().rstrip('/')
speech_region = (settings.get('speech_service_location') or '').strip()
speech_auth_type = settings.get('speech_service_authentication_type', 'key')

if not speech_key or not speech_region:
debug_print("[TTS] Speech service not configured - missing key or region")
if not speech_endpoint:
debug_print("[TTS] Speech service not configured - missing endpoint")
return jsonify({"error": "Speech service not configured"}), 500

if speech_auth_type == 'key' and not (settings.get('speech_service_key') or '').strip():
debug_print("[TTS] Speech service not configured - missing key for key authentication")
return jsonify({"error": "Speech service not configured"}), 500

if speech_auth_type == 'managed_identity' and not speech_region:
debug_print("[TTS] Speech service not configured - missing location for managed identity")
return jsonify({"error": "Speech service not configured"}), 500

debug_print(f"[TTS] Speech service configured - region: {speech_region}")
debug_print(
f"[TTS] Speech service configured - auth_type: {speech_auth_type}, "
f"endpoint: {speech_endpoint}, location: {speech_region or 'n/a'}"
)

# Parse request data
data = request.get_json()
Expand All @@ -71,10 +85,12 @@ def synthesize_speech():
debug_print(f"[TTS] Request params - voice: {voice}, speed: {speed}, text_length: {len(text)}")

# Configure speech service
speech_config = speechsdk.SpeechConfig(
subscription=speech_key,
region=speech_region
)
try:
speech_config = get_speech_synthesis_config(settings, speech_endpoint, speech_region)
except ValueError as config_error:
debug_print(f"[TTS] Speech service configuration invalid: {str(config_error)}")
return jsonify({"error": str(config_error)}), 500

speech_config.speech_synthesis_voice_name = voice

# Set output format to high quality
Expand Down
9 changes: 8 additions & 1 deletion application/single_app/route_frontend_admin_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ def admin_settings():
'admin_settings.html',
app_settings=settings_for_template,
settings=settings_for_template,
azure_environment=AZURE_ENVIRONMENT,
default_video_indexer_endpoint=video_indexer_endpoint,
default_video_indexer_arm_api_version=DEFAULT_VIDEO_INDEXER_ARM_API_VERSION,
user_settings=user_settings,
update_available=update_available,
latest_version=latest_version,
Expand Down Expand Up @@ -1325,12 +1328,16 @@ def is_valid_url(url):
'video_indexer_resource_group': form_data.get('video_indexer_resource_group', '').strip(),
'video_indexer_subscription_id': form_data.get('video_indexer_subscription_id', '').strip(),
'video_indexer_account_name': form_data.get('video_indexer_account_name', '').strip(),
'video_indexer_arm_api_version': form_data.get('video_indexer_arm_api_version', '2024-01-01').strip(),
'video_indexer_arm_api_version': form_data.get('video_indexer_arm_api_version', DEFAULT_VIDEO_INDEXER_ARM_API_VERSION).strip(),
'video_index_timeout': int(form_data.get('video_index_timeout', 600)),

# Audio file settings with Azure speech service
'speech_service_endpoint': form_data.get('speech_service_endpoint', '').strip(),
'speech_service_location': form_data.get('speech_service_location', '').strip(),
'speech_service_subscription_id': form_data.get('speech_service_subscription_id', '').strip(),
'speech_service_resource_group': form_data.get('speech_service_resource_group', '').strip(),
'speech_service_resource_name': form_data.get('speech_service_resource_name', '').strip(),
'speech_service_resource_id': form_data.get('speech_service_resource_id', '').strip(),
'speech_service_locale': form_data.get('speech_service_locale', '').strip(),
'speech_service_authentication_type': form_data.get('speech_service_authentication_type', 'key'),
'speech_service_key': form_data.get('speech_service_key', '').strip(),
Expand Down
Loading
Loading