How to programmatically access Sharepoint sites other than root from Office365-REST-Python-Client?

1.4k Views Asked by At

I need to programmatically access my organization's Office 365 Sharepoint. In particular, at the moment I need to be able to upload and download files from specific lists/paths.

I created an Azure AD application using this manual and granted Sites.FullControl.All permission (consent was granted by the admin as well).

enter image description here

I am using Office365-REST-Python-Client Python library for calling Sharepoint API, which seems to be a well-maintained library and accepted in the Sharepoint community.

I was able to authenticate as my app using a certificate I created:

from office365.sharepoint.client_context import ClientContext

base_url = 'https://my-company.sharepoint.com/'

cert_auth_data = dict(
    tenant='61ad46cb-b256-451d-9b4c-b592d46a7dc1',
    client_id='b3af34ed-1335-468b-a82b-d0cf6ec79683',
    thumbprint='815B134CD6D15EB0F07D247940AA6EF96263859F',
    cert_path='selfsigncert.pem',
)

ctx = ClientContext(base_url).with_client_certificate(**cert_auth_data)
res = ctx.web.get().execute_query()
print(res.properties['Title'])  # Works

Now I need to access a specific site in the portal, and this is where I start having problems. If I put https://my-company.sharepoint.com/sites/mysite as URL, I receive the following error:

ValueError: {'error': 'invalid_resource', 'error_description': 'AADSTS500011: The resource principal named https://my-company.sharepoint.com/sites/mysite was not found in the tenant named My Company Limited. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: e8bbbe6c-f5ef-4d6a-8635-0848184e1801\r\nCorrelation ID: f6a57e34-886a-4247-8a4e-194f098876ed\r\nTimestamp: 2022-05-12 02:26:44Z', 'error_codes': [500011], 'timestamp': '2022-05-12 02:26:44Z', 'trace_id': 'e8bbbe6c-f5ef-4d6a-8635-0848184e1801', 'correlation_id': 'f6a57e34-886a-4247-8a4e-194f098876ed', 'error_uri': 'https://login.microsoftonline.com/error?code=500011'}

I assumed I can somehow reach the site from the ClientContext of the base URL, but I could not figure how to do it and if that is possible at all.

I tried to use Site API:

site = Site.from_url(site_url)

But I see that Site lacks with_client_certificate() (as opposed to ClientContext) and has only with_credentials() method. I added such a method similarly to ClientContext:

    def with_client_certificate(self, tenant, client_id, thumbprint, cert_path, **kwargs):
        self.context.with_client_certificate(tenant, client_id, thumbprint, cert_path, **kwargs)
        return self

However in this case authorization fails with the same error as above.

  1. Is my application lacking some permissions? If yes, how to fix that?
  2. Am I using the library properly? I failed to find good examples in their repo for my case, but other resources suggest that using site URL is probably the right way [1], [2].
0

There are 0 best solutions below