Office365-REST-Python-Client icon indicating copy to clipboard operation
Office365-REST-Python-Client copied to clipboard

Client object breaks trying to call method

Open PyMap opened this issue 4 years ago • 4 comments

Hi all! Working with onedrive API I found out that, once I instantiate the client = GraphClient(acquire_token_func(tenant_id, client_id, client_secret)):

image

I think that the error happens here https://github.com/vgrem/Office365-REST-Python-Client/blob/master/office365/graph_client.py#L94

... because the _acquire_token_callback() shouldn't be called as a method. At least, when I explore this: client._acquire_token_callback['access_token']

the access token shows up correctly (which make me infer that client id, secret and tenant are good

PyMap avatar Aug 23 '21 22:08 PyMap

Greetings!

GraphClient class constructor accept a callback function as an input argument, for example:

client = GraphClient(acquire_token_by_client_credentials)

where

def acquire_token_by_client_credentials():
    authority_url = 'https://login.microsoftonline.com/{0}'.format(tenant_name)
    app = msal.ConfidentialClientApplication(
        authority=authority_url,
        client_id=client_id,
        client_credential=client_secret
    )
    return app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])

The callback function is expected to return a dict representing the json token (which should contain access_token key):

{
   'token_type': 'Bearer', 
   'scope': 'profile openid email https://graph.microsoft.com/Mail.Send', 
   'access_token': '--access token goes here--', 
}

By default Microsoft Authentication Library (MSAL) for Python library is utilized to acquire tokens.

And finally, callback function gets invoked during authenticate_request call by library.

vgrem avatar Aug 24 '21 06:08 vgrem

@vgrem thanks for the explanation! The client object I'm showing in the first post was instantiated in the same way you do. I mean, by calling the acquire_token_by_client_credentials method with my tenant, client id and secret.

When I try to call drive items from the client object, like this

drives = client.drives.get().execute_query()

... then the error I showed in the post raises up.

I manage to get my token if I do the following:

client._acquire_token_callback

This returns me something like:

{'access_token': 'my_token',
 'expires_in': 86399,
 'ext_expires_in': 86399,
 'token_type': 'Bearer'}

In the description, the error shows that method breaks when trying to call the callback function. But if I try it out of the client.drives.get() (like I showed you above) it works fine:

image

To sum up, in my case this is breaking in line 94 of the graph_client.py when trying to do token_json = self._acquire_token_callback(). That's why I'm asking if it should be _acquire_token_callback instead.

I'm not managing to instantiate the drives object to call the .web_url attribute

PyMap avatar Aug 24 '21 13:08 PyMap

Hi PyMap,

I have started working with vgrem's package only yesterday and following his examples worked fine for me. But then I restructured and integrated the code in my existing code - and accidentally initiated the client instances by calling the acquire_token_func using "() "at the end: client = GraphClient(acquire_token_func()) - this produced exactly the error you are describing here also for me... did you iniate the client perhaps also with "()"

not1q84-1 avatar Nov 12 '21 08:11 not1q84-1

The callback function needs to return an instance of office365.runtime.auth.token_response.TokenResponse not a dict.

    token = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
    return TokenResponse(**token)

works for me.

jgentil avatar Feb 08 '22 18:02 jgentil