简体   繁体   English

无法使用 python boto3 和 upload_fileobj 将文件上传到 AWS S3

[英]Unable to upload file to AWS S3 using python boto3 and upload_fileobj

I am trying to get a webp image, convert it to jpg and upload it to aws S3 without saving the file to disk (using io.BytesIO and boto3 upload_fileobj ), but with no success.我正在尝试获取 webp 图像,将其转换为 jpg 并将其上传到 aws S3 而不将文件保存到磁盘(使用io.BytesIO和 boto3 upload_fileobj ),但没有成功。 The funny thing is that it works fine if I save the file to local disk and than use boto3 upload melhod.有趣的是,如果我将文件保存到本地磁盘而不是使用 boto3 upload melhod,它就可以正常工作。

This works:这有效:

r = requests.get(url)
 if r.status_code == 200:
  file_name = "name.jpeg"
  s3 = boto3.client("s3")
  webp_file = io.BytesIO(r.content)
  im = Image.open(webp_file).convert("RGB")
  im.save(
    f"{config.app_settings.image_tmp_dir}/{file_name}", "JPEG"
  )
  s3.upload_file(
    f"{config.app_settings.image_tmp_dir}/{file_name}",
    config.app_settings.image_S3_bucket,
    file_name,
    ExtraArgs={"ContentType": "image/jpeg"},
  )

This does not work:这不起作用:

r = requests.get(url)
 if r.status_code == 200:
  file_name = "name.jpeg"
  s3 = boto3.client("s3")
  webp_file = io.BytesIO(r.content)
  im = Image.open(webp_file).convert("RGB")
  jpg_file = io.BytesIO()
  im.save(
    jpg_file, "JPEG"
  )
  s3.upload_fileobj(
    jpg_file,
    config.app_settings.image_S3_bucket,
    file_name,
    ExtraArgs={"ContentType": "image/jpeg"},
  )

I can see that the jpg_file has the correct size after im.save , but when the file is uploaded to aws S3 I get empty file.我可以看到jpg_file im.save具有正确的大小,但是当文件上传到 aws S3 时,我得到了空文件。

After calling im.save(jpg_file, "JPEG") , the stream's position is still pointing after the newly-written image data.调用im.save(jpg_file, "JPEG")流的 position仍然指向新写入的图像数据。 Anything that tries to read from jpg_file , will start reading from that position and will not see the image data.任何试图从jpg_file读取的内容,都将从该 position 开始读取,并且不会看到图像数据。

You can use the stream's seek() method to move the position back to the start of the stream, before s3.upload_fileobj() tries to read it:您可以使用流的seek()方法将 position 移回 stream 的开头,然后s3.upload_fileobj()尝试读取它:

  im.save(
    jpg_file, "JPEG"
  )

  # Reset the stream position back to the start of the stream.
  jpg_file.seek(0)

  s3.upload_fileobj(
    jpg_file,
    config.app_settings.image_S3_bucket,
    file_name,
    ExtraArgs={"ContentType": "image/jpeg"},
  )

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

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