Я пытаюсь извлечь файл из AWS S3, используя Boto3, непосредственно в объект BytesIO. В конечном итоге это будет использоваться для управления загруженными данными, но сейчас я просто пытаюсь передать этот файл непосредственно пользователю через Flask. Насколько я понимаю, все, что ниже, должно работать, но не работает. Браузер просто ничего не отображает (и показывает только загруженные несколько байтов данных).
(В этом примере мой образец файла имеет формат png)
from flask import Flask, send_from_directory, abort, Response, send_file, make_response
import boto3, botocore
import os
import io
AWS_ACCESS_KEY = os.environ['AWS_ACCESS_KEY'].rstrip()
AWS_SECRET_KEY = os.environ['AWS_SECRET_KEY'].rstrip()
S3_BUCKET = "static1"
app = Flask(__name__, static_url_path='/tmp')
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
s3 = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY,)
file = io.BytesIO()
metadata = s3.head_object(Bucket=S3_BUCKET, Key=path)
conf = boto3.s3.transfer.TransferConfig(use_threads=False)
s3.download_fileobj(S3_BUCKET, path, file)
return send_file(file, mimetype=metadata['ContentType'])
if __name__ == '__main__':
app.run(debug=True,port=3000,host='0.0.0.0')
Если я изменю эту базовую процедуру для записи объекта BytesIO на диск, а затем прочитаю его обратно в новый объект BytesIO - все будет работать нормально. Как показано ниже:
def catch_all(path):
s3 = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY,)
file = io.BytesIO()
metadata = s3.head_object(Bucket=S3_BUCKET, Key=path)
conf = boto3.s3.transfer.TransferConfig(use_threads=False)
s3.download_fileobj(S3_BUCKET, path, file)
print(file.getvalue())
fh = open("/tmp/test1.png","wb")
fh.write(file.getvalue())
fh.close()
fh = open("/tmp/test1.png","rb")
f2 = io.BytesIO(fh.read())
fh.close
print(f2.getvalue())
return send_file(f2, mimetype=metadata['ContentType'])
Ходя по кругу с этим в течение нескольких дней, ясно, что я что-то упускаю, и я не уверен, что. Скрипт запускается внутри док-контейнера Python 3.8 с последними копиями boto3/flask/etc.