使用 lambda 上传到 S3 的 JPG 文件已损坏

问题描述 投票:0回答:2

我有这个简单的 python lambda,它可以下载 JPG 图像并将其上传到 S3 存储桶。

url = 'https://somesite.com/11/frame.jpg?abs_begin=2019-08-29T05:18:26Z'

s3 = boto3.client('s3')

with contextlib.closing(requests.get(url, stream=True, verify=False)) as response:

    fp = BytesIO(response.content)

    s3.upload_fileobj(fp, bucket_name, 'my-dir/' + 'test_img.jpg')

但是,当查看我的存储桶时,它显示文件大小为 162 字节。从浏览器 GUI 下载到本地磁盘时,macOS 提示:

The file "test_img.jpg" could not be opened.
It may be damaged or use a file format that Preview doesn’t recognise.

知道是什么原因造成的吗?

python amazon-s3 aws-lambda
2个回答
1
投票

您确定该网站为您提供了 JPEG 文件吗?我建议以某种方式检查

response.status_code
,我通常只是在其中放置一个
raise_for_status()
并让调用代码处理异常

此外,如果您实际上正在流式传输内容,则只需要传递

stream=True
即可,您只是一次性阅读所有内容,请求流式传输是一种浪费。建议使用流式传输,否则您需要将整个文件保存在内存中,这可能会造成浪费

如果您想检查是否确实获得了图像,您可以在上传到 S3 之前使用

Pillow
打开图像,例如:

import tempfile

import requests
from PIL import Image  # pip install -U Pillow

# dummy image
url = 'https://picsum.photos/id/1053/1500/1000'

# get a temp file in case we get a large image
with tempfile.TemporaryFile() as fd:
    with requests.get(url, stream=True) as response:
        # make sure HTTP request succeeded
        response.raise_for_status()

        for data in response.iter_content(8192):
            fd.write(data)

    # seek back to beginning of file and load to make sure it's OK
    fd.seek(0)
    with Image.open(fd) as img:
        # will raise an exception on failure
        img.verify()
        print(f'got a {img.format} image of size {img.size}' )

    # let S3 do its thing
    s3.upload_fileobj(fd, bucket_name, 'my-dir/test_img.jpg')

0
投票

对于Python(Flask),您可以使用:

file = request.files['file']

headers = {'Content-Type': file.content_type, 'x-amazon-apigateway-binary-media-types': 'image/jpeg' }

api_url = '<url_endpoint>'

file.seek(0)
file_data = file.read()

response = requests.put(api_url,file_data, headers=headers)
© www.soinside.com 2019 - 2024. All rights reserved.