0

I am using Office365-REST-Python-Client to connect to a SharePoint server with Python:

from office365.sharepoint.client_context import ClientContext
from office365.runtime.auth.userCredential import UserCredential

username = 'email_address'
password = 'password'
ctx = ClientContext("https://[tenant].sharepoint.com/sites/mySite").with_credentials(UserCredential(username, password))
web = ctx.web.load().execute_query()

This results in:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-14-a0545a904a3e> in <module>
      2 password = 'password'
      3 ctx = ClientContext("https://[tenant].sharepoint.com/sites/mySite").with_credentials(UserCredential(username, password))
----> 4 web = ctx.web.load().execute_query()

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\sharepoint\base_entity.py in execute_query(self)
     22 
     23     def execute_query(self):
---> 24         self.context.execute_query()
     25         return self
     26 

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\runtime\client_runtime_context.py in execute_query(self)
     54     def execute_query(self):
     55         while self.has_pending_request:
---> 56             self.get_pending_request().execute_query()
     57             query = self.get_pending_request().current_query
     58             self.afterExecuteOnce.notify(query.return_type)

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\runtime\client_request.py in execute_query(self)
     39             request = self.build_request()
     40             self.beforeExecute.notify(request)
---> 41             response = self.execute_request_direct(request)
     42             response.raise_for_status()
     43             self.process_response(response)

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\runtime\odata\odata_request.py in execute_request_direct(self, request)
     35         request.ensure_header('Content-Type', media_type)
     36         request.ensure_header('Accept', media_type)
---> 37         return super(ODataRequest, self).execute_request_direct(request)
     38 
     39     @property

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\runtime\client_request.py in execute_request_direct(self, request_options)
     51         :type request_options: RequestOptions
     52         """
---> 53         self.context.authenticate_request(request_options)
     54         if request_options.method == HttpMethod.Post:
     55             if request_options.is_bytes or request_options.is_file:

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\sharepoint\client_context.py in authenticate_request(self, request)
    115     def authenticate_request(self, request):
    116         if not self.authentication_context.is_authenticated:
--> 117             self.authentication_context.acquire_token()
    118 
    119         super(ClientContext, self).authenticate_request(request)

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\runtime\auth\authentication_context.py in acquire_token(self)
     36             return self.acquire_token_for_app(self.credentials.clientId, self.credentials.clientSecret)
     37         elif isinstance(self.credentials, UserCredential):
---> 38             return self.acquire_token_for_user(self.credentials.userName, self.credentials.password)
     39         else:
     40             raise ValueError("Unknown credential type")

C:\ProgramData\Anaconda3\envs\office365\lib\site-packages\office365\runtime\auth\authentication_context.py in acquire_token_for_user(self, username, password)
     48         self.provider = SamlTokenProvider(self.url, username, password)
     49         if not self.provider.acquire_token():
---> 50             raise ValueError('Acquire token failed: {0}'.format(self.provider.error))
     51         return True
     52 

ValueError: Acquire token failed: Error: HTTPSConnectionPool(host='[tenant].sharepoint.com', port=port_number): Max retries exceeded with url: /_forms/default.aspx?wa=wsignin1.0 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)')))

I tried adding the site certificate to the certifi cacert.pem file with the top answer here: Unable to get local issuer certificate when using requests in python, but this resulted in the same error.

My versions are:

  • certifi: 2020.6.20
  • Office365-REST-Python-Client: 2.1.10
  • Python: 3.8.3

What other steps can I take to resolve this error?

OverflowingTheGlass
  • 2,324
  • 1
  • 27
  • 75

1 Answers1

0

Have you tried hardcoding your Site URL without the "[tenant]?"

I never got user authentication to work because my company uses two factor authentication. I used sharepoints app-only authentication

Details on how to do that are here:

https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly

Do the step in: https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azureacs using the proper URL based upon Site Collection (even for Library scope.)

Determine the Permission XML from: https://medium.com/ng-sp/sharepoint-add-in-permission-xml-cheat-sheet-64b87d8d7600
Either #2 (Site Collection) or #4 (specific Library\List) sounds good for your need.

This code worked for me once I had the above steps finished.

from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.file import File 



context_auth = AuthenticationContext(url=site_url)            #Gets the API enviornment to authenticate with
#get's a token to make the api client
context_auth.acquire_token_for_app(client_id, client_secret)  

ctx = ClientContext(site_url, context_auth)                    #makes my reusable client to make requests to the API
web = ctx.web                                                  #loads the web data 
ctx.load(web)                                                  #
ctx.execute_query()                                            #
Pablo
  • 11
  • 1