1

Objective: To build a python script which will download all the files from a SharePoint Document Library and store in the same folder structure (including subfolders till the N-th)

Using: Python 3.6 and a great SharePoint REST API tool by @Vadim Gremyachev

Done till now:

a) Retrieving list of folders in root

b) Retrieving list of files and folders in a given folder

c) Downloading files iteratively from a given folder

I am not an expert in recursion logic and need some help to go about this problem.

Sample Code:

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


def print_folder_contents(ctx, folder_name):

    try:
        folder = ctx.web.get_folder_by_server_relative_url("/sites/abc/Shared Documents/"+folder_name+"/")
        ctx.load(folder)
        ctx.execute_query()

        # Folders
        fold_names = []
        sub_folders = folder.folders
        ctx.load(sub_folders)
        ctx.execute_query()
        for s_folder in sub_folders:
            # print("Folder name: {0}".format(folder.properties["Name"]))
            fold_names.append(s_folder.properties["Name"])


        # Files
        f_names = []
        files = folder.files
        ctx.load(files)
        ctx.execute_query()
        for myfile in files:
            # print("File name: {0}".format(myfile.properties["Name"]))
            f_names.append(myfile.properties["Name"])
        return fold_names, f_names

    except Exception as e:
        print('Problem printing out library contents: ', e)


def print_root_contents(ctx):

    try:
        list_object = ctx.web.lists.get_by_title('Documents')
        folder = list_object.root_folder
        ctx.load(folder)
        ctx.execute_query()

        folders = folder.folders
        ctx.load(folders)
        ctx.execute_query()

        for myfolder in folders:
            print("For Folder : {0}".format(myfolder.properties["Name"]))
            folder_list, files_list = print_folder_contents(ctx)  # , myfolder.properties["Name"])
            print("Sub folders - ", folder_list)
            print("Files - ", files_list)

    except Exception as e:
        print('Problem printing out library contents: ', e)

ctx = None
folder_name = 'alpha_test'
url = 'https://company.sharepoint.com/sites/abc'
ctx_auth = AuthenticationContext(url=url)
if ctx_auth.acquire_token_for_user(username='id', password='pass'):
    ctx = ClientContext(url, ctx_auth)
print_root_contents(ctx)

The above code works perfectly file in listing all root level folders and one level internal subfolders and files list. I need a JSON (python dict) representing the directory structure.

Example of python dict (fi: files, fo: folders):

Eg: 1

{
  "root": [
    {
      "fo1": [
        "fi1",
        "fi2"
      ],
      "fo2": [
        "fi1",
        "fi2"
      ]
    },
    "fi1",
    "fi2"
  ]
}

Eg: 2

{
  "root": [
    {
      "fo1": {
        "fo1": "f1",
        "fo2": [
          "f1",
          "f2"
        ]
      },
      "fo2": [
        "fi1",
        "fi2"
      ]
    },
    "fi1",
    "fi2"
  ]
}
Aakash Basu
  • 1,137
  • 2
  • 15
  • 39
  • Trying to replicate your code, I get this error: *ModuleNotFoundError: No module named 'web'*. Any idea why? – RenauV Jun 26 '19 at 14:23
  • Sorry to open such an old thread. Im trying to implement something similar to your base code without the JSON part. When I get to the print_root_contents, i bump into the following error: 'List' object has no attribute 'root_folder'. Do you have any ideas? – Batteredburrito Oct 29 '20 at 12:32

0 Answers0