Skip to content

Commit 182bdae

Browse files
authored
Projects Client - Get Azure OpenAI should use the parent resource unless caller provides a connection name (#45790)
1 parent 41ed3db commit 182bdae

3 files changed

Lines changed: 58 additions & 24 deletions

File tree

sdk/ai/azure-ai-projects/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
### Bugs Fixed
1010

11+
- Projects Client: Get Azure OpenAI should use the parent resource unless caller provides a connection name
12+
1113
### Other Changes
1214

1315
## 1.0.0-beta.2 (2025-06-17)

sdk/ai/azure-ai-projects/src/main/java/com/azure/ai/projects/AIProjectClientBuilder.java

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
import com.openai.azure.AzureOpenAIServiceVersion;
5353
import com.openai.client.okhttp.OpenAIOkHttpClient;
5454
import com.openai.credential.BearerTokenCredential;
55+
import java.net.MalformedURLException;
56+
import java.net.URL;
5557
import java.util.ArrayList;
5658
import java.util.List;
5759
import java.util.Map;
@@ -419,31 +421,36 @@ private OpenAIOkHttpClient.Builder createOpenAIOkHttpClientDelegateBuilder() {
419421
OpenAIOkHttpClient.Builder builder = OpenAIOkHttpClient.builder();
420422
ConnectionsClient connectionsClient = this.buildConnectionsClient();
421423
if (openAIConnectionName == null) {
422-
throw LOGGER.logExceptionAsError(new IllegalArgumentException("OpenAI connection name is not set."));
423-
}
424-
Connection connection = connectionsClient.getConnection(openAIConnectionName, true);
425-
if (connection.getType() != ConnectionType.AZURE_OPEN_AI) {
426-
throw LOGGER.logExceptionAsError(new IllegalArgumentException("The connection is not of type OPENAI."));
427-
}
428-
String azureOpenAIEndpoint = connection.getTarget();
429-
if (azureOpenAIEndpoint.endsWith("/")) {
430-
azureOpenAIEndpoint = azureOpenAIEndpoint.substring(0, azureOpenAIEndpoint.length() - 1);
431-
}
432-
builder.baseUrl(azureOpenAIEndpoint);
433-
BaseCredentials credentials = connection.getCredentials();
434-
if (credentials.getType() == CredentialType.API_KEY && credentials instanceof ApiKeyCredentials) {
435-
String apiKey = ((ApiKeyCredentials) credentials).getApiKey();
436-
builder.apiKey(apiKey);
437-
} else if (credentials.getType() == CredentialType.ENTRA_ID) {
438-
if (tokenCredential == null) {
439-
throw LOGGER
440-
.logExceptionAsError(new IllegalArgumentException("Credential is required for OpenAI connection."));
441-
}
424+
// use the parent resource
425+
String azureOpenAIEndpoint = getOpenAIInferenceUrl(this.endpoint);
426+
builder.baseUrl(azureOpenAIEndpoint);
442427
builder.credential(BearerTokenCredential
443-
.create(getBearerTokenSupplier(tokenCredential, "https://cognitiveservices.azure.com/.default")));
428+
.create(getBearerTokenSupplier(this.tokenCredential, "https://cognitiveservices.azure.com/.default")));
444429
} else {
445-
throw LOGGER.logExceptionAsError(
446-
new IllegalArgumentException("Unsupported credential type for OpenAI connection."));
430+
Connection connection = connectionsClient.getConnection(openAIConnectionName, true);
431+
if (connection.getType() != ConnectionType.AZURE_OPEN_AI) {
432+
throw LOGGER.logExceptionAsError(new IllegalArgumentException("The connection is not of type OPENAI."));
433+
}
434+
String azureOpenAIEndpoint = connection.getTarget();
435+
if (azureOpenAIEndpoint.endsWith("/")) {
436+
azureOpenAIEndpoint = azureOpenAIEndpoint.substring(0, azureOpenAIEndpoint.length() - 1);
437+
}
438+
builder.baseUrl(azureOpenAIEndpoint);
439+
BaseCredentials credentials = connection.getCredentials();
440+
if (credentials.getType() == CredentialType.API_KEY && credentials instanceof ApiKeyCredentials) {
441+
String apiKey = ((ApiKeyCredentials) credentials).getApiKey();
442+
builder.apiKey(apiKey);
443+
} else if (credentials.getType() == CredentialType.ENTRA_ID) {
444+
if (tokenCredential == null) {
445+
throw LOGGER.logExceptionAsError(
446+
new IllegalArgumentException("Credential is required for OpenAI connection."));
447+
}
448+
builder.credential(BearerTokenCredential
449+
.create(getBearerTokenSupplier(tokenCredential, "https://cognitiveservices.azure.com/.default")));
450+
} else {
451+
throw LOGGER.logExceptionAsError(
452+
new IllegalArgumentException("Unsupported credential type for OpenAI connection."));
453+
}
447454
}
448455
if (azureOpenAIServiceVersion != null) {
449456
builder.azureServiceVersion(azureOpenAIServiceVersion);
@@ -602,6 +609,31 @@ private static Supplier<String> getBearerTokenSupplier(TokenCredential credentia
602609
};
603610
}
604611

612+
/**
613+
* Converts an input URL in the format:
614+
* https://[host-name]/[some-path]
615+
* to:
616+
* https://[host-name]
617+
*
618+
* @param inputUrl The input endpoint URL used to construct AIProjectClient.
619+
* @return The endpoint URL required to construct an AzureOpenAI client.
620+
*/
621+
private static String getOpenAIInferenceUrl(String inputUrl) {
622+
URL parsed = null;
623+
try {
624+
parsed = new URL(inputUrl);
625+
} catch (MalformedURLException e) {
626+
throw LOGGER
627+
.logExceptionAsError(new IllegalArgumentException("Invalid endpoint URL format. Malformed.", e));
628+
}
629+
if (!"https".equals(parsed.getProtocol()) || parsed.getHost().isEmpty()) {
630+
throw LOGGER.logExceptionAsError(
631+
new IllegalArgumentException("Invalid endpoint URL format. Must be an https URL with a host."));
632+
}
633+
String newUrl = "https://" + parsed.getHost();
634+
return newUrl;
635+
}
636+
605637
/**
606638
* Create an instance of the AIProjectClientBuilder.
607639
*/
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
directory: specification/ai/Azure.AI.Projects/
2-
commit: 9f58ff4442493f8f333c751656d4b3a7e10d6e83
2+
commit: ff0bb49f83506566af01d38027029cd05469ab6a
33
repo: Azure/azure-rest-api-specs
44
additionalDirectories: []
55

0 commit comments

Comments
 (0)