Як завантажити файл у каталог у відро S3 за допомогою boto


107

Я хочу скопіювати файл у відро s3 за допомогою python.

Наприклад: у мене ім'я відра = тест. А у відрі у мене 2 папки з назвою "dump" & "input". Тепер я хочу скопіювати файл з локального каталогу в папку "dump" S3 за допомогою 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)

[ОНОВЛЕННЯ] Я не пітоніст, тож дякую за детальну інформацію про повідомлення про імпорт. Також я не рекомендую розміщувати облікові дані у власному вихідному коді. Якщо ви запускаєте це всередині AWS, використовуйте Ідентифікатори IAM з інстанційними профілями ( http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instan-profiles.html ), щоб зберегти таку ж поведінку в в середовищі Dev / Test, використовуйте щось на зразок голограми від AdRoll ( https://github.com/AdRoll/hologram )


8
Я б уникнув декількох ліній імпорту, а не пітонічних. Перемістіть рядки імпорту вгору, а для бото можна скористатися з boto.s3.connection import S3Connection; conn = S3Connection (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY); bucket = conn.create_bucket (назва відра ...); bucket.new_key (ім'я користувача, ...). set_contents_from_filename ....
cgseller

2
boto.s3.key.Key не існує 1.7.12
Алекс Паві

оновлення станом на квітень 2020 року перейдіть за цим посиланням upload_file_to_s3_using_python
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
Так .. менш складна і поширена практика
Лев Принц

1
Я спробував це, він не працює, але k.set_contents_from_filename (testfile, cb = процент_cb, num_cb = 10) робить
Simon

1
Ви на бото-2, останнє? У будь-якому випадку, set_contents_from_filename - це ще простіший варіант. Действуй !
vcarel

3
key.set_contents_from_filename('some_file.zip')також працював би тут. Див. Док . Відповідний код для boto3 можна знайти тут .
Грег Садецький

44
import boto3

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

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

чи можете ви пояснити цей рядок s3.Bucket (BUCKET) .upload_file ("ваш / локальний / файл", "dump / file")
venkat

@venkat "ваш / локальний / файл" - це файлова доріжка, така як "/home/file.txt" на комп'ютері за допомогою python / boto, а "dump / file" - ключове ім'я для зберігання файлу у відрі S3. Дивіться: boto3.readthedocs.io/en/latest/reference/services/…
Джош С.

1
Схоже, користувач заздалегідь налаштував AWS-ключі, для цього відкрийте командний рядок anaconda та введіть aws configure, введіть свою інформацію, і ви автоматично підключитесь до boto3. Перевірте boto3.readthedocs.io/en/latest/guide/quickstart.html
seeiespi

найпростіше рішення IMO, так само просто, як tinys3, але без необхідності чергової зовнішньої залежності. Також настійно рекомендуємо aws configureзаздалегідь встановити ключі AWS, щоб полегшити ваше життя.
barlaensdoonn

Що відбувається, коли в облікових даних є кілька профілів. як пройти конкретні облікові дані
Тара Прасад Гурунг

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
wordsforthewise

Це також призвело мене до цього скрутного: github.com/boto/boto/issues/2207#issuecomment-60682869 і це: stackoverflow.com/questions/5396932 / ...
wordsforthewise

6
Оскільки проект tinys3 покинутий, ви не повинні використовувати це. github.com/smore-inc/tinys3/isissue/45
Халіль Каскавлів

Ця квартира не працювала для мене більше у 2019 році. Tinys3 не просто покинули ... Я не думаю, що вона більше працює. Для всіх, хто вирішить спробувати це, не дивуйтеся, якщо ви отримаєте 403 помилки. Однак просте boto3.clientрішення (як відповідь Маніша Мехра) спрацювало негайно.
Русс

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)

що таке шлях файлу і що таке папка + ім'я файлу? це заплутано
colintobing

@colintobing filepath - це шлях до файлу кластеру, а ім'я папки / ім'я файлу - це умова іменування, яке ви хочете мати у відрі s3
Manish Mehra

2
@ManishMehra Відповідь буде краще, якби ви її відредагували, щоб уточнити точку плутанини колінтобінгів; це не очевидно, не перевіряючи документи, які параметри відносяться до місцевих шляхів, а які - до шляхів S3, не перевіряючи документи та не читаючи коментарі. (Як тільки це буде зроблено, ви можете познайомитись, щоб усі коментарі були вичищені, оскільки вони застаріли.)
Марк Амерді

aws_access_key_idа aws_secret_access_keyтакож можна налаштувати за допомогою CLI AWS і зберігати поза сценарієм, щоб `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.
Роман Орач

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) - назва відра для завантаження.
  • Key ( str) - ім'я, яке ви хочете призначити своєму файлу у своєму відрі s3. Це може бути те саме, що ім'я файлу або інше ім'я на ваш вибір, але тип файлу повинен залишатися таким же.

    Примітка. Я припускаю, що ви зберегли свої облікові дані в ~\.awsпапці, як це було запропоновано в кращих практиках конфігурації в документації boto3 .


  • Дякую, Nde Samuel, що працював зі мною ... Одне, що потрібно було додатково вимагати в моєму випадку - це відро вже створене, щоб уникнути помилки "" Вказаного відра не існує "".
    HassanSh__3571619

    @ HassanSh__3571619 Я радий, що це допомогло.
    Самуель

    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
    
    

    Там вже три важливих змінних тут, то ВЕДРО Const, то file_to_upload і ім'я файлу

    BUCKET: - назва вашого відра S3

    file_to_upload_path: повинен бути шлях до файлу, який ви хочете завантажити

    file_name: це отриманий файл і шлях у вашому відрі (саме тут ви додаєте папки чи що завгодно)

    Існує багато способів, але ви можете повторно використовувати цей код у іншому подібному сценарії

    import S3
    
    def some_function():
        S3.S3().upload_file(path_to_file, final_file_name)
    Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
    Licensed under cc by-sa 3.0 with attribution required.