So laden Sie eine Datei mit boto in ein Verzeichnis im S3-Bucket hoch

106

Ich möchte eine Datei in s3 Bucket mit Python kopieren.

Bsp.: Ich habe Bucket Name = Test. Und im Bucket habe ich 2 Ordner mit den Namen "dump" & "input". Jetzt möchte ich eine Datei mit Python aus dem lokalen Verzeichnis in den S3 "Dump" -Ordner kopieren ... Kann mir jemand helfen?

Dheeraj Gundra
quelle

Antworten:

105

Versuche dies...

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)

[UPDATE] Ich bin kein Pythonist, also danke für die Hinweise zu den Importanweisungen. Außerdem würde ich nicht empfehlen, Anmeldeinformationen in Ihren eigenen Quellcode einzufügen. Wenn Sie dies in AWS ausführen, verwenden Sie IAM-Anmeldeinformationen mit Instanzprofilen ( http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html ) und behalten Sie das gleiche Verhalten bei Verwenden Sie in Ihrer Entwicklungs- / Testumgebung so etwas wie ein Hologramm von AdRoll ( https://github.com/AdRoll/hologram ).

Felipe Garcia
quelle
8
Ich würde die mehrfachen Importzeilen vermeiden, nicht pythonisch. Verschieben Sie die Importzeilen nach oben, und für das Boto können Sie aus boto.s3.connection import S3Connection verwenden. conn = S3Connection (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY); Bucket = conn.create_bucket (Bucketname ...); buckle.new_key (keyname, ...). set_contents_from_filename ....
cgseller
2
boto.s3.key.Key existiert nicht am 1.7.12
Alex Pavy
Update ab April 2020 Folgen Sie
Prayag Sharma
48

Keine Notwendigkeit, es so kompliziert zu machen:

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
quelle
Dies funktioniert, aber für große ZIP-Dateien müssen Sie möglicherweise Chunked verwenden. elastician.com/2010/12/s3-multipart-upload-in-boto.html
cgseller
2
Ja .. weniger komplizierte und häufig verwendete Praxis
Leo Prince
1
Ich habe es versucht, es funktioniert nicht, aber k.set_contents_from_filename (Testdatei, cb = Prozent_cb, num_cb = 10) tut es
Simon
1
Bist du auf Boto 2, spätestens? Auf jeden Fall ist set_contents_from_filename eine noch einfachere Option. Tue es !
Vcarel
3
key.set_contents_from_filename('some_file.zip')würde auch hier funktionieren. Siehe doc . Den entsprechenden Code für boto3 finden Sie hier .
Greg Sadetsky
44
import boto3

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

s3.Bucket(BUCKET).upload_file("your/local/file", "dump/file")
Boris
quelle
Können Sie diese Zeile erklären? s3.Bucket (BUCKET) .upload_file ("Ihre / lokale / Datei", "Dump / Datei")
Venkat
@venkat "your / local / file" ist ein Dateipfad wie "/home/file.txt" auf dem Computer, der Python / Boto verwendet, und "dump / file" ist ein Schlüsselname zum Speichern der Datei im S3-Bucket. Siehe: boto3.readthedocs.io/en/latest/reference/services/…
Josh S.
1
Es sieht so aus, als hätte der Benutzer AWS-Schlüssel vorkonfiguriert. Öffnen Sie dazu Ihre Anaconda-Eingabeaufforderung und aws configuregeben Sie ein, geben Sie Ihre Daten ein und Sie werden automatisch eine Verbindung mit boto3 herstellen. Überprüfen Sie boto3.readthedocs.io/en/latest/guide/quickstart.html
seeiespi
einfachste Lösung IMO, genauso einfach wie tinys3, aber ohne die Notwendigkeit einer weiteren externen Abhängigkeit. Empfehlen Sie außerdem dringend, Ihre AWS-Schlüssel im Voraus einzurichten aws configure, um Ihnen das Leben zu erleichtern.
Barlaensdoonn
Was passiert, wenn die Anmeldeinformationen mehrere Profile enthalten? wie man die spezifischen Anmeldeinformationen weitergibt
Tara Prasad Gurung
36

Ich habe dies verwendet und es ist sehr einfach zu implementieren

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
quelle
Ich denke nicht, dass dies für große Dateien funktioniert. Ich musste dies verwenden: docs.pythonboto.org/en/latest/s3_tut.html#storing-large-data
wordsforthewise
Das führte mich auch zu diesem Fix: github.com/boto/boto/issues/2207#issuecomment-60682869 und dies: stackoverflow.com/questions/5396932/…
wordsforthewise
6
Da das tinys3-Projekt aufgegeben wird, sollten Sie dies nicht verwenden. github.com/smore-inc/tinys3/issues/45
Halil Kaskavalci
Diese Wohnung hat 2019 bei mir nicht mehr funktioniert. Tinys3 wird nicht einfach aufgegeben ... Ich glaube nicht, dass es mehr funktioniert. Für alle anderen, die dies versuchen möchten, wundern Sie sich nicht, wenn Sie 403 Fehler erhalten. Eine einfache boto3.clientLösung (wie die Antwort von Manish Mehra) funktionierte jedoch sofort.
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
quelle
Was ist Dateipfad und was ist Ordnername + Dateiname? es ist verwirrend
Colintobing
@colintobing Dateipfad ist der Pfad der Datei im Cluster und Ordnername / Dateiname ist die Namenskonvention, die Sie in s3 Bucket haben möchten
Manish Mehra
2
@ManishMehra Die Antwort wäre besser, wenn Sie sie bearbeiten würden, um den Verwirrungspunkt von Colintobing zu verdeutlichen. Es ist nicht offensichtlich, ohne die Dokumente zu überprüfen, welche Parameter sich auf lokale Pfade und welche auf S3-Pfade beziehen, ohne die Dokumente zu überprüfen oder die Kommentare zu lesen. (Sobald dies erledigt ist, können Sie markieren, dass alle Kommentare hier gelöscht werden, da sie veraltet sind.)
Mark Amery
aws_access_key_id und aws_secret_access_key kann auch mit der AWS-CLI konfiguriert und außerhalb des Skripts gespeichert werden, sodass `client = boto3.client ('s3') aufgerufen werden kann
yvesva
15

Laden Sie die Datei innerhalb einer Sitzung mit Anmeldeinformationen auf s3 hoch.

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')
Roman Orac
quelle
Was ist der s3_output_key?
Roelant
Dies ist der Dateiname im S3-Bucket.
Roman Orac
12

Dies wird auch funktionieren:

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
quelle
7

Dies ist ein Drei-Liner. Folgen Sie einfach den Anweisungen in der boto3-Dokumentation .

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

Einige wichtige Argumente sind:

Parameter:

  • Dateiname ( str) - Der Pfad zu der hochzuladenden Datei.
  • Bucket ( str) - Der Name des Buckets, in den hochgeladen werden soll.
  • Key ( str) - Der Name der Datei, die Sie Ihrer Datei in Ihrem S3-Bucket zuweisen möchten. Dies kann derselbe sein wie der Name der Datei oder ein anderer Name Ihrer Wahl, aber der Dateityp sollte gleich bleiben.

    Hinweis: Ich gehe davon aus, dass Sie Ihre Anmeldeinformationen in einem ~\.awsOrdner gespeichert haben, wie in den bewährten Konfigurationsmethoden in der boto3-Dokumentation vorgeschlagen .

  • Samuel Nde
    quelle
    Vielen Dank, Nde Samuel, das hat bei mir funktioniert ... Eine Sache, die in meinem Fall zusätzlich erforderlich war, war, dass der Bucket bereits erstellt wurde, um den Fehler "" Der angegebene Bucket existiert nicht "" zu vermeiden.
    HassanSh__3571619
    @ HassanSh__3571619 Ich bin froh, dass es geholfen hat.
    Samuel Nde
    4
    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
    quelle
    3

    Mit 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

    Weitere Informationen: - https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html

    Noufal Valapra
    quelle
    1

    Beispiel für das Hochladen eines Ordners wie folgt: Code und S3-Ordnerbild Geben Sie hier die Bildbeschreibung ein

    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: Für mehr Referenz- URL

    Willie Cheng
    quelle
    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
    quelle
    Eine Texterklärung mit dem, was Ihr Code tut, wird nett sein!
    Nick
    0

    Ich habe etwas, das mir etwas mehr Ordnung zu bieten scheint:

    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
    
    

    Hier gibt es drei wichtige Variablen, die BUCKET-Konstante , die Datei_to_upload und den Dateinamen

    BUCKET: ist der Name Ihres S3-Buckets

    file_to_upload_path: muss der Pfad von der Datei sein, die Sie hochladen möchten

    file_name: ist die resultierende Datei und der Pfad in Ihrem Bucket (hier fügen Sie Ordner hinzu oder was auch immer)

    Es gibt viele Möglichkeiten, aber Sie können diesen Code in einem anderen Skript wie diesem wiederverwenden

    import S3
    
    def some_function():
        S3.S3().upload_file(path_to_file, final_file_name)
    Jesus Walker
    quelle