2015-03-03 4 views
1

Я пытаюсь загрузить большой файл в свой ковш с помощью параллельных загрузок. Я натолкнулся на код от here и решил использовать его, поскольку он очень прост и понятен. Однако запуск программы дает мне ошибкуBoto S3 response Error: Access Denied

boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden 
<?xml version="1.0" encoding="UTF-8"?> 
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>BF24672A4459F15E</RequestId><HostId>SN94E8Sg3QeiNQdOoB0CNZmAKZkVSrae8ORBOcjN9mKl07LjYV8hHhNG5Ox2f2bC</HostId></Error> 

Я прошел через все другое решение данного здесь, на StackOverflow и не было найдено ни один из них, чтобы быть проблемой. У меня есть полный доступ к ведро, и я могу читать, писать, удалять файлы из корзины поочередно и получать эту ошибку только при использовании этого кода. s3cmd также отлично работает и не показывает ошибок. Любая помощь будет оценена. Код и трассировки стека вставили ниже:

код:

import math 
from multiprocessing.dummy import Pool #using dummy for debugging 
import os 

from boto.s3.connection import S3Connection 
from filechunkio import FileChunkIO 
from ConfigParser import RawConfigParser, NoOptionError 

config = RawConfigParser() 
config.read('tm/aws.cfg') 

#conn = S3Connection(config.get('prodAws', 'aws_access_key_id'), config.get('prodAws', 'aws_secret_access_key')) 
acs_key = config.get('prodAws', 'aws_access_key_id') 
sec_key = config.get('prodAws', 'aws_secret_access_key') 
try: 
    default_bucket = config.get('prodAws', 'bucket') 
except NoOptionError, e: 
    print("Configuration error({0})".format(e.message)) 
    exit() 

def _upload_part(bucketname, aws_key, aws_secret, multipart_id, part_num, 
       keyname, offset, bytes, amount_of_retries = 5): 
    """ 
    Uploads a part with retries. 
    """ 
    def _upload(retries_left=amount_of_retries): 
     try: 
      print('Start uploading part #%d ...' % part_num) 
      conn = S3Connection(aws_key, aws_secret) 
      bucket = conn.get_bucket(bucketname, validate=False) 
      for mp in bucket.get_all_multipart_uploads(): 
       if mp.id == multipart_id: 
        with FileChunkIO(keyname, 'r', offset=offset, bytes=bytes) as fp: 
         mp.upload_part_from_file(fp=fp, part_num=part_num) 
        break 
     except Exception as e: 
      print e 
      if retries_left: 
       _upload(retries_left = retries_left - 1) 
      else: 
       print('Failed uploading part #%d' % part_num) 
       raise e 
     else: 
      print('Uploaded part #%d' % part_num) 

    _upload() 


def upload(bucketname, aws_key, aws_secret, keyname, parallel_processes=5): 
    """ 
    Parallel multipart upload. 
    """ 
    conn = S3Connection(aws_key, aws_secret) 
    bucket = conn.get_bucket(bucketname, validate=False) 

    mp = bucket.initiate_multipart_upload(keyname) 

    source_size = os.stat(keyname).st_size 
    bytes_per_chunk = max(int(math.sqrt(5242880) * math.sqrt(source_size)), 5242880) 
    chunk_amount = int(math.ceil(source_size/float(bytes_per_chunk))) 

    pool = Pool(processes=parallel_processes) 
    for i in range(chunk_amount): 
     offset = i * bytes_per_chunk 
     remaining_bytes = source_size - offset 
     bytes = min([ bytes_per_chunk, remaining_bytes ]) 
     part_num = i + 1 
     #_upload_part(bucketname, aws_key, aws_secret, mp.id, part_num, 
       #keyname, offset, bytes) 
     pool.apply_async(_upload_part, [bucketname, aws_key, aws_secret, mp.id, 
             part_num, keyname, offset, bytes]) 
    pool.close() 
    pool.join() 

    if len(mp.get_all_parts()) == chunk_amount: 
     mp.complete_upload() 
     key = bucket.get_key(keyname) 
    else: 
     mp.cancel_upload() 

upload(default_bucket, acs_key, sec_key, 'bigfile.txt') 

StackTrace:

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 783, in __bootstrap 
    self.__bootstrap_inner() 
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner 
    self.run() 
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run 
    self.__target(*self.__args, **self.__kwargs) 
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 113, in worker 
    result = (True, func(*args, **kwds)) 
 File "/home/desktop/s3/parup.py", line 46, in _upload_part 
    _upload() 
 File "/home/desktop/s3/parup.py", line 39, in _upload 
    _upload(retries_left = retries_left - 1) 
 File "/home/desktop/s3/parup.py", line 39, in _upload 
    _upload(retries_left = retries_left - 1) 
 File "/home/desktop/s3/parup.py", line 39, in _upload 
    _upload(retries_left = retries_left - 1) 
 File "/home/desktop/s3/parup.py", line 39, in _upload 
    _upload(retries_left = retries_left - 1) 
 File "/home/desktop/s3/parup.py", line 39, in _upload 
    _upload(retries_left = retries_left - 1) 
 File "/home/desktop/s3/parup.py", line 42, in _upload 
    raise e 
+0

Код, похоже, вытаскивает учетные данные из файла с именем 'tm/aws.cfg' - вы разместили там свои учетные данные? В качестве альтернативы, если вы запускаете свой код из экземпляра EC2, которому была назначена роль, или с компьютера, который может использовать CLI AWS, просто используйте 'S3Connection()' вместо передачи учетных данных вызову API. Он найдет учетные данные, которые вы использовали с 's3cmd' (предположительно). –

ответ

0

Исправлена ​​ошибка:

Проблема была с for mp in bucket.get_all_multipart_uploads(). я удалил его и изменил if mp.id == multipart.id на if multipart.id