Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
azure_openai.py294 linesDownload Raw Back to chat_models
1"""Azure OpenAI chat wrapper."""2 3from __future__ import annotations4 5import logging6import os7import warnings8from typing import Any, Awaitable, Callable, Dict, List, Union9 10from langchain_core._api.deprecation import deprecated11from langchain_core.outputs import ChatResult12from langchain_core.utils import get_from_dict_or_env, pre_init13from pydantic import BaseModel, Field14 15from langchain_community.chat_models.openai import ChatOpenAI16from langchain_community.utils.openai import is_openai_v117 18logger = logging.getLogger(__name__)19 20 21@deprecated(22    since="0.0.10",23    removal="1.0",24    alternative_import="langchain_openai.AzureChatOpenAI",25)26class AzureChatOpenAI(ChatOpenAI):27    """`Azure OpenAI` Chat Completion API.28 29    To use this class you30    must have a deployed model on Azure OpenAI. Use `deployment_name` in the31    constructor to refer to the "Model deployment name" in the Azure portal.32 33    In addition, you should have the ``openai`` python package installed, and the34    following environment variables set or passed in constructor in lower case:35    - ``AZURE_OPENAI_API_KEY``36    - ``AZURE_OPENAI_ENDPOINT``37    - ``AZURE_OPENAI_AD_TOKEN``38    - ``OPENAI_API_VERSION``39    - ``OPENAI_PROXY``40 41    For example, if you have `gpt-35-turbo` deployed, with the deployment name42    `35-turbo-dev`, the constructor should look like:43 44    .. code-block:: python45 46        AzureChatOpenAI(47            azure_deployment="35-turbo-dev",48            openai_api_version="2023-05-15",49        )50 51    Be aware the API version may change.52 53    You can also specify the version of the model using ``model_version`` constructor54    parameter, as Azure OpenAI doesn't return model version with the response.55 56    Default is empty. When you specify the version, it will be appended to the57    model name in the response. Setting correct version will help you to calculate the58    cost properly. Model version is not validated, so make sure you set it correctly59    to get the correct cost.60 61    Any parameters that are valid to be passed to the openai.create call can be passed62    in, even if not explicitly saved on this class.63    """64 65    azure_endpoint: Union[str, None] = None66    """Your Azure endpoint, including the resource.67    68        Automatically inferred from env var `AZURE_OPENAI_ENDPOINT` if not provided.69    70        Example: `https://example-resource.azure.openai.com/`71    """72    deployment_name: Union[str, None] = Field(default=None, alias="azure_deployment")73    """A model deployment. 74    75        If given sets the base client URL to include `/deployments/{azure_deployment}`.76        Note: this means you won't be able to use non-deployment endpoints.77    """78    openai_api_version: str = Field(default="", alias="api_version")79    """Automatically inferred from env var `OPENAI_API_VERSION` if not provided."""80    openai_api_key: Union[str, None] = Field(default=None, alias="api_key")81    """Automatically inferred from env var `AZURE_OPENAI_API_KEY` if not provided."""82    azure_ad_token: Union[str, None] = None83    """Your Azure Active Directory token.84    85        Automatically inferred from env var `AZURE_OPENAI_AD_TOKEN` if not provided.86        87        For more: 88        https://www.microsoft.com/en-us/security/business/identity-access/microsoft-entra-id.89    """90    azure_ad_token_provider: Union[Callable[[], str], None] = None91    """A function that returns an Azure Active Directory token.92        93        Will be invoked on every sync request. For async requests,94        will be invoked if `azure_ad_async_token_provider` is not provided.95    """96    azure_ad_async_token_provider: Union[Callable[[], Awaitable[str]], None] = None97    """A function that returns an Azure Active Directory token.98 99        Will be invoked on every async request.100    """101    model_version: str = ""102    """Legacy, for openai<1.0.0 support."""103    openai_api_type: str = ""104    """Legacy, for openai<1.0.0 support."""105    validate_base_url: bool = True106    """For backwards compatibility. If legacy val openai_api_base is passed in, try to 107        infer if it is a base_url or azure_endpoint and update accordingly.108    """109 110    @classmethod111    def get_lc_namespace(cls) -> List[str]:112        """Get the namespace of the langchain object."""113        return ["langchain", "chat_models", "azure_openai"]114 115    @pre_init116    def validate_environment(cls, values: Dict) -> Dict:117        """Validate that api key and python package exists in environment."""118        if values["n"] < 1:119            raise ValueError("n must be at least 1.")120        if values["n"] > 1 and values["streaming"]:121            raise ValueError("n must be 1 when streaming.")122 123        # Check OPENAI_KEY for backwards compatibility.124        # TODO: Remove OPENAI_API_KEY support to avoid possible conflict when using125        # other forms of azure credentials.126        values["openai_api_key"] = (127            values["openai_api_key"]128            or os.getenv("AZURE_OPENAI_API_KEY")129            or os.getenv("OPENAI_API_KEY")130        )131        values["openai_api_base"] = values["openai_api_base"] or os.getenv(132            "OPENAI_API_BASE"133        )134        values["openai_api_version"] = values["openai_api_version"] or os.getenv(135            "OPENAI_API_VERSION"136        )137        # Check OPENAI_ORGANIZATION for backwards compatibility.138        values["openai_organization"] = (139            values["openai_organization"]140            or os.getenv("OPENAI_ORG_ID")141            or os.getenv("OPENAI_ORGANIZATION")142        )143        values["azure_endpoint"] = values["azure_endpoint"] or os.getenv(144            "AZURE_OPENAI_ENDPOINT"145        )146        values["azure_ad_token"] = values["azure_ad_token"] or os.getenv(147            "AZURE_OPENAI_AD_TOKEN"148        )149 150        values["openai_api_type"] = get_from_dict_or_env(151            values, "openai_api_type", "OPENAI_API_TYPE", default="azure"152        )153        values["openai_proxy"] = get_from_dict_or_env(154            values, "openai_proxy", "OPENAI_PROXY", default=""155        )156 157        try:158            import openai159 160        except ImportError:161            raise ImportError(162                "Could not import openai python package. "163                "Please install it with `pip install openai`."164            )165        if is_openai_v1():166            # For backwards compatibility. Before openai v1, no distinction was made167            # between azure_endpoint and base_url (openai_api_base).168            openai_api_base = values["openai_api_base"]169            if openai_api_base and values["validate_base_url"]:170                if "/openai" not in openai_api_base:171                    values["openai_api_base"] = (172                        values["openai_api_base"].rstrip("/") + "/openai"173                    )174                    warnings.warn(175                        "As of openai>=1.0.0, Azure endpoints should be specified via "176                        f"the `azure_endpoint` param not `openai_api_base` "177                        f"(or alias `base_url`). Updating `openai_api_base` from "178                        f"{openai_api_base} to {values['openai_api_base']}."179                    )180                if values["deployment_name"]:181                    warnings.warn(182                        "As of openai>=1.0.0, if `deployment_name` (or alias "183                        "`azure_deployment`) is specified then "184                        "`openai_api_base` (or alias `base_url`) should not be. "185                        "Instead use `deployment_name` (or alias `azure_deployment`) "186                        "and `azure_endpoint`."187                    )188                    if values["deployment_name"] not in values["openai_api_base"]:189                        warnings.warn(190                            "As of openai>=1.0.0, if `openai_api_base` "191                            "(or alias `base_url`) is specified it is expected to be "192                            "of the form "193                            "https://example-resource.azure.openai.com/openai/deployments/example-deployment. "  # noqa: E501194                            f"Updating {openai_api_base} to "195                            f"{values['openai_api_base']}."196                        )197                        values["openai_api_base"] += (198                            "/deployments/" + values["deployment_name"]199                        )200                    values["deployment_name"] = None201            client_params = {202                "api_version": values["openai_api_version"],203                "azure_endpoint": values["azure_endpoint"],204                "azure_deployment": values["deployment_name"],205                "api_key": values["openai_api_key"],206                "azure_ad_token": values["azure_ad_token"],207                "azure_ad_token_provider": values["azure_ad_token_provider"],208                "organization": values["openai_organization"],209                "base_url": values["openai_api_base"],210                "timeout": values["request_timeout"],211                "max_retries": values["max_retries"],212                "default_headers": {213                    **(values["default_headers"] or {}),214                    "User-Agent": "langchain-comm-python-azure-openai",215                },216                "default_query": values["default_query"],217                "http_client": values["http_client"],218            }219            values["client"] = openai.AzureOpenAI(**client_params).chat.completions220 221            azure_ad_async_token_provider = values["azure_ad_async_token_provider"]222 223            if azure_ad_async_token_provider:224                client_params["azure_ad_token_provider"] = azure_ad_async_token_provider225 226            values["async_client"] = openai.AsyncAzureOpenAI(227                **client_params228            ).chat.completions229        else:230            values["client"] = openai.ChatCompletion231        return values232 233    @property234    def _default_params(self) -> Dict[str, Any]:235        """Get the default parameters for calling OpenAI API."""236        if is_openai_v1():237            return super()._default_params238        else:239            return {240                **super()._default_params,241                "engine": self.deployment_name,242            }243 244    @property245    def _identifying_params(self) -> Dict[str, Any]:246        """Get the identifying parameters."""247        return {**self._default_params}248 249    @property250    def _client_params(self) -> Dict[str, Any]:251        """Get the config params used for the openai client."""252        if is_openai_v1():253            return super()._client_params254        else:255            return {256                **super()._client_params,257                "api_type": self.openai_api_type,258                "api_version": self.openai_api_version,259            }260 261    @property262    def _llm_type(self) -> str:263        return "azure-openai-chat"264 265    @property266    def lc_attributes(self) -> Dict[str, Any]:267        return {268            "openai_api_type": self.openai_api_type,269            "openai_api_version": self.openai_api_version,270        }271 272    def _create_chat_result(self, response: Union[dict, BaseModel]) -> ChatResult:273        if not isinstance(response, dict):274            response = response.dict()275        for res in response["choices"]:276            if res.get("finish_reason", None) == "content_filter":277                raise ValueError(278                    "Azure has not provided the response due to a content filter "279                    "being triggered"280                )281        chat_result = super()._create_chat_result(response)282 283        if "model" in response:284            model = response["model"]285            if self.model_version:286                model = f"{model}-{self.model_version}"287 288            if chat_result.llm_output is not None and isinstance(289                chat_result.llm_output, dict290            ):291                chat_result.llm_output["model_name"] = model292 293        return chat_result294 
codekingpro/portable-devtools · Team Ai