Spaces:
Paused
Paused
| from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, cast | |
| import httpx | |
| import litellm | |
| from litellm._logging import verbose_logger | |
| from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig | |
| from litellm.secret_managers.main import get_secret_str | |
| from litellm.types.llms.openai import * | |
| from litellm.types.responses.main import * | |
| from litellm.types.router import GenericLiteLLMParams | |
| from litellm.utils import _add_path_to_api_base | |
| if TYPE_CHECKING: | |
| from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj | |
| LiteLLMLoggingObj = _LiteLLMLoggingObj | |
| else: | |
| LiteLLMLoggingObj = Any | |
| class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig): | |
| def validate_environment( | |
| self, | |
| headers: dict, | |
| model: str, | |
| api_key: Optional[str] = None, | |
| ) -> dict: | |
| api_key = ( | |
| api_key | |
| or litellm.api_key | |
| or litellm.azure_key | |
| or get_secret_str("AZURE_OPENAI_API_KEY") | |
| or get_secret_str("AZURE_API_KEY") | |
| ) | |
| headers.update( | |
| { | |
| "Authorization": f"Bearer {api_key}", | |
| } | |
| ) | |
| return headers | |
| def get_complete_url( | |
| self, | |
| api_base: Optional[str], | |
| litellm_params: dict, | |
| ) -> str: | |
| """ | |
| Constructs a complete URL for the API request. | |
| Args: | |
| - api_base: Base URL, e.g., | |
| "https://litellm8397336933.openai.azure.com" | |
| OR | |
| "https://litellm8397336933.openai.azure.com/openai/responses?api-version=2024-05-01-preview" | |
| - model: Model name. | |
| - optional_params: Additional query parameters, including "api_version". | |
| - stream: If streaming is required (optional). | |
| Returns: | |
| - A complete URL string, e.g., | |
| "https://litellm8397336933.openai.azure.com/openai/responses?api-version=2024-05-01-preview" | |
| """ | |
| api_base = api_base or litellm.api_base or get_secret_str("AZURE_API_BASE") | |
| if api_base is None: | |
| raise ValueError( | |
| f"api_base is required for Azure AI Studio. Please set the api_base parameter. Passed `api_base={api_base}`" | |
| ) | |
| original_url = httpx.URL(api_base) | |
| # Extract api_version or use default | |
| api_version = cast(Optional[str], litellm_params.get("api_version")) | |
| # Create a new dictionary with existing params | |
| query_params = dict(original_url.params) | |
| # Add api_version if needed | |
| if "api-version" not in query_params and api_version: | |
| query_params["api-version"] = api_version | |
| # Add the path to the base URL | |
| if "/openai/responses" not in api_base: | |
| new_url = _add_path_to_api_base( | |
| api_base=api_base, ending_path="/openai/responses" | |
| ) | |
| else: | |
| new_url = api_base | |
| # Use the new query_params dictionary | |
| final_url = httpx.URL(new_url).copy_with(params=query_params) | |
| return str(final_url) | |
| ######################################################### | |
| ########## DELETE RESPONSE API TRANSFORMATION ############## | |
| ######################################################### | |
| def _construct_url_for_response_id_in_path( | |
| self, api_base: str, response_id: str | |
| ) -> str: | |
| """ | |
| Constructs a URL for the API request with the response_id in the path. | |
| """ | |
| from urllib.parse import urlparse, urlunparse | |
| # Parse the URL to separate its components | |
| parsed_url = urlparse(api_base) | |
| # Insert the response_id at the end of the path component | |
| # Remove trailing slash if present to avoid double slashes | |
| path = parsed_url.path.rstrip("/") | |
| new_path = f"{path}/{response_id}" | |
| # Reconstruct the URL with all original components but with the modified path | |
| constructed_url = urlunparse( | |
| ( | |
| parsed_url.scheme, # http, https | |
| parsed_url.netloc, # domain name, port | |
| new_path, # path with response_id added | |
| parsed_url.params, # parameters | |
| parsed_url.query, # query string | |
| parsed_url.fragment, # fragment | |
| ) | |
| ) | |
| return constructed_url | |
| def transform_delete_response_api_request( | |
| self, | |
| response_id: str, | |
| api_base: str, | |
| litellm_params: GenericLiteLLMParams, | |
| headers: dict, | |
| ) -> Tuple[str, Dict]: | |
| """ | |
| Transform the delete response API request into a URL and data | |
| Azure OpenAI API expects the following request: | |
| - DELETE /openai/responses/{response_id}?api-version=xxx | |
| This function handles URLs with query parameters by inserting the response_id | |
| at the correct location (before any query parameters). | |
| """ | |
| delete_url = self._construct_url_for_response_id_in_path( | |
| api_base=api_base, response_id=response_id | |
| ) | |
| data: Dict = {} | |
| verbose_logger.debug(f"delete response url={delete_url}") | |
| return delete_url, data | |
| ######################################################### | |
| ########## GET RESPONSE API TRANSFORMATION ############### | |
| ######################################################### | |
| def transform_get_response_api_request( | |
| self, | |
| response_id: str, | |
| api_base: str, | |
| litellm_params: GenericLiteLLMParams, | |
| headers: dict, | |
| ) -> Tuple[str, Dict]: | |
| """ | |
| Transform the get response API request into a URL and data | |
| OpenAI API expects the following request | |
| - GET /v1/responses/{response_id} | |
| """ | |
| get_url = self._construct_url_for_response_id_in_path( | |
| api_base=api_base, response_id=response_id | |
| ) | |
| data: Dict = {} | |
| verbose_logger.debug(f"get response url={get_url}") | |
| return get_url, data | |