我有这个简单的 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.
知道是什么原因造成的吗?
您确定该网站为您提供了 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')
对于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)