codekingpro/portable-devtools
114k
1"""Azure OpenAI embeddings wrapper."""2 3from __future__ import annotations4 5import os6import warnings7from typing import Any, Awaitable, Callable, Dict, Optional, Union8 9from langchain_core._api.deprecation import deprecated10from langchain_core.utils import get_from_dict_or_env11from pydantic import Field, model_validator12from typing_extensions import Self13 14from langchain_community.embeddings.openai import OpenAIEmbeddings15from langchain_community.utils.openai import is_openai_v116 17 18@deprecated(19 since="0.0.9",20 removal="1.0",21 alternative_import="langchain_openai.AzureOpenAIEmbeddings",22)23class AzureOpenAIEmbeddings(OpenAIEmbeddings):24 """`Azure OpenAI` Embeddings API."""25 26 azure_endpoint: Union[str, None] = None27 """Your Azure endpoint, including the resource.28 29 Automatically inferred from env var `AZURE_OPENAI_ENDPOINT` if not provided.30 31 Example: `https://example-resource.azure.openai.com/`32 """33 deployment: Optional[str] = Field(default=None, alias="azure_deployment")34 """A model deployment. 35 36 If given sets the base client URL to include `/deployments/{azure_deployment}`.37 Note: this means you won't be able to use non-deployment endpoints.38 """39 openai_api_key: Union[str, None] = Field(default=None, alias="api_key")40 """Automatically inferred from env var `AZURE_OPENAI_API_KEY` if not provided."""41 azure_ad_token: Union[str, None] = None42 """Your Azure Active Directory token.43 44 Automatically inferred from env var `AZURE_OPENAI_AD_TOKEN` if not provided.45 46 For more: 47 https://www.microsoft.com/en-us/security/business/identity-access/microsoft-entra-id.48 """49 azure_ad_token_provider: Union[Callable[[], str], None] = None50 """A function that returns an Azure Active Directory token.51 52 Will be invoked on every sync request. For async requests,53 will be invoked if `azure_ad_async_token_provider` is not provided.54 """55 azure_ad_async_token_provider: Union[Callable[[], Awaitable[str]], None] = None56 """A function that returns an Azure Active Directory token.57 58 Will be invoked on every async request.59 """60 openai_api_version: Optional[str] = Field(default=None, alias="api_version")61 """Automatically inferred from env var `OPENAI_API_VERSION` if not provided."""62 validate_base_url: bool = True63 64 @model_validator(mode="before")65 @classmethod66 def validate_environment(cls, values: Dict) -> Any:67 """Validate that api key and python package exists in environment."""68 # Check OPENAI_KEY for backwards compatibility.69 # TODO: Remove OPENAI_API_KEY support to avoid possible conflict when using70 # other forms of azure credentials.71 values["openai_api_key"] = (72 values.get("openai_api_key")73 or os.getenv("AZURE_OPENAI_API_KEY")74 or os.getenv("OPENAI_API_KEY")75 )76 values["openai_api_base"] = values.get("openai_api_base") or os.getenv(77 "OPENAI_API_BASE"78 )79 values["openai_api_version"] = values.get("openai_api_version") or os.getenv(80 "OPENAI_API_VERSION", default="2023-05-15"81 )82 values["openai_api_type"] = get_from_dict_or_env(83 values, "openai_api_type", "OPENAI_API_TYPE", default="azure"84 )85 values["openai_organization"] = (86 values.get("openai_organization")87 or os.getenv("OPENAI_ORG_ID")88 or os.getenv("OPENAI_ORGANIZATION")89 )90 values["openai_proxy"] = get_from_dict_or_env(91 values,92 "openai_proxy",93 "OPENAI_PROXY",94 default="",95 )96 values["azure_endpoint"] = values.get("azure_endpoint") or os.getenv(97 "AZURE_OPENAI_ENDPOINT"98 )99 values["azure_ad_token"] = values.get("azure_ad_token") or os.getenv(100 "AZURE_OPENAI_AD_TOKEN"101 )102 # Azure OpenAI embedding models allow a maximum of 2048 texts103 # at a time in each batch104 # See: https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#embeddings105 values["chunk_size"] = min(values["chunk_size"], 2048)106 try:107 import openai # noqa: F401108 except ImportError:109 raise ImportError(110 "Could not import openai python package. "111 "Please install it with `pip install openai`."112 )113 if is_openai_v1():114 # For backwards compatibility. Before openai v1, no distinction was made115 # between azure_endpoint and base_url (openai_api_base).116 openai_api_base = values["openai_api_base"]117 if openai_api_base and values["validate_base_url"]:118 if "/openai" not in openai_api_base:119 values["openai_api_base"] += "/openai"120 warnings.warn(121 "As of openai>=1.0.0, Azure endpoints should be specified via "122 f"the `azure_endpoint` param not `openai_api_base` "123 f"(or alias `base_url`). Updating `openai_api_base` from "124 f"{openai_api_base} to {values['openai_api_base']}."125 )126 if values["deployment"]:127 warnings.warn(128 "As of openai>=1.0.0, if `deployment` (or alias "129 "`azure_deployment`) is specified then "130 "`openai_api_base` (or alias `base_url`) should not be. "131 "Instead use `deployment` (or alias `azure_deployment`) "132 "and `azure_endpoint`."133 )134 if values["deployment"] not in values["openai_api_base"]:135 warnings.warn(136 "As of openai>=1.0.0, if `openai_api_base` "137 "(or alias `base_url`) is specified it is expected to be "138 "of the form "139 "https://example-resource.azure.openai.com/openai/deployments/example-deployment. " # noqa: E501140 f"Updating {openai_api_base} to "141 f"{values['openai_api_base']}."142 )143 values["openai_api_base"] += (144 "/deployments/" + values["deployment"]145 )146 values["deployment"] = None147 return values148 149 @model_validator(mode="after")150 def post_init_validator(self) -> Self:151 """Validate that the base url is set."""152 import openai153 154 if is_openai_v1():155 client_params = {156 "api_version": self.openai_api_version,157 "azure_endpoint": self.azure_endpoint,158 "azure_deployment": self.deployment,159 "api_key": self.openai_api_key,160 "azure_ad_token": self.azure_ad_token,161 "azure_ad_token_provider": self.azure_ad_token_provider,162 "organization": self.openai_organization,163 "base_url": self.openai_api_base,164 "timeout": self.request_timeout,165 "max_retries": self.max_retries,166 "default_headers": {167 **(self.default_headers or {}),168 "User-Agent": "langchain-comm-python-azure-openai",169 },170 "default_query": self.default_query,171 "http_client": self.http_client,172 }173 self.client = openai.AzureOpenAI(**client_params).embeddings174 175 if self.azure_ad_async_token_provider:176 client_params["azure_ad_token_provider"] = (177 self.azure_ad_async_token_provider178 )179 180 self.async_client = openai.AsyncAzureOpenAI(**client_params).embeddings181 else:182 self.client = openai.Embedding183 return self184 185 @property186 def _llm_type(self) -> str:187 return "azure-openai-chat"188 