0

I can get Azure subscriptons list using REST API.

However, when I'm switching to Azure Python SDK, there seems to be some problems.

This is the code so far:

from azure.identity.aio import ClientSecretCredential
from azure.mgmt.resource import SubscriptionClient
import json

data = json.load(open("parameters.json"))

credential = ClientSecretCredential(
    tenant_id=data["tenant"],
    client_id=data["client_id"],
    client_secret=data["client_secret"],
)

subs = SubscriptionClient(credential=credential)
l = list(subs.subscriptions.list())
print(l)

I use an additional list in the pnultimate line because subs.subscriptions.list() returns an iterator. Despite that, the code seems pretty straightforward.

However, this code gives the following error:

Traceback (most recent call last):
  File "c:\Users\azureuser\Documents\GitHub\vmss-scripts\vm_create.py", line 14, in <module>
    l = list(subs.subscriptions.list())
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\paging.py", line 123, in __next__
    return next(self._page_iterator)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\paging.py", line 75, in __next__
    self._response = self._get_next(self.continuation_token)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\mgmt\resource\subscriptions\v2022_12_01\operations\_operations.py", line 526, in get_next
    pipeline_response: PipelineResponse = self._client._pipeline.run(  # pylint: disable=protected-access
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\_base.py", line 230, in run
    return first_node.send(pipeline_request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\_base.py", line 86, in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\_base.py", line 86, in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\_base.py", line 86, in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
  [Previous line repeated 2 more times]
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\mgmt\core\policies\_base.py", line 46, in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\policies\_redirect.py", line 197, in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\policies\_retry.py", line 531, in send
    response = self.next.send(request)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\policies\_authentication.py", line 124, in send
    self.on_request(request)
  File "C:\Users\azureuser\scoop\apps\python\current\Lib\site-packages\azure\core\pipeline\policies\_authentication.py", line 100, in on_request
    self._update_headers(request.http_request.headers, self._token.token)
                                                       ^^^^^^^^^^^^^^^^^
AttributeError: 'coroutine' object has no attribute 'token'
sys:1: RuntimeWarning: coroutine 'GetTokenMixin.get_token' was never awaited

I don't know what was missing, and the error didn't gives much information.

It seems it was related with token. I can get a token with the following method:

async def print_token():
    token = await credential.get_token("https://management.azure.com/.default")
    print(token.token)
    await credential.close()

asyncio.run(print_token())

But it requires asyncio to run, which isn't compatible with my code. And where should I should put the token?

I've investigated the source code if Azure CLI. It seems it get subscriptions using the same method: https://github.com/Azure/azure-cli/blob/f369cead2604e37480611b0cc269fee615956ea2/src/azure-cli-core/azure/cli/core/_profile.py#L835

The client was acqurired from the function below, and the type was

https://github.com/Azure/azure-cli/blob/f369cead2604e37480611b0cc269fee615956ea2/src/azure-cli-core/azure/cli/core/profiles/_shared.py#L60

Which is essentially the SubscriptionClient.

1
  • from azure.identity import ClientSecretCredential Commented May 21, 2024 at 6:11

2 Answers 2

1

Initially, I too got same error when I ran your code in my environment like this:

from azure.identity.aio import ClientSecretCredential
from azure.mgmt.resource import SubscriptionClient
import json

data = json.load(open("parameters.json"))

credential = ClientSecretCredential(
    tenant_id=data["tenant"],
    client_id=data["client_id"],
    client_secret=data["client_secret"],
)

subs = SubscriptionClient(credential=credential)
l = list(subs.subscriptions.list())
print(l)

Response:

enter image description here

To list subscriptions using Azure Python SDK without asyncio module, make use of below modified code:

from azure.identity import ClientSecretCredential
from azure.mgmt.resource import SubscriptionClient
import json

with open("parameters.json") as f:
    data = json.load(f)

credential = ClientSecretCredential(
    tenant_id=data["tenant"],
    client_id=data["client_id"],
    client_secret=data["client_secret"],
)

subs_client = SubscriptionClient(credential)

subscriptions = subs_client.subscriptions.list()

for subscription in subscriptions:
    #print(f"Subscription ID: {subscription.subscription_id}, Display Name: {subscription.display_name}")
    print(json.dumps(subscription.as_dict(), indent=2))

Response:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

0

Also, this is the code for async version.

import asyncio
from azure.identity.aio import ClientSecretCredential
from azure.mgmt.resource.subscriptions.aio import SubscriptionClient
import json

data = None
with open("parameters.json") as f:
    data = json.load(f)


async def app():
    credential = ClientSecretCredential(
        tenant_id=data["tenant"],
        client_id=data["client_id"],
        client_secret=data["client_secret"],
    )

    subs_client = SubscriptionClient(credential)

    subscriptions = subs_client.subscriptions.list()

    async for subscription in subscriptions:
        # print(f"Subscription ID: {subscription.subscription_id}, Display Name: {subscription.display_name}")
        print(json.dumps(subscription.as_dict(), indent=2))

    await subs_client.close()
    await credential.close()


asyncio.run(app())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.