@@ -101,6 +101,90 @@ def __init__(
101101
102102 self .telemetry = TelemetryOperations (self ) # type: ignore
103103
104+ def _get_openai_base_url (self , agent_name : Optional [str ], kwargs : dict ) -> str :
105+ """Resolve the base URL for the AsyncOpenAI client.
106+
107+ :param agent_name: Optional hosted-agent name.
108+ :type agent_name: str or None
109+ :param kwargs: Caller keyword arguments; ``base_url`` is popped when present.
110+ :type kwargs: dict
111+ :return: The base URL to use for the AsyncOpenAI client.
112+ :rtype: str
113+ :raises ValueError: If ``agent_name`` is provided but ``allow_preview=True`` was not set.
114+ """
115+ if "base_url" in kwargs :
116+ return kwargs .pop ("base_url" )
117+ if agent_name is not None :
118+ if self ._config .allow_preview : # pylint: disable=protected-access
119+ return (
120+ self ._config .endpoint .rstrip ("/" ) + f"/agents/{ agent_name } /endpoint/protocols/openai"
121+ ) # pylint: disable=protected-access
122+ raise ValueError (
123+ "Calling `get_openai_client` method with an `agent_name` requires you to set `allow_preview=True`"
124+ "\n when constructing the AIProjectClient. Note that preview features are under development and "
125+ "\n subject to change. They should not be used in production environments."
126+ )
127+ return self ._config .endpoint .rstrip ("/" ) + "/openai/v1" # pylint: disable=protected-access
128+
129+ def _get_openai_query_params (self , agent_name : Optional [str ], kwargs : dict ) -> dict :
130+ """Build the ``default_query`` dict for the AsyncOpenAI client.
131+
132+ :param agent_name: Optional hosted-agent name.
133+ :type agent_name: str or None
134+ :param kwargs: Caller keyword arguments; ``default_query`` is popped when present.
135+ :type kwargs: dict
136+ :return: Query parameters to forward to the AsyncOpenAI client.
137+ :rtype: dict
138+ """
139+ default_query = dict [str , str ](kwargs .pop ("default_query" , None ) or {})
140+ if agent_name is not None and "api-version" not in default_query :
141+ default_query ["api-version" ] = self ._config .api_version # pylint: disable=protected-access
142+ return default_query
143+
144+ def _get_openai_api_key (self , kwargs : dict ):
145+ """Resolve the API key for the AsyncOpenAI client.
146+
147+ :param kwargs: Caller keyword arguments; ``api_key`` is popped when present.
148+ :type kwargs: dict
149+ :return: The API key string or a bearer-token-provider callable.
150+ :rtype: str or Callable
151+ """
152+ if "api_key" in kwargs :
153+ return kwargs .pop ("api_key" )
154+ return get_bearer_token_provider (
155+ self ._config .credential , # pylint: disable=protected-access
156+ "https://ai.azure.com/.default" ,
157+ )
158+
159+ def _get_openai_http_client (self , kwargs : dict ):
160+ """Resolve the HTTP transport client for the AsyncOpenAI client.
161+
162+ :param kwargs: Caller keyword arguments; ``http_client`` is popped when present.
163+ :type kwargs: dict
164+ :return: An httpx.AsyncClient instance configured with logging transport, or ``None``.
165+ :rtype: httpx.AsyncClient or None
166+ """
167+ if "http_client" in kwargs :
168+ return kwargs .pop ("http_client" )
169+ if self ._console_logging_enabled :
170+ return httpx .AsyncClient (transport = _OpenAILoggingTransport ())
171+ return None
172+
173+ def _prepare_openai_headers (self , agent_name : Optional [str ], kwargs : dict ) -> dict :
174+ """Build the ``default_headers`` dict for the AsyncOpenAI client.
175+
176+ :param agent_name: Optional hosted-agent name.
177+ :type agent_name: str or None
178+ :param kwargs: Caller keyword arguments; ``default_headers`` is popped when present.
179+ :type kwargs: dict
180+ :return: Headers to forward to the AsyncOpenAI client.
181+ :rtype: dict
182+ """
183+ default_headers = dict [str , str ](kwargs .pop ("default_headers" , None ) or {})
184+ if agent_name is not None and not _has_header_case_insensitive (default_headers , _FOUNDRY_FEATURES_HEADER_NAME ):
185+ default_headers [_FOUNDRY_FEATURES_HEADER_NAME ] = _BETA_OPERATION_FEATURE_HEADERS ["agents" ]
186+ return default_headers
187+
104188 @distributed_trace
105189 def get_openai_client (self , * , agent_name : Optional [str ] = None , ** kwargs : Any ) -> AsyncOpenAI :
106190 """Get an authenticated AsyncOpenAI client from the `openai` package.
@@ -131,51 +215,17 @@ def get_openai_client(self, *, agent_name: Optional[str] = None, **kwargs: Any)
131215
132216 kwargs = kwargs .copy () if kwargs else {}
133217
134- # Allow caller to override base_url
135- if "base_url" in kwargs :
136- base_url = kwargs .pop ("base_url" )
137- elif agent_name is not None :
138- if self ._config .allow_preview :
139- base_url = (
140- self ._config .endpoint .rstrip ("/" ) + f"/agents/{ agent_name } /endpoint/protocols/openai"
141- ) # pylint: disable=protected-access
142- else :
143- raise ValueError (
144- "Calling `get_openai_client` method with an `agent_name` requires you to set `allow_preview=True`"
145- "\n when constructing the AIProjectClient. Note that preview features are under development and "
146- "\n subject to change. They should not be used in production environments."
147- )
148- else :
149- base_url = self ._config .endpoint .rstrip ("/" ) + "/openai/v1" # pylint: disable=protected-access
150-
151- default_query = dict [str , str ](kwargs .pop ("default_query" , None ) or {})
152- if agent_name is not None and "api-version" not in default_query :
153- default_query ["api-version" ] = self ._config .api_version # pylint: disable=protected-access
218+ base_url = self ._get_openai_base_url (agent_name , kwargs )
219+ default_query = self ._get_openai_query_params (agent_name , kwargs )
154220
155221 logger .debug ( # pylint: disable=specify-parameter-names-in-call
156222 "[get_openai_client] Creating OpenAI client using Entra ID authentication, base_url = `%s`" , # pylint: disable=line-too-long
157223 base_url ,
158224 )
159225
160- # Allow caller to override api_key, otherwise use token provider
161- if "api_key" in kwargs :
162- api_key = kwargs .pop ("api_key" )
163- else :
164- api_key = get_bearer_token_provider (
165- self ._config .credential , # pylint: disable=protected-access
166- "https://ai.azure.com/.default" ,
167- )
168-
169- if "http_client" in kwargs :
170- http_client = kwargs .pop ("http_client" )
171- elif self ._console_logging_enabled :
172- http_client = httpx .AsyncClient (transport = _OpenAILoggingTransport ())
173- else :
174- http_client = None
175-
176- default_headers = dict [str , str ](kwargs .pop ("default_headers" , None ) or {})
177- if agent_name is not None and not _has_header_case_insensitive (default_headers , _FOUNDRY_FEATURES_HEADER_NAME ):
178- default_headers [_FOUNDRY_FEATURES_HEADER_NAME ] = _BETA_OPERATION_FEATURE_HEADERS ["agents" ]
226+ api_key = self ._get_openai_api_key (kwargs )
227+ http_client = self ._get_openai_http_client (kwargs )
228+ default_headers = self ._prepare_openai_headers (agent_name , kwargs )
179229
180230 openai_custom_user_agent = default_headers .get ("User-Agent" , None )
181231
0 commit comments