【问题标题】:Upload Base64 Image to S3 and return URL将 Base64 图像上传到 S3 并返回 URL
【发布时间】:2020-02-19 07:34:15
【问题描述】:

我正在尝试使用 Python 将 base64 图像上传到 S3 存储桶。 我用谷歌搜索并得到了一些答案,但没有一个对我有用。有些答案使用 boto 而不是 boto3,因此它们对我没用。 我也试过这个链接:Boto3: upload file from base64 to S3 但它对我不起作用,因为Object 方法对于 s3 是未知的。

以下是我目前的代码:

import boto3

s3 = boto3.client('s3')
filename = photo.personId + '.png'
bucket_name = 'photos-collection'
dataToPutInS3 = base64.b64decode(photo.url[23:])

将此变量dataToPutInS3数据上传到s3存储桶并从中获取url的正确方法是什么?

【问题讨论】:

  • 你没有s3.Object的原因是你使用boto3.client('s3')而不是像例子中的boto3.resource('s3')
  • @dmigo 感谢您指出这一点,我根据您的意见更新了我的答案。
  • @Karan Sharma 对你有用吗?
  • 嗨@AmitBaranes我已经使用了代码但是,在将对象放入S3存储桶时出现以下错误:“原因”:“调用GetBucketLocation操作时发生错误(AccessDenied):访问被拒绝”早些时候,对于 putObject,我遇到了相同的 Access Denied 错误,但在更新 iamRoleStatements: for putObject 之后,该错误已解决。你有什么想法,如何解决 GetBucketLocation Access Denied 问题。 ?
  • 使用此s3:GetBucketLocation更新您的 iam 角色操作

标签: python python-3.x amazon-web-services amazon-s3 boto3


【解决方案1】:

您没有提到如何获得base64。为了重现,我的代码 sn-p 使用 requests 库从 Internet 获取图像,然后使用 base64 库将其转换为 base64。

这里的技巧是确保您要上传的 base64 字符串不包含 data:image/jpeg;base64 前缀。 而且,正如 @dmigo 在 cmets 中提到的那样,您应该使用 boto3.resource 而不是 boto3.client。

    from botocore.vendored import requests
    import base64
    import boto3

    s3 = boto3.resource('s3')
    bucket_name = 'BukcetName'
    #where the file will be uploaded, if you want to upload the file to folder use 'Folder Name/FileName.jpeg'
    file_name_with_extention = 'FileName.jpeg'
    url_to_download = 'URL'

    #make sure there is no data:image/jpeg;base64 in the string that returns
    def get_as_base64(url):
        return base64.b64encode(requests.get(url).content)

    def lambda_handler(event, context):
        image_base64 = get_as_base64(url_to_download)
        obj = s3.Object(bucket_name,file_name_with_extention)
        obj.put(Body=base64.b64decode(image_base64))
        #get bucket location
        location = boto3.client('s3').get_bucket_location(Bucket=bucket_name)['LocationConstraint']
        #get object url
        object_url = "https://%s.s3-%s.amazonaws.com/%s" % (bucket_name,location, file_name_with_extention)
        print(object_url)

更多关于S3.Object.put

【讨论】:

  • 我从 Web 应用程序获取 base64 图像字符串数据,函数 post_guest_photo 接收图像数据,然后我必须将该图像作为 jpeg 保存到 S3 存储桶。
【解决方案2】:

您可以将 base64 转换为 IO 字节并使用 upload_fileobj 上传到 S3 存储桶。

import base64
import six
import uuid
import imghdr
import io


def get_file_extension(file_name, decoded_file):
    extension = imghdr.what(file_name, decoded_file)
    extension = "jpg" if extension == "jpeg" else extension
    return extension


def decode_base64_file(data):
    """
    Fuction to convert base 64 to readable IO bytes and auto-generate file name with extension
    :param data: base64 file input
    :return: tuple containing IO bytes file and filename
    """
    # Check if this is a base64 string
    if isinstance(data, six.string_types):
        # Check if the base64 string is in the "data:" format
        if 'data:' in data and ';base64,' in data:
            # Break out the header from the base64 content
            header, data = data.split(';base64,')

        # Try to decode the file. Return validation error if it fails.
        try:
            decoded_file = base64.b64decode(data)
        except TypeError:
            TypeError('invalid_image')

        # Generate file name:
        file_name = str(uuid.uuid4())[:12]  # 12 characters are more than enough.
        # Get the file name extension:
        file_extension = get_file_extension(file_name, decoded_file)

        complete_file_name = "%s.%s" % (file_name, file_extension,)

        return io.BytesIO(decoded_file), complete_file_name


def upload_base64_file(base64_file):
    bucket_name = 'your_bucket_name'
    file, file_name = decode_base64_file(base64_file)
    client = boto3.client('s3', aws_access_key_id='aws_access_key_id',
                          aws_secret_access_key='aws_secret_access_key')

    client.upload_fileobj(
        file,
        bucket_name,
        file_name,
        ExtraArgs={'ACL': 'public-read'}
    )
    return f"https://{bucket_name}.s3.amazonaws.com/{file_name}"

【讨论】:

  • 完美运行!
猜你喜欢
  • 2014-06-26
  • 2017-08-01
  • 2016-04-14
  • 1970-01-01
  • 2013-08-27
  • 2022-08-20
  • 2015-05-30
  • 2015-09-05
  • 2014-08-15
相关资源
最近更新 更多