简体   繁体   English

使用 Boto3 回调,显示上传进度

[英]Callback with Boto3, Showing Upload Progress

I am in a situation with a document storage feature in a Django/Python application (using Boto3) where I also need to provide the user with information on the progress of an upload.我在 Django/Python 应用程序(使用 Boto3)中遇到文档存储功能的情况,我还需要向用户提供有关上传进度的信息。

The methods I have seen which use straight JS are not all universally 'usable' across browsers, what I want is to be able upload a file using Boto3 and then also show an upload progress bar in my Django template.我所看到的直接使用 JS 的方法并非都在浏览器中普遍“可用”,我想要的是能够使用 Boto3 上传文件,然后还在我的 Django 模板中显示上传进度条。

Looking at the docs here: https://boto3.amazonaws.com/v1/documentation/api/latest/_modules/boto3/s3/transfer.html I am not understanding how it would be possible to show building progress of the upload calling ProgressPercentage() from within a template.查看此处的文档: https : //boto3.amazonaws.com/v1/documentation/api/latest/_modules/boto3/s3/transfer.html我不明白如何显示上传调用的构建进度ProgressPercentage()来自模板。

How would I go about displaying the actual progress for my user in a template using Boto3?我将如何使用 Boto3 在模板中为我的用户显示实际进度?

class ProgressPercentage(object):
        def __init__(self, filename):
            self._filename = filename
            self._size = float(os.path.getsize(filename))
            self._seen_so_far = 0
            self._lock = threading.Lock()

        def __call__(self, bytes_amount):
            # To simplify we'll assume this is hooked up
            # to a single filename.
            with self._lock:
                self._seen_so_far += bytes_amount
                percentage = (self._seen_so_far / self._size) * 100
                sys.stdout.write(
                    "\r%s  %s / %s  (%.2f%%)" % (
                        self._filename, self._seen_so_far, self._size,
                        percentage))
                sys.stdout.flush()


transfer = S3Transfer(boto3.client('s3', 'us-west-2'))
# Upload /tmp/myfile to s3://bucket/key and print upload progress.
transfer.upload_file('/tmp/myfile', 'bucket', 'key',
                         callback=ProgressPercentage('/tmp/myfile'))

There are three related answers in SO: SO中有三个相关的答案:

  1. Get progress callback in aws boto3 uploads (couldn't make it work, but seems elegant) 在 aws boto3 上传中获取进度回调(无法使其工作,但看起来很优雅)

  2. Track download progress of S3 file using boto3 and callbacks (this one is for downloads, but helped me understand what the callback should look like) 使用 boto3 和回调跟踪 S3 文件的下载进度(这个用于下载,但帮助我了解回调应该是什么样子)

  3. S3 Python Download with Progress Bar (worked, I used this one to write my code). 带进度条的 S3 Python 下载(有效,我用这个来编写我的代码)。

Here is what I did that worked:这是我所做的工作:

import boto3
from botocore.exceptions import NoCredentialsError, ClientError
import os
import progressbar

ACCESS_KEY = 'MY_ACCESS_KEY'
SECRET_KEY = 'MY_SECRET_KEY_THAT_I_KNOW_SHOULD_NOT_BE_HERE_BUT_I_HAVENT_IMPLEMENTED_THE_PROPER_WAY_YET_ALSO_I_DO_NOT_KNOW_WHY_I_AM_YELLING_SORRY'

def upload_to_aws(local_file, s3_bucket, s3_folder, s3_filename,force_overwrite='n'):
    s3 = boto3.client('s3', aws_access_key_id=ACCESS_KEY,
                    aws_secret_access_key=SECRET_KEY)


    def write_to_aws():

        statinfo = os.stat(local_file)
        up_progress = progressbar.progressbar.ProgressBar(maxval=statinfo.st_size)
        up_progress.start()

        def upload_progress(chunk):
            up_progress.update(up_progress.currval + chunk)


        try:
            print("Writting")
            s3.upload_file(local_file, s3_bucket, s3_folder+s3_filename, Callback=upload_progress)
            print("Upload Successful")
            return True
        except FileNotFoundError:
            print("The source file was not found")
            return False
        except NoCredentialsError:
            print("Credentials not available")
            return False
    try:
        s3.head_object(Bucket=s3_bucket, Key=s3_folder+s3_filename)
        if force_overwrite=='y':
            write_to_aws
        else:
            ask_overwrite = input('File already exists at destination. Overwrite?')
            if ask_overwrite == 'y':
                write_to_aws()
            else:
                print('leaving application')
    except ClientError as e:
        write_to_aws()

I know you probably figured that out already, but if anyone else finds this while searching for the solution, I hope this helps我知道您可能已经想通了,但是如果其他人在寻找解决方案时发现了这一点,我希望这会有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM