0
votes

I am trying to upload documents to the SharePoint online.

Target url: https://companyURL.sharepoint.com/sites/A/B/Info_documents/C

My aim is to search folder C, and if X subfolder is present in folder C, I need to upload a file. To accomplish this, I have generated client_id and client_secret by navigating to http://{sharepointsite}/_layouts/15/AppRegNew.aspx. In the XML permissions, I gave the following code:

I am using https://github.com/vgrem/Office365-REST-Python-Client for this implementation. When trying to use the following code snippet to see, if I am having the access to sharepoint using client_id and client_secret, i am seeing different errors:

    import json

from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.runtime.client_request import ClientRequest
from office365.runtime.utilities.request_options import RequestOptions
from office365.sharepoint.client_context import ClientContext


app_settings = {
    'url': 'https://companyURL.sharepoint.com/sites/A/B/Info_documents/C',
    'client_id': 'xxxxxxxx',
    'client_secret': 'xxxxxx',
}

context_auth = AuthenticationContext(url=app_settings['url'])
context_auth.acquire_token_for_app(client_id=app_settings['client_id'], client_secret=app_settings['client_secret'])

ctx = ClientContext(app_settings['url'], context_auth)
web = ctx.web
ctx.load(web)
ctx.execute_query()
print("Web site title: {0}".format(web.properties['Title']))

Error: ClientRequestException: ('-2147024891, System.UnauthorizedAccessException', 'Access denied. You do not have permission to perform this action or access this resource.', '403 Client Error: Forbidden for url: https://companyURL.sharepoint.com/sites/A/B/Info_documents/C_api/Web')

But I gave the permissions, not sure whether I am doing wrong or selected the wrong module.

Please help.

Following is the XML code i gave when generating the client_ID and client_secret:

<AppPermissionRequests AllowAppOnlyPolicy="true">
       <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read"/>
       <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write"/>
     </AppPermissionRequests>
1

1 Answers

1
votes

Given the description

My aim is to search folder C, and if X subfolder is present in folder C, I need to upload a file.

and the the following link format:

https://companyURL.sharepoint.com/sites/A/B/Info_documents/C

your folder structure could be represented like this:

https://companyURL.sharepoint.com/sites/A/B/  <-this is the actual site url
          |
   Info_documents <-library
              |
          C <-folder

Since AuthenticationContext class accepts the first parameter to be site url, app_settings needs to be updated like this:

app_settings = {
    'url': 'https://companyURL.sharepoint.com/sites/A/B/',  //need to refer to site url
    'client_id': '--client id goes here--',
    'client_secret': '--client secret goes here--',
}

Now comes the turn of App principal, since the requested permissions are applicable per web (scope: http://sharepoint/content/sitecollection/web), the second step (granting permissions) needs to be accomplished per specified web:

https://companyURL.sharepoint.com/sites/A/B/_layouts/15/appinv.aspx

Example

Here is an example which demonstrates how to verify if sub folder exists under the parent folder:

context_auth = AuthenticationContext(url=app_settings['url'])
context_auth.acquire_token_for_app(client_id=app_settings['client_id'], 
client_secret=app_settings['client_secret'])
ctx = ClientContext(app_settings['url'], context_auth)

folder_url = "Info_documents/C"  #folder url where to find 
folder_name = "X"  #folder name to find
result = ctx.web.get_folder_by_server_relative_url(folder_url).folders.filter("Name eq '{0}'".format(folder_name))
ctx.load(result)
ctx.execute_query()
if len(result) > 0:
    print("Folder has been found: {0}".format(result[0].properties["Name"]))