Cách tải tệp lên thư mục trong thùng S3 bằng boto


107

Tôi muốn sao chép một tệp trong nhóm s3 bằng python.

Ví dụ: Tôi có tên xô = thử nghiệm. Và trong bucket mình có 2 tên thư mục là "dump" & "input". Bây giờ tôi muốn sao chép một tệp từ thư mục cục bộ sang thư mục "dump" S3 bằng python ... Có ai có thể giúp tôi không?

Câu trả lời:


105

Thử cái này...

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)

[CẬP NHẬT] Tôi không phải là người nuôi trăn, vì vậy cảm ơn bạn đã quan tâm đến các báo cáo nhập khẩu. Ngoài ra, tôi không khuyên bạn nên đặt thông tin đăng nhập bên trong mã nguồn của riêng bạn. Nếu bạn đang chạy điều này bên trong AWS, hãy sử dụng Thông tin đăng nhập IAM với Hồ sơ cá thể ( http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html ) và giữ nguyên hành vi trong môi trường Dev / Test của bạn, hãy sử dụng thứ gì đó như Hologram từ AdRoll ( https://github.com/AdRoll/hologram )


8
Tôi sẽ tránh nhiều dòng nhập khẩu, không phải pythonic. Di chuyển các dòng nhập lên trên cùng và đối với boto, bạn có thể sử dụng từ boto.s3.connection import S3Connection; conn = S3Connection (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY); bucket = conn.create_bucket (bucketname ...); bucket.new_key (keyname, ...). set_contents_from_filename ....
cgseller

2
boto.s3.key.Key không tồn tại vào ngày 1.7.12
Alex Pavy 21/06/18

cập nhật kể từ tháng 4 năm 2020 theo liên kết này upload_file_to_s3_using_python
Prayag Sharma

48

Không cần phải làm cho nó phức tạp:

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)

Điều này sẽ hoạt động, nhưng đối với các tệp .zip lớn, bạn có thể cần sử dụng phân đoạn. elastician.com/2010/12/s3-multipart-upload-in-boto.html
cgseller

2
Có .. thực hành ít phức tạp hơn và thường được sử dụng
Leo Prince

1
Tôi cố gắng này, nó không làm việc, nhưng k.set_contents_from_filename (testfile, cb = percent_cb, num_cb = 10) thực hiện
Simon

1
Bạn đang sử dụng boto 2, mới nhất? Dù sao, set_contents_from_filename là một lựa chọn thậm chí còn đơn giản hơn. Cứ liều thử đi !
vcarel

3
key.set_contents_from_filename('some_file.zip')cũng sẽ làm việc ở đây. Xem doc . Bạn có thể tìm thấy mã tương ứng cho boto3 tại đây .
Greg Sadetsky

44
import boto3

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

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

bạn có thể giải thích dòng này không s3.Bucket (BUCKET) .upload_file ("your / local / file", "dump / file")
venkat

@venkat "your / local / file" là một đường dẫn tệp như "/home/file.txt" trên máy tính sử dụng python / boto và "dump / file" là tên khóa để lưu trữ tệp trong Nhóm S3. Xem: boto3.readthedocs.io/en/latest/reference/services/…
Josh S.

1
Có vẻ như người dùng đã định cấu hình trước các Khóa AWS, để thực hiện việc này, hãy mở dấu nhắc lệnh anaconda của bạn và nhập aws configure, nhập thông tin của bạn và bạn sẽ tự động kết nối với boto3. Kiểm tra boto3.readthedocs.io/en/latest/guide/quickstart.html
seeiespi

IMO giải pháp đơn giản nhất, dễ dàng như tinys3 nhưng không cần phụ thuộc bên ngoài khác. Cũng thật sự khuyên bạn nên thiết lập các khóa AWS aws configuretrước thời hạn để giúp cuộc sống của bạn dễ dàng hơn.
barlaensdoonn

Điều gì xảy ra khi có nhiều hồ sơ trong thông tin đăng nhập. làm thế nào để vượt qua các thông tin cụ thể
Tara Prasad Gurung

36

Tôi đã sử dụng cái này và nó rất đơn giản để thực hiện

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/


Tôi không nghĩ rằng điều này hiệu quả đối với các tệp lớn. Tôi đã sử dụng điều này: docs.pythonboto.org/en/latest/s3_tut.html#storing-large-data
wordsforthewise


6
Vì dự án tinys3 bị bỏ rơi, bạn không nên sử dụng nó. github.com/smore-inc/tinys3/issues/45
Halil Kaskavalci

Căn hộ này không hoạt động với tôi nữa vào năm 2019. Tinys3 không chỉ bị bỏ rơi ... Tôi không nghĩ nó hoạt động nữa. Đối với bất kỳ ai khác quyết định thử điều này, đừng ngạc nhiên nếu bạn gặp lỗi 403. Tuy nhiên, một boto3.clientgiải pháp đơn giản (như câu trả lời của Manish Mehra) đã có tác dụng ngay lập tức.
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)

Filepath là gì và folder_name + tên tệp là gì? nó khó hiểu
colintobing

@colintobing filepath là đường dẫn của file trên cụm và FOLDER_NAME / filename là quy ước đặt tên mà bạn muốn có trong s3 xô
Manish Mehra

2
@ManishMehra Câu trả lời sẽ tốt hơn nếu bạn chỉnh sửa nó để làm rõ điểm nhầm lẫn của colintobing; không rõ ràng nếu không kiểm tra tài liệu tham số nào tham chiếu đến đường dẫn cục bộ và tham số nào đến đường dẫn S3 mà không cần kiểm tra tài liệu hoặc đọc nhận xét. (Sau khi hoàn tất, bạn có thể gắn cờ để xóa tất cả các nhận xét ở đây, vì chúng sẽ lỗi thời.)
Mark Amery vào

aws_access_key_idaws_secret_access_keycũng có thể được định cấu hình bằng AWS CLI và được lưu trữ ngoài tập lệnh để có thể gọi `client = boto3.client ('s3')
yvesva

16

Tải tệp lên s3 trong một phiên có thông tin đăng nhập.

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 là gì?
Roelant

Đây là tên tệp trong nhóm S3.
Roman Orac

12

Điều này cũng sẽ hoạt động:

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

Đây là ba lớp lót. Chỉ cần làm theo hướng dẫn trên tài liệu 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')

Một số đối số quan trọng là:

Thông số:

  • Tên tệp ( str) - Đường dẫn đến tệp để tải lên.
  • Bucket ( str) - Tên của nhóm để tải lên.
  • Key ( str) - Tên của tệp mà bạn muốn gán cho tệp của mình trong nhóm s3. Tên này có thể giống với tên của tệp hoặc một tên khác mà bạn chọn nhưng loại tệp phải giữ nguyên.

    Lưu ý: Tôi giả sử rằng bạn đã lưu thông tin đăng nhập của mình trong một ~\.awsthư mục như được đề xuất trong phương pháp cấu hình tốt nhất trong tài liệu boto3 .


  • Cảm ơn Nde Samuel, điều đó đã làm việc với tôi ... Một điều cần thiết bổ sung trong trường hợp của tôi là phải tạo nhóm để tránh lỗi "" Nhóm được chỉ định không tồn tại "".
    HassanSh__3571619

    @ HassanSh__3571619 Tôi rất vui vì nó đã hữu ích.
    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

    Sử dụng 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

    Để biết thêm: - https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html


    1

    Ví dụ về thư mục tải lên như mã sau và hình ảnh thư mục S3 nhập mô tả hình ảnh ở đây

    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: Để biết thêm URL tham khảo


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

    Một văn bản giải thích với những gì mã của bạn sẽ rất hay!
    Nick

    0

    Tôi có một cái gì đó mà dường như tôi có một chút trật tự hơn:

    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
    
    

    Có ba biến quan trọng ở đây, const BUCKET , file_to_uploadfile_name

    BUCKET: là tên của nhóm S3 của bạn

    file_to_upload_path: phải là đường dẫn từ tệp bạn muốn tải lên

    file_name: là tệp kết quả và đường dẫn trong nhóm của bạn (đây là nơi bạn thêm các thư mục hoặc những gì từng có)

    Có nhiều cách nhưng bạn có thể sử dụng lại mã này trong một tập lệnh khác như thế này

    import S3
    
    def some_function():
        S3.S3().upload_file(path_to_file, final_file_name)
    Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
    Licensed under cc by-sa 3.0 with attribution required.