Office365-rest-python-client: Comment télécharger un dossier SharePoint contenant plusieurs fichiers ?

Créé le 27 mars 2019  ·  15Commentaires  ·  Source: vgrem/Office365-REST-Python-Client

Mon code Python 3:

depuis office365.runtime.auth.authentication_context importer AuthenticationContext
depuis office365.sharepoint.client_context importer ClientContext

url = ' https://company.sharepoint.com/sites/abc '
ctx_auth = AuthenticationContext(url=url)
si ctx_auth.acquire_token_for_user(username='[email protected]', password='12345'):
ctx = ClientContext(url, ctx_auth)
listes = ctx.web.lists
ctx.load(listes)
ctx.execute_query()
pour l dans les listes :
print(l.properties['Titre'])

À partir du code ci-dessus, je peux lister les éléments du site. Mais mon plan est d'exécuter l'intégralité de ce module dans AWS Lambda à l'aide de Python, de le télécharger à partir de documents SharePoint et de le stocker dans AWS S3.

Un dossier peut contenir plusieurs fichiers. Je veux télécharger le dossier entier avec tous les fichiers. Quelqu'un a fait ça ? De l'aide? Un code fonctionnel sera d'une grande aide car je suis totalement nouveau dans le grattage Web !

Commentaire le plus utile

Ne me remerciez pas, @vgrem est à blâmer :) ... et je ne suis pas sûr, il y a peut-être d'autres moyens d'obtenir la même chose ....

à droite, pour répertorier tous les dossiers de la bibliothèque de documents Shared Documents, vous pouvez essayer :

    list_object = ctx.web.lists.get_by_title(listTitle)
    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("File name: {0}".format(myfolder.properties["Name"]))

m.

Tous les 15 commentaires

Salut,
peut-être pourriez-vous le faire en boucle, par exemple :

  1. renvoyer d'abord le contenu de la bibliothèque de documents sharepoint à l'aide d'une fonction :

listTitle = "Documents"
site = "abc"

def fncPrintLibraryContents(ctx, listTitle):

try:

    list_object = ctx.web.lists.get_by_title(listTitle)
    folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()

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

    return files

except:

    print('Problem printing out library contents')   
    sys.exit(1)
  1. puis téléchargez chaque fichier en appelant un proc, par exemple :

def downloadFile (ctx, fileName):

try:
    with open(fileName, "wb") as localFile:            
        relativeUrl = '/sites/{0}/Shared%20Documents/{1}'.format(site, fileName)
        response = File.open_binary(ctx, relativeUrl)
        localFile.write(response.content) 
        localFile.close()

except:

    print('Problem downloading file:', fileName)
    sys.exit(1)

myfiles = fncPrintLibraryContents(ctx, listTitle)

pour monfichier dans mesfichiers :
print("Téléchargement du fichier : {0}".format(monfichier.properties["Nom"]))
downloadFile(ctx,` monfichier.properties["Nom"])

m.

pls, indentez les deux dernières lignes de la boucle for, je n'arrive pas à le faire.
m.

Hey,

Merci pour une réponse si rapide. Je suis en mesure de télécharger avec succès les fichiers, étant donné que je dois donner jusqu'au nom du fichier. Mais, pour pouvoir télécharger de manière récursive tous les fichiers, je dois d'abord répertorier tous ceux qui existent dans un dossier particulier qui, après plusieurs essais, obtient des erreurs Not Found. Peut-être que je me trompe quelque part, parce que mon concept de titre n'est pas correct, donc chaque fois que j'essaie de répertorier un sous-dossier en donnant ce nom comme titre, j'échoue. Je vais parcourir votre code et voir si je suis capable de le faire.

Pendant ce temps, mon code en cours d'exécution (le téléchargement fonctionne bien, la liste des dossiers et des fichiers pour la racine fonctionne mais chaque fois que dans le titre je donne un nom de dossier spécifique autre que Documents, cela échoue):

`de office365.runtime.auth.authentication_context importer AuthenticationContext
depuis office365.sharepoint.client_context importer ClientContext
à partir du fichier d'importation office365.sharepoint.file
depuis office365.sharepoint.file_creation_information importer FileCreationInformation

def read_folder_and_files(context, list_title):
"""Lire un exemple de dossier"""
list_obj = context.web.lists.get_by_title(list_title)
dossier = list_obj.root_folder
context.load(dossier)
context.execute_query()
print("Liste url : {0}".format(dossier.properties["ServerRelativeUrl"]))

files = folder.files
context.load(files)
context.execute_query()
for cur_file in files:
    print("File name: {0}".format(cur_file.properties["Name"]))

folders = context.web.folders
context.load(folders)
context.execute_query()
for folder in folders:
    print("Folder name: {0}".format(folder.properties["Name"]))

def download_file(context):
réponse = File.open_binary(contexte, "/sites/new/Shared Documents/2011-A/file1.csv")
imprimer (réponse)
imprimer(réponse.contenu)
avec open(r"C:UsersaakashbDownloadstestfile1.csv", "wb") comme fichier_local :
fichier_local.write(response.content)

ctx = aucun
url = ' https://company.sharepoint.com/sites/new '
ctx_auth = AuthenticationContext(url=url)
if ctx_auth.acquire_token_for_user(username='[email protected]', password='12345'):
ctx = ClientContext(url, ctx_auth)
read_folder_and_files(ctx, 'Documents')

print('fonction entrante')

download_file(ctx)

print('quitter la fonction')`

1) Désolé pour la structure cassée de mon code que je vous ai donné.
2) Je viens de lancer votre code et de vérifier, il fait exactement ce que mon code fait en termes de liste. Il répertorie les fichiers à la racine (pas dans un dossier). Mais je veux faire la même chose pour les dossiers.
3) Je veux aussi lister les dossiers. Lorsque j'utilise le code de liste des dossiers de

Nom du dossier : SitePages
Nom du dossier : Bibliothèque de styles
Nom du dossier : _catalogs
Nom du dossier : FormServerTemplates
Nom du dossier : _private
Nom du dossier : Liens de partage
Nom du dossier : SiteAssets
Nom du dossier : images
Nom du dossier : Documents partagés
Nom du dossier : Listes
Nom du dossier : _cts

Quels ne sont aucun des dossiers que j'ai dans le SharePoint Doc Lib.

Alors, en bref, comment puis-je lister les dossiers Doc Lib et leurs fichiers respectifs à télécharger ?

Salut,
veuillez consulter le problème ici : https://github.com/vgrem/Office365-REST-Python-Client/issues/91
spécifiquement à la ligne qui va comme ceci:

dossier = ctx.web.get_folder_by_server_relative_url(app_settings['urlrel'])

Si cela ne vous aide pas, je reviendrai vers vous pour vous fournir plus de détails.
m.

... ce que je voulais dire, c'était d'utiliser la méthode get_folder_by_server_relative_url au lieu de get_by_title, par exemple

app_settings = {'urlrel': '/sites/abc/Shared Documents/TEST'}

def printFolderContents (ctx, listTitle):

try:

    #list_object = ctx.web.lists.get_by_title(listTitle)
    folder = ctx.web.get_folder_by_server_relative_url(app_settings['urlrel'])
    #folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()
    #print(folder.url)

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

    for myfile in files:
        print("File name: {0}".format(myfile.properties["Name"]))

except:

    print('Problem printing out library contents')   
    sys.exit(1)

Dis moi si ça aide ...

pour télécharger les fichiers dans le dossier TEST de la bibliothèque de documents partagés, vous pouvez par exemple modifier le code ci-dessus pour en faire une fonction, telle que :

def fncGetFolderContents(ctx, listTitle):

try:

    #list_object = ctx.web.lists.get_by_title(listTitle)
    folder = ctx.web.get_folder_by_server_relative_url(app_settings['urlrel'])
    #folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()
    #print(folder.url)

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

    #for myfile in files:
    #    print("File name: {0}".format(myfile.properties["Name"]))

    return files

except:

    print('Problem printing out library contents')   
    sys.exit(1)

et modifiez un peu la fonction de téléchargement, par exemple :

def downloadFolderFile(ctx, fileName):

try:
    with open(fileName, "wb") as localFile:            
        relativeUrl = '/sites/{0}/Shared%20Documents/{1}/{2}'.format(site, yourFolder, fileName)
        #relativeUrl = app_settings['urlrel']
        response = File.open_binary(ctx, relativeUrl)
        localFile.write(response.content) 
        localFile.close()

except:

    print('Problem downloading file:', fileName)
    sys.exit(1)

myfiles = fncGetFolderContents(ctx, listTitle)

pour monfichier dans mesfichiers :
print("Téléchargement du fichier : {0}".format(monfichier.properties["Nom"]))
downloadFolderFile(ctx, myfile.properties["Nom"])

Merci beaucoup mec ! Vous êtes tous les deux très rapides dans les réponses, et l'API est absolument géniale !

Je vais le parcourir dès que possible et essayer de reproduire. Mais, existe-t-il un moyen de répertorier les dossiers ? Je veux dire, le dernier code que vous avez donné fonctionnera lorsque je connaîtrai le nom du dossier. Si j'automatise le processus et qu'un nouveau dossier est créé et que les fichiers sont conservés, cela ne fonctionnera pas pour le nouveau dossier, n'est-ce pas ? C'est pourquoi je voulais aussi un dossier de liste, juste au cas où. Quoi qu'il en soit, la solution actuelle devrait fonctionner pour mon cas d'utilisation.

Un grand merci à vous deux. Je mettrai à jour ici, une fois que j'aurai exécuté l'expérience.

Ne me remerciez pas, @vgrem est à blâmer :) ... et je ne suis pas sûr, il y a peut-être d'autres moyens d'obtenir la même chose ....

à droite, pour répertorier tous les dossiers de la bibliothèque de documents Shared Documents, vous pouvez essayer :

    list_object = ctx.web.lists.get_by_title(listTitle)
    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("File name: {0}".format(myfolder.properties["Name"]))

m.

Fantastique. L'impression et le téléchargement du contenu du dossier itératif ont fonctionné !

Merci,

Ce code télécharge les fichiers pdf corrompus. Ils sont vides - 156 octets. Des idées pourquoi?

Je reçois également des fichiers pdf corrompus avec seulement 1 Ko de nom de fichier en utilisant le code ci-dessus. Une idée?

Je reçois également des fichiers pdf corrompus avec seulement 1 Ko de nom de fichier en utilisant le code ci-dessus. Une idée?

Je l'ai compris, pour moi la raison était l'URL relative. Lorsque j'ai besoin de répertorier le contenu d'un dossier, je n'ai pas besoin d'ajouter /sites/sitename/library etc., il doit simplement s'agir de /library. Mais lorsque je télécharge déjà les fichiers, je dois ajouter /sites/sitename/folder/file.

C'est vraiment bizarre, car je peux toujours accéder et télécharger des fichiers sans ajouter /sites/sitename/, mais le contenu est alors corrompu. Dans le même temps, si j'ajoute /sites/sitename/ lorsque je reçois le contenu du dossier, cela génère une erreur et ne fonctionne que si je démarre l'URL relative avec une bibliothèque.

Il est étrange que chaque ressource suggère d'ajouter /sites/sitename à l'URL relative à la fois pour le contenu du dossier et le contenu du fichier.

Merci pour la suggestion. pouvez-vous partager le code de travail final. Si nous voulons télécharger tout le contenu du sous-dossier comme /sites/sitename/Documents/somefolder, quel serait le code final ?

Merci les gars. Cela aide à résoudre de nombreux problèmes et problèmes rencontrés lors de l'utilisation du package Sharepoint.

Cette page vous a été utile?
0 / 5 - 0 notes