web-dev-qa-db-fra.com

télécharger un répertoire vers s3 avec boto

Je suis déjà connecté à l'instance et je souhaite télécharger les fichiers générés à partir de mon script python directement sur S3. J'ai essayé ceci:

import boto
s3 = boto.connect_s3()
bucket = s3.get_bucket('alexandrabucket')
from boto.s3.key import Key
key = bucket.new_key('s0').set_contents_from_string('some content')

mais il s'agit plutôt de créer un nouveau fichier s0 avec le contexte "même contenu" alors que je souhaite uploader le répertoire s0 sur mybucket.

J'ai également regardé s3put mais je n'ai pas réussi à obtenir ce que je voulais.

15
user3333539

Il n'y a rien dans la bibliothèque boto elle-même qui vous permettrait de télécharger un répertoire entier. Vous pouvez écrire votre propre code pour parcourir le répertoire en utilisant os.walk ou similaire et pour télécharger chaque fichier individuel à l'aide de boto.

Il existe un utilitaire de ligne de commande dans boto appelé s3put qui pourrait gérer cela ou vous pourriez utiliser outil AWS CLI qui a beaucoup de fonctionnalités qui vous permettent de télécharger des répertoires entiers ou même de synchroniser le compartiment S3 avec un répertoire local ou vice-versa.

16
garnaat

La fonction suivante peut être utilisée pour télécharger un répertoire vers s3 via boto.

    def uploadDirectory(path,bucketname):
        for root,dirs,files in os.walk(path):
            for file in files:
                s3C.upload_file(os.path.join(root,file),bucketname,file)

Fournissez un chemin d'accès au répertoire et au nom du compartiment comme entrées. Les fichiers sont placés directement dans le compartiment. Modifiez la dernière variable de la fonction upload_file () pour les placer dans des "répertoires".

5
JDPTET

Vous pouvez effectuer les opérations suivantes:

import os
import boto3

s3_resource = boto3.resource("s3", region_name="us-east-1")

def upload_objects():
    try:
        bucket_name = "S3_Bucket_Name" #s3 bucket name
        root_path = 'D:/sample/' # local folder for upload

        my_bucket = s3_resource.Bucket(bucket_name)

        for path, subdirs, files in os.walk(root_path):
            path = path.replace("\\","/")
            directory_name = path.replace(root_path,"")
            for file in files:
                my_bucket.upload_file(os.path.join(path, file), directory_name+'/'+file)

    except Exception as err:
        print(err)

if __name__ == '__main__':
    upload_objects()
2
Gowtham Balusamy

J'ai construit la fonction sur la base des commentaires de @JDPTET, cependant,

  1. J'avais besoin de supprimer le chemin d'accès local complet de la mise en ligne dans le compartiment!
  2. Je ne sais pas combien de séparateurs de chemin je rencontre - j'ai donc dû utiliser os.path.normpath
    def upload_folder_to_s3(s3bucket, inputDir, s3Path):
        print("Uploading results to s3 initiated...")
        print("Local Source:",inputDir)
        os.system("ls -ltR " + inputDir)

        print("Dest  S3path:",s3Path)

        try:
            for path, subdirs, files in os.walk(inputDir):
                for file in files:
                    dest_path = path.replace(inputDir,"")
                    __s3file = os.path.normpath(s3Path + '/' + dest_path + '/' + file)
                    __local_file = os.path.join(path, file)
                    print("upload : ", __local_file, " to Target: ", __s3file, end="")
                    s3bucket.upload_file(__local_file, __s3file)
                    print(" ...Success")
        except Exception as e:
            print(" ... Failed!! Quitting Upload!!")
            print(e)
            raise e

    s3 = boto3.resource('s3', region_name='us-east-1')
    s3bucket = s3.Bucket("<<s3bucket_name>>")
    upload_folder_to_s3(s3bucket, "<<Local Folder>>", "<<s3 Path>>")
0
user 923227

Pour lire le dossier de formulaire de fichier, nous pouvons utiliser

import boto
from boto.s3.key import Key

keyId = 'YOUR_AWS_ACCESS_KEY_ID'
sKeyId='YOUR_AWS_ACCESS_KEY_ID'
bucketName='your_bucket_name'

conn = boto.connect_s3(keyId,sKeyId)
bucket = conn.get_bucket(bucketName)
for key in bucket.list():
    print ">>>>>"+key.name
    pathV = key.name.split('/')
    if(pathV[0] == "data"):
        if(pathV[1] != ""):
            srcFileName = key.name
            filename = key.name
            filename = filename.split('/')[1]
            destFileName = "model/data/"+filename
            k = Key(bucket,srcFileName)
            k.get_contents_to_filename(destFileName)
    Elif(pathV[0] == "nlu_data"):
        if(pathV[1] != ""):
            srcFileName = key.name
            filename = key.name
            filename = filename.split('/')[1]
            destFileName = "model/nlu_data/"+filename
            k = Key(bucket,srcFileName)
            k.get_contents_to_filename(destFileName)
0
Aakash Handa