150 votes

Comment télécharger un fichier vers un répertoire dans un seau S3 à l'aide de boto ?

Je veux copier un fichier dans un seau s3 en utilisant python.

Ex : J'ai un nom de seau = test. Et dans le seau, j'ai 2 dossiers nommés "dump" et "input". Maintenant je veux copier un fichier du répertoire local au dossier "dump" de S3 en utilisant python... Quelqu'un peut-il m'aider ?

2voto

Willie Cheng Points 2209

Pour l'exemple de dossier de téléchargement, utilisez le code suivant et l'image du dossier S3. enter image description here

import boto
import boto.s3
import boto.s3.connection
import os.path
import sys    

# Fill in info on data to upload
# destination bucket name
bucket_name = 'willie20181121'
# source directory
sourceDir = '/home/willie/Desktop/x/'  #Linux Path
# destination directory name (on s3)
destDir = '/test1/'   #S3 Path

#max size in bytes before uploading in parts. between 1 and 5 GB recommended
MAX_SIZE = 20 * 1000 * 1000
#size of parts when uploading in parts
PART_SIZE = 6 * 1000 * 1000

access_key = 'MPBVAQ*******IT****'
secret_key = '11t63yDV***********HgUcgMOSN*****'

conn = boto.connect_s3(
        aws_access_key_id = access_key,
        aws_secret_access_key = secret_key,
        host = '******.org.tw',
        is_secure=False,               # uncomment if you are not using ssl
        calling_format = boto.s3.connection.OrdinaryCallingFormat(),
        )
bucket = conn.create_bucket(bucket_name,
        location=boto.s3.connection.Location.DEFAULT)

uploadFileNames = []
for (sourceDir, dirname, filename) in os.walk(sourceDir):
    uploadFileNames.extend(filename)
    break

def percent_cb(complete, total):
    sys.stdout.write('.')
    sys.stdout.flush()

for filename in uploadFileNames:
    sourcepath = os.path.join(sourceDir + filename)
    destpath = os.path.join(destDir, filename)
    print ('Uploading %s to Amazon S3 bucket %s' % \
           (sourcepath, bucket_name))

    filesize = os.path.getsize(sourcepath)
    if filesize > MAX_SIZE:
        print ("multipart upload")
        mp = bucket.initiate_multipart_upload(destpath)
        fp = open(sourcepath,'rb')
        fp_num = 0
        while (fp.tell() < filesize):
            fp_num += 1
            print ("uploading part %i" %fp_num)
            mp.upload_part_from_file(fp, fp_num, cb=percent_cb, num_cb=10, size=PART_SIZE)

        mp.complete_upload()

    else:
        print ("singlepart upload")
        k = boto.s3.key.Key(bucket)
        k.key = destpath
        k.set_contents_from_filename(sourcepath,
                cb=percent_cb, num_cb=10)

PS : Pour plus de références URL

2voto

Jojo Points 63

Si vous avez le interface de ligne de commande aws installé sur votre système, vous pouvez utiliser pythons sous-processus bibliothèque. Par exemple :

import subprocess
def copy_file_to_s3(source: str, target: str, bucket: str):
   subprocess.run(["aws", "s3" , "cp", source, f"s3://{bucket}/{target}"])

De même, vous pouvez utiliser cette logique pour toutes sortes d'opérations client AWS, comme le téléchargement ou l'énumération de fichiers, etc. Il est également possible d'obtenir des valeurs de retour. De cette façon, il n'est pas nécessaire d'importer boto3. Je suppose que son utilisation n'est pas prévue de cette façon, mais en pratique, je trouve que c'est très pratique. De cette façon, vous obtenez également l'état du téléchargement affiché dans votre console - par exemple :

Completed 3.5 GiB/3.5 GiB (242.8 MiB/s) with 1 file(s) remaining

Pour modifier la méthode en fonction de vos souhaits, je vous recommande de jeter un coup d'œil à l'outil de gestion de l'information de la Commission européenne. sous-processus ainsi qu'à la référence Référence AWS Cli .

Note : Il s'agit d'une copie de ma réponse à une demande d'information de la part d'une personne de l'Union européenne. question similaire .

1voto

Jesus Walker Points 26

J'ai quelque chose qui me semble avoir un peu plus d'ordre :

import boto3
from pprint import pprint
from botocore.exceptions import NoCredentialsError

class S3(object):
    BUCKET = "test"
    connection = None

    def __init__(self):
        try:
            vars = get_s3_credentials("aws")
            self.connection = boto3.resource('s3', 'aws_access_key_id',
                                             'aws_secret_access_key')
        except(Exception) as error:
            print(error)
            self.connection = None

    def upload_file(self, file_to_upload_path, file_name):
        if file_to_upload is None or file_name is None: return False
        try:
            pprint(file_to_upload)
            file_name = "your-folder-inside-s3/{0}".format(file_name)
            self.connection.Bucket(self.BUCKET).upload_file(file_to_upload_path, 
                                                                      file_name)
            print("Upload Successful")
            return True

        except FileNotFoundError:
            print("The file was not found")
            return False

        except NoCredentialsError:
            print("Credentials not available")
            return False

Il y a trois variables importantes ici, la BUCKET const, le fichier_à_télécharger et le nom_fichier

BUCKET : est le nom de votre seau S3

file_to_upload_path doit être le chemin d'accès au fichier que vous voulez télécharger.

file_name : est le fichier résultant et le chemin dans votre seau (c'est ici que vous ajoutez des dossiers ou autres).

Il y a plusieurs façons de procéder mais vous pouvez réutiliser ce code dans un autre script comme ceci

import S3

def some_function():
    S3.S3().upload_file(path_to_file, final_file_name)

1voto

Ramesh Ponnusamy Points 576

Vous devriez également mentionner le type de contenu pour éviter le problème d'accès aux fichiers.

import os
image='fly.png'
s3_filestore_path = 'images/fly.png'
filename, file_extension = os.path.splitext(image)
content_type_dict={".png":"image/png",".html":"text/html",
               ".css":"text/css",".js":"application/javascript",
               ".jpg":"image/png",".gif":"image/gif",
               ".jpeg":"image/jpeg"}

content_type=content_type_dict[file_extension]
s3 = boto3.client('s3', config=boto3.session.Config(signature_version='s3v4'),
                  region_name='ap-south-1',
                  aws_access_key_id=S3_KEY,
                  aws_secret_access_key=S3_SECRET)
s3.put_object(Body=image, Bucket=S3_BUCKET, Key=s3_filestore_path, ContentType=content_type)

0voto

Martin Points 1
xmlstr = etree.tostring(listings,  encoding='utf8', method='xml')
conn = boto.connect_s3(
        aws_access_key_id = access_key,
        aws_secret_access_key = secret_key,
        # host = '<bucketName>.s3.amazonaws.com',
        host = 'bycket.s3.amazonaws.com',
        #is_secure=False,               # uncomment if you are not using ssl
        calling_format = boto.s3.connection.OrdinaryCallingFormat(),
        )
conn.auth_region_name = 'us-west-1'

bucket = conn.get_bucket('resources', validate=False)
key= bucket.get_key('filename.txt')
key.set_contents_from_string("SAMPLE TEXT")
key.set_canned_acl('public-read')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X