微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

异常:AttributeError:使用Azure函数和Python的'DefaultAzureCredential'对象没有属性'signed_session'

如何解决异常:AttributeError:使用Azure函数和Python的'DefaultAzureCredential'对象没有属性'signed_session'

我编写了一个运行python3的Azure函数,以简单地打开Azure VM。

功能应用程序有一个系统分配的受管理身份,我已经授予该角色VM贡献者角色。要使该功能使用托管身份,我正在使用DefaultAzureCredential()类。

我得到的错误是: Exception: AttributeError: 'DefaultAzureCredential' object has no attribute 'signed_session' 我已经进行了大量研究,但似乎找不到解决方法

以下是相关代码

from azure.identity import DefaultAzureCredential
credentials = DefaultAzureCredential()
compute_client = ComputeManagementClient(credentials,subscription_id)
# Starting the VM
print('\nStarting VM ' + VM_NAME)
vm_start = compute_client.virtual_machines.start(
    RG_NAME,VM_NAME)
vm_start.wait()

您必须原谅我,我只是Python的新手,但对学习非常感兴趣。

解决方法

如果使用azure-mgmt-compute(17.0.0b1)的预览版,它似乎已修复

另一个由于版本颠簸而引起的麻烦是他们将启动功能从start更改为begin_start。

希望这对某人有帮助!

,

此问题在此处解决:https://docs.microsoft.com/en-us/azure/developer/python/azure-sdk-authenticate?tabs=cmd

在此页面上搜索“将DefaultAzureCredential与SDK管理库一起使用”,它将带您到详细介绍问题的部分。

简而言之。...

他们更新了DefaultAzureCredential类,并且不再具有'signed_session'属性。应该更新管理库的最新版本以解决此问题。如另一种解决方案中所述,更新您的azure-cli库以确保您具有最新版本。但是,并非所有管理库都已更新。您可以暂时使用由Azure SDK工程团队的成员创建的包装。 https://gist.github.com/lmazuel/cc683d82ea1d7b40208de7c9fc8de59d

# Wrap credentials from azure-identity to be compatible with SDK that needs msrestazure or azure.common.credentials
# Need msrest >= 0.6.0
# See also https://pypi.org/project/azure-identity/

from msrest.authentication import BasicTokenAuthentication
from azure.core.pipeline.policies import BearerTokenCredentialPolicy
from azure.core.pipeline import PipelineRequest,PipelineContext
from azure.core.pipeline.transport import HttpRequest

from azure.identity import DefaultAzureCredential

class CredentialWrapper(BasicTokenAuthentication):
    def __init__(self,credential=None,resource_id="https://management.azure.com/.default",**kwargs):
        """Wrap any azure-identity credential to work with SDK that needs azure.common.credentials/msrestazure.
        Default resource is ARM (syntax of endpoint v2)
        :param credential: Any azure-identity credential (DefaultAzureCredential by default)
        :param str resource_id: The scope to use to get the token (default ARM)
        """
        super(CredentialWrapper,self).__init__(None)
        if credential is None:
            credential = DefaultAzureCredential()
        self._policy = BearerTokenCredentialPolicy(credential,resource_id,**kwargs)

    def _make_request(self):
        return PipelineRequest(
            HttpRequest(
                "CredentialWrapper","https://fakeurl"
            ),PipelineContext(None)
        )

    def set_token(self):
        """Ask the azure-core BearerTokenCredentialPolicy policy to get a token.
        Using the policy gives us for free the caching system of azure-core.
        We could make this code simpler by using private method,but by definition
        I can't assure they will be there forever,so mocking a fake call to the policy
        to extract the token,using 100% public API."""
        request = self._make_request()
        self._policy.on_request(request)
        # Read Authorization,and get the second part after Bearer
        token = request.http_request.headers["Authorization"].split(" ",1)[1]
        self.token = {"access_token": token}

    def signed_session(self,session=None):
        self.set_token()
        return super(CredentialWrapper,self).signed_session(session)

if __name__ == "__main__":
    import os
    credentials = CredentialWrapper()
    subscription_id = os.environ.get("AZURE_SUBSCRIPTION_ID","<subscription_id>")

    from azure.mgmt.resource import ResourceManagementClient
    client = ResourceManagementClient(credentials,subscription_id)
    for rg in client.resource_groups.list():
        print(rg.name)

您的代码将如下所示:

from cred_wrapper import CredentialWrapper
credentials = CredentialWrapper()
compute_client = ComputeManagementClient(credentials,subscription_id)
# Starting the VM
print('\nStarting VM ' + VM_NAME)
vm_start = compute_client.virtual_machines.start(
    RG_NAME,VM_NAME)
vm_start.wait()

你应该从那里做饭!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。