Comment télécharger un fichier dans le répertoire du compartiment S3 à l'aide de boto

107

Je souhaite copier un fichier dans le seau s3 en utilisant python.

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

Dheeraj Gundra
la source

Réponses:

105

Essaye ça...

import boto
import boto.s3
import sys
from boto.s3.key import Key

AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''

bucket_name = AWS_ACCESS_KEY_ID.lower() + '-dump'
conn = boto.connect_s3(AWS_ACCESS_KEY_ID,
        AWS_SECRET_ACCESS_KEY)


bucket = conn.create_bucket(bucket_name,
    location=boto.s3.connection.Location.DEFAULT)

testfile = "replace this with an actual filename"
print 'Uploading %s to Amazon S3 bucket %s' % \
   (testfile, bucket_name)

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


k = Key(bucket)
k.key = 'my test file'
k.set_contents_from_filename(testfile,
    cb=percent_cb, num_cb=10)

[MISE À JOUR] Je ne suis pas un pythoniste, donc merci pour les informations concernant les instructions d'importation. De plus, je ne recommanderais pas de placer les informations d'identification dans votre propre code source. Si vous l'exécutez dans AWS, utilisez les informations d'identification IAM avec des profils d'instance ( http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html ) et pour conserver le même comportement dans votre environnement de développement / test, utilisez quelque chose comme Hologram d'AdRoll ( https://github.com/AdRoll/hologram )

Felipe Garcia
la source
8
J'éviterais les multiples lignes d'importation, pas pythoniques. Déplacez les lignes d'importation vers le haut, et pour le boto, vous pouvez utiliser de boto.s3.connection import S3Connection; conn = S3Connection (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY); bucket = conn.create_bucket (nom du bucket ...); bucket.new_key (keyname, ...). set_contents_from_filename ....
cgseller
2
boto.s3.key.Key n'existe pas le 1.7.12
Alex Pavy
mise à jour en avril 2020 suivez ce lien upload_file_to_s3_using_python
Prayag Sharma
48

Pas besoin de compliquer les choses:

s3_connection = boto.connect_s3()
bucket = s3_connection.get_bucket('your bucket name')
key = boto.s3.key.Key(bucket, 'some_file.zip')
with open('some_file.zip') as f:
    key.send_file(f)
vcarel
la source
Cela fonctionnera, mais pour les fichiers .zip volumineux, vous devrez peut-être utiliser chunked. elastician.com/2010/12/s3-multipart-upload-in-boto.html
cgseller
2
Oui .. pratique moins compliquée et couramment utilisée
Leo Prince
1
J'ai essayé cela, cela ne fonctionne pas, mais k.set_contents_from_filename (testfile, cb = percent_cb, num_cb = 10) fonctionne
Simon
1
Êtes-vous sur boto 2, le dernier? Quoi qu'il en soit, set_contents_from_filename est une option encore plus simple. Fonce !
vcarel le
3
key.set_contents_from_filename('some_file.zip')fonctionnerait également ici. Voir doc . Le code correspondant pour boto3 peut être trouvé ici .
Greg Sadetsky
44
import boto3

s3 = boto3.resource('s3')
BUCKET = "test"

s3.Bucket(BUCKET).upload_file("your/local/file", "dump/file")
Boris
la source
pouvez-vous expliquer cette ligne s3.Bucket (BUCKET) .upload_file ("votre / local / file", "dump / file")
venkat
@venkat "votre / local / fichier" est un chemin de fichier tel que "/home/file.txt" sur l'ordinateur en utilisant python / boto et "dump / file" est un nom de clé sous lequel stocker le fichier dans le compartiment S3. Voir: boto3.readthedocs.io/en/latest/reference/services/…
Josh S.
1
Il semble que l'utilisateur ait préconfiguré des clés AWS, pour ce faire, ouvrez votre invite de commande anaconda et tapez aws configure, entrez vos informations et vous vous connecterez automatiquement avec boto3. Vérifiez boto3.readthedocs.io/en/latest/guide/quickstart.html
seeiespi
solution la plus simple IMO, aussi simple que tinys3 mais sans avoir besoin d'une autre dépendance externe. Nous vous recommandons également vivement de configurer vos clés AWS à l' aws configureavance pour vous faciliter la vie.
barlaensdoonn
Que se passe-t-il lorsqu'il y a plusieurs profils dans les informations d'identification? comment passer les informations d'identification spécifiques
Tara Prasad Gurung
36

J'ai utilisé ceci et c'est très simple à mettre en œuvre

import tinys3

conn = tinys3.Connection('S3_ACCESS_KEY','S3_SECRET_KEY',tls=True)

f = open('some_file.zip','rb')
conn.upload('some_file.zip',f,'my_bucket')

https://www.smore.com/labs/tinys3/

Oren Efron
la source
Je ne pense pas que cela fonctionne pour les gros fichiers. J'ai dû utiliser ceci: docs.pythonboto.org/en/latest/s3_tut.html#storing-large-data
wordsforthewise
Cela m'a également conduit à ce correctif: github.com/boto/boto/issues/2207#issuecomment-60682869 et ceci: stackoverflow.com/questions/5396932/…
wordsforthewise
6
Puisque le projet tinys3 est abandonné, vous ne devez pas l'utiliser. github.com/smore-inc/tinys3/issues/45
Halil Kaskavalci
Ce flat out ne fonctionnait plus pour moi en 2019. tinys3 n'est pas simplement abandonné ... je ne pense plus que ça marche. Pour quiconque décide d'essayer ceci, ne soyez pas surpris si vous obtenez des erreurs 403. Une boto3.clientsolution simple (comme la réponse de Manish Mehra) a cependant fonctionné immédiatement.
Russ
16
from boto3.s3.transfer import S3Transfer
import boto3
#have all the variables populated which are required below
client = boto3.client('s3', aws_access_key_id=access_key,aws_secret_access_key=secret_key)
transfer = S3Transfer(client)
transfer.upload_file(filepath, bucket_name, folder_name+"/"+filename)
Manish Mehra
la source
qu'est-ce que chemin de fichier et qu'est-ce que nom_dossier + nom de fichier? c'est déroutant
colintobing
@colintobing filepath est le chemin du fichier sur le cluster et nom_dossier / nom de fichier est la convention de dénomination que vous voudriez avoir à l'intérieur du compartiment s3
Manish Mehra
2
@ManishMehra La réponse serait meilleure si vous la modifiez pour clarifier le point de confusion de colintobing; ce n'est pas évident sans vérifier les docs quels paramètres font référence aux chemins locaux et lesquels aux chemins S3 sans vérifier les documents ou lire les commentaires. (Une fois que cela est fait, vous pouvez marquer pour que tous les commentaires ici soient purgés, car ils seront obsolètes.)
Mark Amery
aws_access_key_idet aws_secret_access_keypeut également être configuré avec l'AWS CLI et stocké hors du script afin que `client = boto3.client ('s3') puisse être appelé
yvesva
16

Téléchargez le fichier vers s3 dans une session avec des informations d'identification.

import boto3

session = boto3.Session(
    aws_access_key_id='AWS_ACCESS_KEY_ID',
    aws_secret_access_key='AWS_SECRET_ACCESS_KEY',
)
s3 = session.resource('s3')
# Filename - File to upload
# Bucket - Bucket to upload to (the top level directory under AWS S3)
# Key - S3 object name (can contain subdirectories). If not specified then file_name is used
s3.meta.client.upload_file(Filename='input_file_path', Bucket='bucket_name', Key='s3_output_key')
Orac romain
la source
Qu'est-ce que la clé s3_output_key?
Roelant
Il s'agit du nom de fichier dans le compartiment S3.
Roman Orac
12

Cela fonctionnera également:

import os 
import boto
import boto.s3.connection
from boto.s3.key import Key

try:

    conn = boto.s3.connect_to_region('us-east-1',
    aws_access_key_id = 'AWS-Access-Key',
    aws_secret_access_key = 'AWS-Secrete-Key',
    # host = 's3-website-us-east-1.amazonaws.com',
    # is_secure=True,               # uncomment if you are not using ssl
    calling_format = boto.s3.connection.OrdinaryCallingFormat(),
    )

    bucket = conn.get_bucket('YourBucketName')
    key_name = 'FileToUpload'
    path = 'images/holiday' #Directory Under which file should get upload
    full_key_name = os.path.join(path, key_name)
    k = bucket.new_key(full_key_name)
    k.set_contents_from_filename(key_name)

except Exception,e:
    print str(e)
    print "error"   
Piyush S. Wanare
la source
7

Ceci est un trois lignes. Suivez simplement les instructions de la documentation boto3 .

import boto3
s3 = boto3.resource(service_name = 's3')
s3.meta.client.upload_file(Filename = 'C:/foo/bar/baz.filetype', Bucket = 'yourbucketname', Key = 'baz.filetype')

Certains arguments importants sont:

Paramètres:

  • Nom de fichier ( str) - Le chemin d'accès au fichier à télécharger.
  • Bucket ( str) - Le nom du compartiment vers lequel effectuer le téléchargement.
  • Clé ( str) - Le nom du que vous souhaitez attribuer à votre fichier dans votre compartiment s3. Cela peut être le même que le nom du fichier ou un nom différent de votre choix, mais le type de fichier doit rester le même.

    Remarque: je suppose que vous avez enregistré vos informations d'identification dans un ~\.awsdossier comme suggéré dans les meilleures pratiques de configuration dans la documentation de boto3 .

  • Samuel Nde
    la source
    Merci Nde Samuel, qui a travaillé avec moi ... Une chose qui était supplémentaire requise dans mon cas était d'avoir le bucket déjà créé, pour éviter une erreur de "" Le bucket spécifié n'existe pas "".
    HassanSh__3571619
    @ HassanSh__3571619 Je suis heureux que cela ait aidé.
    Samuel Nde
    5
    import boto
    from boto.s3.key import Key
    
    AWS_ACCESS_KEY_ID = ''
    AWS_SECRET_ACCESS_KEY = ''
    END_POINT = ''                          # eg. us-east-1
    S3_HOST = ''                            # eg. s3.us-east-1.amazonaws.com
    BUCKET_NAME = 'test'        
    FILENAME = 'upload.txt'                
    UPLOADED_FILENAME = 'dumps/upload.txt'
    # include folders in file path. If it doesn't exist, it will be created
    
    s3 = boto.s3.connect_to_region(END_POINT,
                               aws_access_key_id=AWS_ACCESS_KEY_ID,
                               aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
                               host=S3_HOST)
    
    bucket = s3.get_bucket(BUCKET_NAME)
    k = Key(bucket)
    k.key = UPLOADED_FILENAME
    k.set_contents_from_filename(FILENAME)
    Shakti
    la source
    4

    Utilisation de boto3

    import logging
    import boto3
    from botocore.exceptions import ClientError
    
    
    def upload_file(file_name, bucket, object_name=None):
        """Upload a file to an S3 bucket
    
        :param file_name: File to upload
        :param bucket: Bucket to upload to
        :param object_name: S3 object name. If not specified then file_name is used
        :return: True if file was uploaded, else False
        """
    
        # If S3 object_name was not specified, use file_name
        if object_name is None:
            object_name = file_name
    
        # Upload the file
        s3_client = boto3.client('s3')
        try:
            response = s3_client.upload_file(file_name, bucket, object_name)
        except ClientError as e:
            logging.error(e)
            return False
        return True

    Pour en savoir plus: - https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html

    Noufal Valapra
    la source
    1

    Pour l'exemple de dossier de téléchargement comme le code suivant et l'image du dossier S3 entrez la description de l'image ici

    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 d' URL de référence

    Willie Cheng
    la source
    0
    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')
    Martin
    la source
    Une explication textuelle avec ce que fait votre code sera bien!
    Nick
    0

    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, le BUCKET const, le file_to_upload et le file_name

    BUCKET: est le nom de votre compartiment S3

    file_to_upload_path: doit être le chemin du fichier que vous souhaitez télécharger

    file_name: est le fichier résultant et le chemin dans votre compartiment (c'est là que vous ajoutez des dossiers ou quoi que ce soit)

    Il existe de nombreuses façons, mais vous pouvez réutiliser ce code dans un autre script comme celui-ci

    import S3
    
    def some_function():
        S3.S3().upload_file(path_to_file, final_file_name)
    Jésus Walker
    la source