about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/azure/common
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/azure/common
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/azure/common')
-rw-r--r--.venv/lib/python3.12/site-packages/azure/common/__init__.py37
-rw-r--r--.venv/lib/python3.12/site-packages/azure/common/_version.py7
-rw-r--r--.venv/lib/python3.12/site-packages/azure/common/client_factory.py295
-rw-r--r--.venv/lib/python3.12/site-packages/azure/common/cloud.py30
-rw-r--r--.venv/lib/python3.12/site-packages/azure/common/credentials.py171
-rw-r--r--.venv/lib/python3.12/site-packages/azure/common/exceptions.py22
6 files changed, 562 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/azure/common/__init__.py b/.venv/lib/python3.12/site-packages/azure/common/__init__.py
new file mode 100644
index 00000000..6fbc7a2d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/azure/common/__init__.py
@@ -0,0 +1,37 @@
+#-------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+#--------------------------------------------------------------------------
+from ._version import VERSION as _VERSION
+
+__author__ = 'Microsoft Corp. <azpysdkhelp@microsoft.com>'
+__version__ = _VERSION
+
+
+class AzureException(Exception):
+    pass
+
+
+class AzureHttpError(AzureException):
+    def __init__(self, message, status_code):
+        super(AzureHttpError, self).__init__(message)
+        self.status_code = status_code
+
+    def __new__(cls, message, status_code, *args, **kwargs):
+        if cls is AzureHttpError:
+            if status_code == 404:
+                cls = AzureMissingResourceHttpError
+            elif status_code == 409:
+                cls = AzureConflictHttpError
+        return AzureException.__new__(cls, message, status_code, *args, **kwargs)
+
+
+class AzureConflictHttpError(AzureHttpError):
+    def __init__(self, message, status_code):
+        super(AzureConflictHttpError, self).__init__(message, status_code)
+
+
+class AzureMissingResourceHttpError(AzureHttpError):
+    def __init__(self, message, status_code):
+        super(AzureMissingResourceHttpError, self).__init__(message, status_code)
diff --git a/.venv/lib/python3.12/site-packages/azure/common/_version.py b/.venv/lib/python3.12/site-packages/azure/common/_version.py
new file mode 100644
index 00000000..6cbf9cd4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/azure/common/_version.py
@@ -0,0 +1,7 @@
+#-------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+#--------------------------------------------------------------------------
+
+VERSION = "1.1.28"
diff --git a/.venv/lib/python3.12/site-packages/azure/common/client_factory.py b/.venv/lib/python3.12/site-packages/azure/common/client_factory.py
new file mode 100644
index 00000000..4fc1343c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/azure/common/client_factory.py
@@ -0,0 +1,295 @@
+#-------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+#--------------------------------------------------------------------------
+
+import io
+import json
+import os
+import re
+import sys
+import warnings
+try:
+    from inspect import getfullargspec as get_arg_spec
+except ImportError:
+    from inspect import getargspec as get_arg_spec
+
+from .credentials import get_azure_cli_credentials
+from .cloud import get_cli_active_cloud
+
+
+def _instantiate_client(client_class, **kwargs):
+    """Instantiate a client from kwargs, filtering kwargs to match client signature.
+    """
+    args = get_arg_spec(client_class.__init__).args
+    for key in ['subscription_id', 'tenant_id', 'base_url', 'credential', 'credentials']:
+        if key not in kwargs:
+            continue
+        if key not in args:
+            del kwargs[key]
+        elif sys.version_info < (3, 0) and isinstance(kwargs[key], unicode):
+            kwargs[key] = kwargs[key].encode('utf-8')
+    return client_class(**kwargs)
+
+
+def _client_resource(client_class, cloud):
+    """Return a tuple of the resource (used to get the right access token), and the base URL for the client.
+    Either or both can be None to signify that the default value should be used.
+    """
+    if client_class.__name__ == 'GraphRbacManagementClient':
+        return cloud.endpoints.active_directory_graph_resource_id, cloud.endpoints.active_directory_graph_resource_id
+    if client_class.__name__ == 'ApplicationInsightsDataClient':
+        return cloud.endpoints.app_insights_resource_id, cloud.endpoints.app_insights_resource_id+"/v1"
+    if client_class.__name__ == 'KeyVaultClient':
+        vault_host = cloud.suffixes.keyvault_dns[1:]
+        vault_url = 'https://{}'.format(vault_host)
+        return vault_url, None
+    return None, None
+
+
+def get_client_from_cli_profile(client_class, **kwargs):
+    """Return a SDK client initialized with current CLI credentials, CLI default subscription and CLI default cloud.
+
+    *Disclaimer*: This is NOT the recommended approach to authenticate with CLI login, this method is deprecated.
+    use https://pypi.org/project/azure-identity/ and AzureCliCredential instead. See example code below:
+
+    .. code:: python
+
+        from azure.identity import AzureCliCredential
+        from azure.mgmt.compute import ComputeManagementClient
+        client = ComputeManagementClient(AzureCliCredential(), subscription_id)
+
+    This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
+
+    For compatible azure-cli-core (< 2.20.0), This method will automatically fill the following client parameters:
+    - credentials/credential
+    - subscription_id
+    - base_url
+
+    Parameters provided in kwargs will override CLI parameters and be passed directly to the client.
+
+    :Example:
+
+    .. code:: python
+
+        from azure.common.client_factory import get_client_from_cli_profile
+        from azure.mgmt.compute import ComputeManagementClient
+        client = get_client_from_cli_profile(ComputeManagementClient)
+
+    .. versionadded:: 1.1.6
+
+    .. deprecated:: 1.1.28
+
+    .. seealso:: https://aka.ms/azsdk/python/identity/migration
+
+    :param client_class: A SDK client class
+    :return: An instantiated client
+    :raises: ImportError if azure-cli-core package is not available
+    """
+    warnings.warn(
+        "get_client_from_cli_profile is deprecated, please use azure-identity and AzureCliCredential instead. "+
+        "See also https://aka.ms/azsdk/python/identity/migration.",
+        DeprecationWarning
+    )
+
+    cloud = get_cli_active_cloud()
+    parameters = {}
+    no_credential_sentinel = object()
+    kwarg_cred = kwargs.pop('credentials', no_credential_sentinel)
+    if kwarg_cred is no_credential_sentinel:
+        kwarg_cred = kwargs.pop('credential', no_credential_sentinel)
+
+    if kwarg_cred is no_credential_sentinel or 'subscription_id' not in kwargs:
+        resource, _ = _client_resource(client_class, cloud)
+        credentials, subscription_id, tenant_id = get_azure_cli_credentials(
+            resource=resource,
+            with_tenant=True,
+        )
+        # Provide both syntax of cred, we have an "inspect" filter later
+        credential_to_pass = credentials if kwarg_cred is no_credential_sentinel else kwarg_cred
+        parameters.update({
+            'credentials': credential_to_pass,
+            'credential': credential_to_pass,
+            'subscription_id': kwargs.get('subscription_id', subscription_id)
+        })
+
+    args = get_arg_spec(client_class.__init__).args
+    if 'adla_job_dns_suffix' in args and 'adla_job_dns_suffix' not in kwargs:  # Datalake
+        # Let it raise here with AttributeError at worst, this would mean this cloud does not define
+        # ADL endpoint and no manual suffix was given
+        parameters['adla_job_dns_suffix'] = cloud.suffixes.azure_datalake_analytics_catalog_and_job_endpoint
+    elif 'base_url' in args and 'base_url' not in kwargs:
+        _, base_url = _client_resource(client_class, cloud)
+        if base_url:
+            parameters['base_url'] = base_url
+        else:
+            parameters['base_url'] = cloud.endpoints.resource_manager
+    if 'tenant_id' in args and 'tenant_id' not in kwargs:
+        parameters['tenant_id'] = tenant_id
+    parameters.update(kwargs)
+    return _instantiate_client(client_class, **parameters)
+
+
+def _is_autorest_v3(client_class):
+    """Is this client a autorestv3/track2 one?.
+    Could be refined later if necessary.
+    """
+    args = get_arg_spec(client_class.__init__).args
+    return "credential" in args
+
+
+def get_client_from_json_dict(client_class, config_dict, **kwargs):
+    """Return a SDK client initialized with a JSON auth dict.
+
+    *Disclaimer*: This is NOT the recommended approach, see https://aka.ms/azsdk/python/identity/migration for guidance.
+
+    This method will fill automatically the following client parameters:
+    - credentials
+    - subscription_id
+    - base_url
+    - tenant_id
+
+    Parameters provided in kwargs will override parameters and be passed directly to the client.
+
+    :Example:
+
+    .. code:: python
+
+        from azure.common.client_factory import get_client_from_auth_file
+        from azure.mgmt.compute import ComputeManagementClient
+        config_dict = {
+            "clientId": "ad735158-65ca-11e7-ba4d-ecb1d756380e",
+            "clientSecret": "b70bb224-65ca-11e7-810c-ecb1d756380e",
+            "subscriptionId": "bfc42d3a-65ca-11e7-95cf-ecb1d756380e",
+            "tenantId": "c81da1d8-65ca-11e7-b1d1-ecb1d756380e",
+            "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
+            "resourceManagerEndpointUrl": "https://management.azure.com/",
+            "activeDirectoryGraphResourceId": "https://graph.windows.net/",
+            "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
+            "galleryEndpointUrl": "https://gallery.azure.com/",
+            "managementEndpointUrl": "https://management.core.windows.net/"
+        }
+        client = get_client_from_json_dict(ComputeManagementClient, config_dict)
+
+    .. versionadded:: 1.1.7
+
+    .. deprecated:: 1.1.28
+
+    .. seealso:: https://aka.ms/azsdk/python/identity/migration
+
+    :param client_class: A SDK client class
+    :param dict config_dict: A config dict.
+    :return: An instantiated client
+    """
+    if _is_autorest_v3(client_class):
+        raise ValueError(
+            "Auth file or JSON dict are deprecated auth approach and are not supported anymore. "
+            "See also https://aka.ms/azsdk/python/identity/migration."
+        )
+
+    import adal
+    from msrestazure.azure_active_directory import AdalAuthentication
+
+    is_graphrbac = client_class.__name__ == 'GraphRbacManagementClient'
+    is_keyvault = client_class.__name__ == 'KeyVaultClient'
+    parameters = {
+        'subscription_id': config_dict.get('subscriptionId'),
+        'base_url': config_dict.get('resourceManagerEndpointUrl'),
+        'tenant_id': config_dict.get('tenantId')  # GraphRbac
+    }
+    if is_graphrbac:
+        parameters['base_url'] = config_dict['activeDirectoryGraphResourceId']
+
+    if 'credentials' not in kwargs:
+        # Get the right resource for Credentials
+        if is_graphrbac:
+            resource = config_dict['activeDirectoryGraphResourceId']
+        elif is_keyvault:
+            resource = "https://vault.azure.net"
+        else:
+            if "activeDirectoryResourceId" not in config_dict and 'resourceManagerEndpointUrl' not in config_dict:
+                raise ValueError("Need activeDirectoryResourceId or resourceManagerEndpointUrl key")
+            resource = config_dict.get('activeDirectoryResourceId', config_dict['resourceManagerEndpointUrl'])
+
+        authority_url = config_dict['activeDirectoryEndpointUrl']
+        is_adfs = bool(re.match('.+(/adfs|/adfs/)$', authority_url, re.I))
+        if is_adfs:
+            authority_url = authority_url.rstrip('/')  # workaround: ADAL is known to reject auth urls with trailing /
+        else:
+            authority_url = authority_url + '/' + config_dict['tenantId']
+
+        context = adal.AuthenticationContext(
+            authority_url,
+            api_version=None,
+            validate_authority=not is_adfs
+        )
+        parameters['credentials'] = AdalAuthentication(
+            context.acquire_token_with_client_credentials,
+            resource,
+            config_dict['clientId'],
+            config_dict['clientSecret']
+        )
+
+    parameters.update(kwargs)
+    return _instantiate_client(client_class, **parameters)
+
+def get_client_from_auth_file(client_class, auth_path=None, **kwargs):
+    """Return a SDK client initialized with auth file.
+
+    *Disclaimer*: This is NOT the recommended approach, see https://aka.ms/azsdk/python/identity/migration for guidance.
+
+    You can specific the file path directly, or fill the environment variable AZURE_AUTH_LOCATION.
+    File must be UTF-8.
+
+    This method will fill automatically the following client parameters:
+    - credentials
+    - subscription_id
+    - base_url
+
+    Parameters provided in kwargs will override parameters and be passed directly to the client.
+
+    :Example:
+
+    .. code:: python
+
+        from azure.common.client_factory import get_client_from_auth_file
+        from azure.mgmt.compute import ComputeManagementClient
+        client = get_client_from_auth_file(ComputeManagementClient)
+
+    Example of file:
+
+    .. code:: json
+
+        {
+            "clientId": "ad735158-65ca-11e7-ba4d-ecb1d756380e",
+            "clientSecret": "b70bb224-65ca-11e7-810c-ecb1d756380e",
+            "subscriptionId": "bfc42d3a-65ca-11e7-95cf-ecb1d756380e",
+            "tenantId": "c81da1d8-65ca-11e7-b1d1-ecb1d756380e",
+            "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
+            "resourceManagerEndpointUrl": "https://management.azure.com/",
+            "activeDirectoryGraphResourceId": "https://graph.windows.net/",
+            "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
+            "galleryEndpointUrl": "https://gallery.azure.com/",
+            "managementEndpointUrl": "https://management.core.windows.net/"
+        }
+
+    .. versionadded:: 1.1.7
+
+    .. deprecated:: 1.1.28
+
+    .. seealso:: https://aka.ms/azsdk/python/identity/migration
+
+    :param client_class: A SDK client class
+    :param str auth_path: Path to the file.
+    :return: An instantiated client
+    :raises: KeyError if AZURE_AUTH_LOCATION is not an environment variable and no path is provided
+    :raises: FileNotFoundError if provided file path does not exists
+    :raises: json.JSONDecodeError if provided file is not JSON valid
+    :raises: UnicodeDecodeError if file is not UTF8 compliant
+    """
+    auth_path = auth_path or os.environ['AZURE_AUTH_LOCATION']
+
+    with io.open(auth_path, 'r', encoding='utf-8-sig') as auth_fd:
+        config_dict = json.load(auth_fd)
+    return get_client_from_json_dict(client_class, config_dict, **kwargs)
diff --git a/.venv/lib/python3.12/site-packages/azure/common/cloud.py b/.venv/lib/python3.12/site-packages/azure/common/cloud.py
new file mode 100644
index 00000000..ec286e80
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/azure/common/cloud.py
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+#--------------------------------------------------------------------------
+
+def get_cli_active_cloud():
+    """Return a CLI active cloud.
+
+    *Disclaimer*: This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
+
+    .. versionadded:: 1.1.6
+
+    .. deprecated:: 1.1.28
+
+    :return: A CLI Cloud
+    :rtype: azure.cli.core.cloud.Cloud
+    :raises: ImportError if azure-cli-core package is not available
+    """
+
+    try:
+        from azure.cli.core.cloud import get_active_cloud
+    except ImportError:
+        raise ImportError(
+            "The public API of azure-cli-core has been deprecated starting 2.21.0, " +
+            "and this method no longer can return a cloud instance. " +
+            "If you want to use this method, you need to install 'azure-cli-core<2.21.0'. " +
+            "You may corrupt data if you use current CLI and old azure-cli-core."
+        )
+    return get_active_cloud()
diff --git a/.venv/lib/python3.12/site-packages/azure/common/credentials.py b/.venv/lib/python3.12/site-packages/azure/common/credentials.py
new file mode 100644
index 00000000..b653a096
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/azure/common/credentials.py
@@ -0,0 +1,171 @@
+#-------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+#--------------------------------------------------------------------------
+
+import os.path
+import time
+import warnings
+try:
+    from azure.core.credentials import AccessToken as _AccessToken
+except ImportError:
+    _AccessToken = None
+
+
+def get_cli_profile():
+    """Return a CLI profile class.
+
+    *Disclaimer*: This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
+
+    .. versionadded:: 1.1.6
+
+    .. deprecated:: 1.1.28
+
+    :return: A CLI Profile
+    :rtype: azure.cli.core._profile.Profile
+    :raises: ImportError if azure-cli-core package is not available
+    """
+
+    try:
+        from azure.cli.core._profile import Profile
+        from azure.cli.core._session import ACCOUNT
+        from azure.cli.core._environment import get_config_dir
+    except ImportError:
+        raise ImportError(
+            "The public API of azure-cli-core has been deprecated starting 2.21.0, " +
+            "and this method can no longer return a profile. " +
+            "If you need to load CLI profile using this method, you need to install 'azure-cli-core<2.21.0'. " +
+            "You may corrupt data if you use current CLI and old azure-cli-core."
+        )
+
+    azure_folder = get_config_dir()
+    ACCOUNT.load(os.path.join(azure_folder, 'azureProfile.json'))
+    return Profile(storage=ACCOUNT)
+
+
+class _CliCredentials(object):
+    """A wrapper of CLI credentials type that implements the azure-core credential protocol AND
+    the msrestazure protocol.
+
+    :param cli_profile: The CLI profile instance
+    :param resource: The resource to use in "msrestazure" mode (ignored otherwise)
+    """
+
+    _DEFAULT_PREFIX = "/.default"
+
+    def __init__(self, cli_profile, resource):
+        self._profile = cli_profile
+        self._resource = resource
+        self._cred_dict = {}
+
+    def _get_cred(self, resource):
+        if not resource in self._cred_dict:
+            credentials, _, _ = self._profile.get_login_credentials(resource=resource)
+            self._cred_dict[resource] = credentials
+        return self._cred_dict[resource]
+
+    def get_token(self, *scopes, **kwargs):  # pylint:disable=unused-argument
+        if _AccessToken is None:  # import failed
+            raise ImportError("You need to install 'azure-core' to use CLI credentials in this context")
+
+        if len(scopes) != 1:
+            raise ValueError("Multiple scopes are not supported: {}".format(scopes))
+        scope = scopes[0]
+        if scope.endswith(self._DEFAULT_PREFIX):
+            resource = scope[:-len(self._DEFAULT_PREFIX)]
+        else:
+            resource = scope
+
+        credentials = self._get_cred(resource)
+        # _token_retriever() not accessible after azure-cli-core 2.21.0
+        _, token, fulltoken = credentials._token_retriever()  # pylint:disable=protected-access
+
+        return _AccessToken(token, int(fulltoken['expiresIn'] + time.time()))
+
+    def signed_session(self, session=None):
+        credentials = self._get_cred(self._resource)
+        return credentials.signed_session(session)
+
+
+def get_azure_cli_credentials(resource=None, with_tenant=False):
+    """Return Credentials and default SubscriptionID of current loaded profile of the CLI.
+
+    *Disclaimer*: This method is not working for azure-cli-core>=2.21.0 (released in March 2021).
+    It is now recommended to authenticate using https://pypi.org/project/azure-identity/ and AzureCliCredential.
+    See example code below:
+
+    .. code:: python
+
+        from azure.identity import AzureCliCredential
+        from azure.mgmt.compute import ComputeManagementClient
+        client = ComputeManagementClient(AzureCliCredential(), subscription_id)
+
+
+    For compatible azure-cli-core version (< 2.20.0), credentials will be the "az login" command:
+    https://docs.microsoft.com/cli/azure/authenticate-azure-cli
+
+    Default subscription ID is either the only one you have, or you can define it:
+    https://docs.microsoft.com/cli/azure/manage-azure-subscriptions-azure-cli
+
+    .. versionadded:: 1.1.6
+
+    .. deprecated:: 1.1.28
+
+    .. seealso:: https://aka.ms/azsdk/python/identity/migration
+
+    :param str resource: The alternative resource for credentials if not ARM (GraphRBac, etc.)
+    :param bool with_tenant: If True, return a three-tuple with last as tenant ID
+    :return: tuple of Credentials and SubscriptionID (and tenant ID if with_tenant)
+    :rtype: tuple
+    """
+    warnings.warn(
+        "get_client_from_cli_profile is deprecated, please use azure-identity and AzureCliCredential instead. " +
+        "https://aka.ms/azsdk/python/identity/migration.",
+        DeprecationWarning
+    )
+
+    azure_cli_core_check_failed = False
+    try:
+        import azure.cli.core
+        minor_version = int(azure.cli.core.__version__.split(".")[1])
+        if minor_version >= 21:
+            azure_cli_core_check_failed = True
+    except Exception:
+        azure_cli_core_check_failed = True
+
+    if azure_cli_core_check_failed:
+        raise NotImplementedError(
+            "The public API of azure-cli-core has been deprecated starting 2.21.0, " +
+            "and this method can no longer return a valid credential. " +
+            "If you need to still use this method, you need to install 'azure-cli-core<2.21.0'. " +
+            "You may corrupt data if you use current CLI and old azure-cli-core. " +
+            "See also: https://aka.ms/azsdk/python/identity/migration"
+        )
+
+    profile = get_cli_profile()
+    cred, subscription_id, tenant_id = profile.get_login_credentials(resource=resource)
+    cred = _CliCredentials(profile, resource)
+    if with_tenant:
+        return cred, subscription_id, tenant_id
+    else:
+        return cred, subscription_id
+
+
+try:
+    from msrest.authentication import (
+        BasicAuthentication,
+        BasicTokenAuthentication,
+        OAuthTokenAuthentication
+    )
+except ImportError:
+    raise ImportError("You need to install 'msrest' to use this feature")
+
+try:
+    from msrestazure.azure_active_directory import (
+        InteractiveCredentials,
+        ServicePrincipalCredentials,
+        UserPassCredentials
+    )
+except ImportError:
+    raise ImportError("You need to install 'msrestazure' to use this feature")
diff --git a/.venv/lib/python3.12/site-packages/azure/common/exceptions.py b/.venv/lib/python3.12/site-packages/azure/common/exceptions.py
new file mode 100644
index 00000000..f4ef9c49
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/azure/common/exceptions.py
@@ -0,0 +1,22 @@
+#-------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See License.txt in the project root for
+# license information.
+#--------------------------------------------------------------------------
+try:
+    from msrest.exceptions import (
+        ClientException,
+        SerializationError,
+        DeserializationError,
+        TokenExpiredError,
+        ClientRequestError,
+        AuthenticationError,
+        HttpOperationError,
+    )
+except ImportError:
+    raise ImportError("You need to install 'msrest' to use this feature")
+
+try:
+    from msrestazure.azure_exceptions import CloudError
+except ImportError:
+    raise ImportError("You need to install 'msrestazure' to use this feature")