วิธีอัปโหลดไฟล์ไปยังไดเร็กทอรีใน S3 bucket โดยใช้ boto


107

ฉันต้องการคัดลอกไฟล์ในถัง s3 โดยใช้ python

เช่นฉันมีชื่อที่เก็บข้อมูล = ทดสอบ และในที่เก็บข้อมูลฉันมี 2 โฟลเดอร์ชื่อ "dump" & "input" ตอนนี้ฉันต้องการคัดลอกไฟล์จาก local directory ไปยังโฟลเดอร์ S3 "dump" โดยใช้ python ... มีใครช่วยฉันได้บ้าง

คำตอบ:


105

ลองนี่ ...

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)

[อัปเดต] ฉันไม่ใช่ pythonist ดังนั้นขอขอบคุณสำหรับการแจ้งเตือนเกี่ยวกับคำสั่งนำเข้า นอกจากนี้ฉันไม่แนะนำให้ใส่ข้อมูลรับรองในซอร์สโค้ดของคุณเอง หากคุณกำลังเรียกใช้สิ่งนี้ภายใน AWS ให้ใช้ IAM Credentials กับ Instance Profiles ( http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html ) และเพื่อคงพฤติกรรมเดิมไว้ สภาพแวดล้อมการพัฒนา / การทดสอบของคุณใช้บางอย่างเช่นโฮโลแกรมจาก AdRoll ( https://github.com/AdRoll/hologram )


8
ฉันจะหลีกเลี่ยงการนำเข้าหลายบรรทัดไม่ใช่ pythonic ย้ายบรรทัดการนำเข้าไปด้านบนและสำหรับ boto คุณสามารถใช้จาก boto.s3.connection นำเข้า S3Connection; เชื่อมต่อ = S3Connection (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY); ถัง = conn.create_bucket (bucketname ... ); bucket.new_key (keyname, ... ). set_contents_from_filename ....
cgseller

2
boto.s3.key.Key ไม่มีอยู่ใน 1.7.12
Alex Pavy

อัปเดตเมื่อเมษายน 2020 ตามลิงค์นี้ upload_file_to_s3_using_python
Prayag Sharma

48

ไม่จำเป็นต้องทำให้ซับซ้อนขนาดนั้น:

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)

วิธีนี้จะได้ผล แต่สำหรับไฟล์. zip ขนาดใหญ่คุณอาจต้องใช้แบบแยกส่วน elastician.com/2010/12/s3-multipart-upload-in-boto.html
cgseller

2
ใช่ .. วิธีปฏิบัติที่ซับซ้อนน้อยกว่าและใช้กันทั่วไป
Leo Prince

1
ฉันลองแล้วมันไม่ได้ผล แต่ k.set_contents_from_filename (testfile, cb = percent_cb, num_cb = 10) ทำ
Simon

1
คุณใช้ boto 2 ล่าสุดหรือไม่? อย่างไรก็ตาม set_contents_from_filename เป็นตัวเลือกที่ง่ายกว่า ไปเลย!
vcarel

3
key.set_contents_from_filename('some_file.zip')ก็จะทำงานที่นี่เช่นกัน โปรดดูเอกสาร รหัสที่สอดคล้องกันสำหรับ boto3 สามารถพบได้ที่นี่
Greg Sadetsky

45
import boto3

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

s3.Bucket(BUCKET).upload_file("your/local/file", "dump/file")

คุณช่วยอธิบายบรรทัดนี้ได้ไหม s3.Bucket (BUCKET) .upload_file ("your / local / file", "dump / file")
venkat

@venkat "your / local / file" คือ filepath เช่น "/home/file.txt" บนคอมพิวเตอร์โดยใช้ python / boto และ "dump / file" เป็นชื่อคีย์ในการจัดเก็บไฟล์ใน S3 Bucket ดู: boto3.readthedocs.io/en/latest/reference/services/…
Josh S.

1
ดูเหมือนว่าผู้ใช้ได้กำหนดค่า AWS Keys ไว้ล่วงหน้าเพื่อเปิดพรอมต์คำสั่ง anaconda ของคุณและพิมพ์aws configureป้อนข้อมูลของคุณและคุณจะเชื่อมต่อกับ boto3 โดยอัตโนมัติ ตรวจสอบboto3.readthedocs.io/en/latest/guide/quickstart.html
seeiespi

วิธีแก้ปัญหาที่ง่ายที่สุด IMO ง่ายพอ ๆ กับ tinys3 แต่ไม่จำเป็นต้องพึ่งพาภายนอกอื่น ขอแนะนำอย่างยิ่งให้ตั้งค่าคีย์ AWS aws configureล่วงหน้าเพื่อให้ชีวิตของคุณง่ายขึ้น
barlaensdoonn

จะเกิดอะไรขึ้นเมื่อมีหลายโปรไฟล์ในข้อมูลรับรอง วิธีการส่งข้อมูลรับรองเฉพาะ
Tara Prasad Gurung

36

ฉันใช้สิ่งนี้และใช้งานง่ายมาก

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/


ฉันไม่คิดว่ามันจะใช้ได้กับไฟล์ขนาดใหญ่ ฉันต้องใช้สิ่งนี้: docs.pythonboto.org/en/latest/s3_tut.html#storing-large-data
wordforthewise

นั่นทำให้ฉันไปสู่การแก้ไขนี้เช่นกัน: github.com/boto/boto/issues/2207#issuecomment-60682869 และสิ่งนี้: stackoverflow.com/questions/5396932/…
word ต่อไป

6
เนื่องจากโครงการ tinys3 ถูกละทิ้งคุณไม่ควรใช้สิ่งนี้ github.com/smore-inc/tinys3/issues/45
Halil Kaskavalci

การแบนนี้ใช้ไม่ได้กับฉันอีกต่อไปในปี 2019 tinys3 ไม่ได้ถูกทิ้งร้าง ... ฉันไม่คิดว่ามันจะได้ผลอีกต่อไป สำหรับใครก็ตามที่ตัดสินใจลองใช้สิ่งนี้อย่าแปลกใจถ้าคุณได้รับข้อผิดพลาด 403 boto3.clientวิธีแก้ปัญหาง่ายๆ(เช่นคำตอบของ Manish Mehra) ได้ผลทันที
รัส

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)

filepath คืออะไรและ folder_name + filename คืออะไร? มันสับสน
colintobing

@colintobing filepath เป็นพา ธ ของไฟล์บนคลัสเตอร์และ folder_name / filename คือรูปแบบการตั้งชื่อที่คุณต้องการมีไว้ในถัง s3
Manish Mehra

2
@ManishMehra คำตอบจะดีกว่าถ้าคุณแก้ไขเพื่อชี้แจงจุดที่สับสนของ colintobing ไม่ชัดเจนโดยไม่ต้องตรวจสอบเอกสารว่าพารามิเตอร์ใดอ้างถึงโลคัลพา ธ และอันไหนไปยังพา ธ S3 โดยไม่ต้องตรวจสอบเอกสารหรืออ่านความคิดเห็น (เมื่อเสร็จแล้วคุณสามารถตั้งค่าสถานะเพื่อให้ลบความคิดเห็นทั้งหมดที่นี่ได้เนื่องจากความคิดเห็นเหล่านี้จะล้าสมัย)
Mark Amery

aws_access_key_idและaws_secret_access_keyยังสามารถกำหนดค่าด้วย AWS CLI และจัดเก็บออกจากสคริปต์เพื่อให้สามารถเรียกใช้ `` client = boto3.client ('s3') ได้
yvesva

16

อัปโหลดไฟล์ไปยัง s3 ภายในเซสชันด้วยข้อมูลประจำตัว

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')

s3_output_key คืออะไร
Roelant

เป็นชื่อไฟล์ในบัคเก็ต S3
Roman Orac

12

สิ่งนี้จะใช้งานได้:

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"   

7

นี่คือซับสามตัว เพียงทำตามคำแนะนำบนเอกสาร 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')

ข้อโต้แย้งที่สำคัญบางประการ ได้แก่

พารามิเตอร์:

  • ชื่อไฟล์ ( str) - เส้นทางไปยังไฟล์ที่จะอัปโหลด
  • Bucket ( str) - ชื่อที่เก็บข้อมูลที่จะอัปโหลด
  • คีย์ ( str) - ชื่อที่คุณต้องการกำหนดให้กับไฟล์ของคุณในที่เก็บข้อมูล s3 ของคุณ อาจเป็นชื่อเดียวกับชื่อไฟล์หรือชื่ออื่นที่คุณเลือก แต่ประเภทไฟล์ควรจะเหมือนเดิม

    หมายเหตุ:ฉันคิดว่าคุณได้บันทึกข้อมูลประจำตัวของคุณใน~\.awsโฟลเดอร์ตามข้อเสนอแนะในการปฏิบัติที่ดีที่สุดในการกำหนดค่าเอกสาร boto3


  • ขอบคุณ Nde Samuel ที่ทำงานร่วมกับฉัน ... สิ่งหนึ่งที่จำเป็นเพิ่มเติมในกรณีของฉันคือการสร้างที่เก็บข้อมูลไว้แล้วเพื่อหลีกเลี่ยงข้อผิดพลาด "" ไม่มีที่เก็บข้อมูลที่ระบุ ""
    HassanSh__3571619

    @ HassanSh__3571619 ฉันดีใจที่ได้ช่วย
    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)

    4

    ใช้ 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

    สำหรับข้อมูลเพิ่มเติม: - https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html


    1

    สำหรับตัวอย่างโฟลเดอร์อัพโหลดตามรหัสต่อไปนี้และรูปภาพโฟลเดอร์ S3 ป้อนคำอธิบายภาพที่นี่

    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: สำหรับURLอ้างอิงเพิ่มเติม


    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')

    คำอธิบายข้อความพร้อมรหัสของคุณจะดีมาก!
    นิค

    0

    ฉันมีบางอย่างที่ดูเหมือนว่าฉันมีระเบียบมากขึ้น:

    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
    
    

    มีตัวแปรสำคัญสามตัวที่นี่BUCKET const, file_to_uploadและfile_name

    BUCKET: คือชื่อที่เก็บข้อมูล S3 ของคุณ

    file_to_upload_path: ต้องเป็นเส้นทางจากไฟล์ที่คุณต้องการอัปโหลด

    file_name: เป็นไฟล์ผลลัพธ์และเส้นทางในที่เก็บข้อมูลของคุณ (นี่คือที่ที่คุณเพิ่มโฟลเดอร์หรือสิ่งที่เคย)

    มีหลายวิธี แต่คุณสามารถใช้รหัสนี้ซ้ำในสคริปต์อื่นเช่นนี้ได้

    import S3
    
    def some_function():
        S3.S3().upload_file(path_to_file, final_file_name)
    โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
    Licensed under cc by-sa 3.0 with attribution required.