Search code examples
pythonazuremicrosoft-graph-apioffice365microsoft-graph-sdks

msgraph-sdk-python not returning any data


I took reference from https://learn.microsoft.com/en-us/graph/tutorials/python-app-only?tabs=aad.

Copied and pasted the exact code but it is not returning list of users. It is returning access token though.

main.py file:-

import asyncio
import configparser
from msgraph.generated.models.o_data_errors.o_data_error import ODataError
from graph import Graph

async def main():
    print('Python Graph App-Only Tutorial\n')

    # Load settings
    config = configparser.ConfigParser()
    config.read(['config.cfg', 'config.dev.cfg'])
    azure_settings = config['azure']

    graph: Graph = Graph(azure_settings)

    choice = -1

    while choice != 0:
        print('Please choose one of the following options:')
        print('0. Exit')
        print('1. Display access token')
        print('2. List users')
        print('3. Me')

        try:
            choice = int(input())
        except ValueError:
            choice = -1

        try:
            if choice == 0:
                print('Goodbye...')
            elif choice == 1:
                await display_access_token(graph)
            elif choice == 2:
                await list_users(graph)
            elif choice == 3:
                await mee(graph)
            else:
                print('Invalid choice!\n')
        except ODataError as odata_error:
            print('Error:')
            if odata_error.error:
                print(odata_error.error.code, odata_error.error.message)

async def display_access_token(graph: Graph):
    token = await graph.get_app_only_token()
    print('App-only token:', token, '\n')

async def list_users(graph: Graph):
    users_page = await graph.get_users()
    print(users_page)

    # Output each users's details
    if users_page and users_page.value:
        for user in users_page.value:
            print('User:', user.display_name)
            print('  ID:', user.id)
            print('  Email:', user.mail)

        # If @odata.nextLink is present
        more_available = users_page.odata_next_link is not None
        print('\nMore users available?', more_available, '\n')


async def mee(graph: Graph):
    user = await graph.me()

async def make_graph_call(graph: Graph):
    # TODO
    return

# Run main
asyncio.run(main())

**--------------------------------------------------------------------------- graph.py file:-


from configparser import SectionProxy
from azure.identity.aio import ClientSecretCredential
from kiota_authentication_azure.azure_identity_authentication_provider import (
    AzureIdentityAuthenticationProvider
)
from msgraph import GraphRequestAdapter, GraphServiceClient
from msgraph.generated.users.users_request_builder import UsersRequestBuilder
from kiota_abstractions.api_error import APIError
import asyncio
class Graph:
    settings: SectionProxy
    client_credential: ClientSecretCredential
    adapter: GraphRequestAdapter
    app_client: GraphServiceClient

    def __init__(self, config: SectionProxy):
        self.settings = config
        client_id = self.settings['clientId']
        tenant_id = self.settings['tenantId']
        client_secret = self.settings['clientSecret']

        self.client_credential = ClientSecretCredential(tenant_id, client_id, client_secret)
        auth_provider = AzureIdentityAuthenticationProvider(self.client_credential) # type: ignore
        self.adapter = GraphRequestAdapter(auth_provider)
        self.app_client = GraphServiceClient(self.adapter)

    async def get_app_only_token(self):
        graph_scope = 'https://graph.microsoft.com/.default'
        access_token = await self.client_credential.get_token(graph_scope)
        return access_token.token
    
    async def get_users(self):
        try:
            query_params = UsersRequestBuilder.UsersRequestBuilderGetQueryParameters(
                # Only request specific properties
                select = ['displayName', 'id', 'mail'],
                # Get at most 25 results
                top = 25,
                # Sort by display name
                orderby= ['displayName']
            )
            request_config = UsersRequestBuilder.UsersRequestBuilderGetRequestConfiguration(
                query_parameters=query_params
            )

            users = await self.app_client.users.get(request_configuration=request_config)
            return users
        except APIError as e:
            print(f'Error: {e.error.message}')
            

    async def me(self):
        try:
            me = await self.app_client.me.get()
            if me:
                print(me)
        except APIError as e:
            print(f'Error: {e}')



Output

Output


Solution

  • I took reference from https://learn.microsoft.com/en-us/graph/tutorials/python-app-only?tabs=aad. Copied and pasted the exact code but it is not returning list of users. It is returning access token though.

    I tried with same document in my environment and even for me it is not listing users, it returns access token though.

    enter image description here

    Alternatively, you can use the below code to get the list of users using Python.

    Code:

    import requests
    import json
    
    
    tenant_id=""
    client_id=""
    client_secret=""
    
    token_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" 
    data = {
          "grant_type": "client_credentials",
          "client_id": f"{client_id}",  
          "client_secret": f"{client_secret}",  
          "scope": "https://graph.microsoft.com/.default"
        }
    response = requests.post(token_endpoint, data=data)
    access_token = response.json()["access_token"]
    # print("Access Token:", access_token)
    
    url = "https://graph.microsoft.com/v1.0/users"
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }
    
    # Send the request to the API endpoint
    response = requests.get(url, headers=headers)
    
    # Parse the response JSON
    users = json.loads(response.text)
    # Print the list of users
    for user in users["value"]:
        print("List of Users:")
        print(user["displayName"])
    

    Output:

    List of Users:
    MOD xxxr
    Alex xxxx
    Allan xxx
    Demo Kxxxx
    Demo xxxx1
    Demo xxxxr
    Dexx
    Diego xxxxx
    emovaya
    employee
    evenyxxxxx
    Exchangexxxx
    

    enter image description here