Python 烧瓶-处理表格文件&;上载到AWS S3而不保存到文件
我正在使用Flask应用程序接收带有上传文件(本例中为视频)的多部分/表单数据请求 我不想将文件保存在本地目录中,因为此应用程序将在服务器上运行,保存它会减慢速度 我试图使用Flask request.files['']方法创建的file对象,但它似乎不起作用 以下是代码的这一部分:Python 烧瓶-处理表格文件&;上载到AWS S3而不保存到文件,python,amazon-s3,flask,buffer,protocol-buffers,Python,Amazon S3,Flask,Buffer,Protocol Buffers,我正在使用Flask应用程序接收带有上传文件(本例中为视频)的多部分/表单数据请求 我不想将文件保存在本地目录中,因为此应用程序将在服务器上运行,保存它会减慢速度 我试图使用Flask request.files['']方法创建的file对象,但它似乎不起作用 以下是代码的这一部分: @bp.route('/video_upload', methods=['POST']) def VideoUploadHandler(): form = request.form video_fi
@bp.route('/video_upload', methods=['POST'])
def VideoUploadHandler():
form = request.form
video_file = request.files['video_data']
if video_file:
s3 = boto3.client('s3')
s3.upload_file(video_file.read(), S3_BUCKET, 'video.mp4')
return json.dumps('DynamoDB failure')
这将返回一个错误:
TypeError: must be encoded string without NULL bytes, not str
在线:
s3.upload_file(video_file.read(), S3_BUCKET, 'video.mp4')
我确实是通过先保存文件,然后访问保存的文件来实现的,所以捕获请求文件不是问题。这项工作:
video_file.save(form['video_id']+".mp4")
s3.upload_file(form['video_id']+".mp4", S3_BUCKET, form['video_id']+".mp4")
处理内存中的文件数据并将其传递给
s3.upload\u file()
方法的最佳方法是什么?我使用的是boto3方法,我只找到第一个参数中使用的文件名的示例,所以我不确定如何使用内存中的文件正确处理这个问题。谢谢 首先,您需要能够访问发送到Flask的原始数据。这并不像看上去那么容易,因为您正在阅读表单。要能够读取原始流,可以使用flask.request.stream
,其行为类似于StringIO
。这里的技巧是,您不能调用request.form
或request.file
,因为访问这些属性会将整个流加载到内存或文件中
您将需要一些额外的工作来提取流的正确部分(不幸的是,我无法帮助您,因为这取决于表单的制作方式,但我将让您对此进行实验)
最后,您可以使用boto的set\u contents\u from\u file
功能,因为upload\u file
似乎不处理类似文件的对象(StringIO
等等)
示例代码:
from boto.s3.key import Key
@bp.route('/video_upload', methods=['POST'])
def VideoUploadHandler():
# form = request.form <- Don't do that
# video_file = request.files['video_data'] <- Don't do that either
video_file_and_metadata = request.stream # This is a file-like object which does not only contain your video file
# This is what you need to implement
video_title, video_stream = extract_title_stream(video_file_and_metadata)
# Then, upload to the bucket
s3 = boto3.client('s3')
bucket = s3.create_bucket(bucket_name, location=boto.s3.connection.Location.DEFAULT)
k = Key(bucket)
k.key = video_title
k.set_contents_from_filename(video_stream)
来自boto.s3.key导入密钥
@路由('/video_upload',方法=['POST'])
def VideoUploadHandler():
#谢谢你的帮助!您能否详细说明提取标题流(视频文件和元数据)
?我是新来的,所以我不确定从哪里开始提取与我已经做的不同的流。正如我所说的,这是特定于您的表单的,所以您应该自己看看它。。。看一看。对于request.stream
可能有一个get\u value
方法,但我不确定。在我看来,你最好的办法是按照你以前处理文件的方式来处理文件:这样更安全,而且我不确定你是否需要额外的性能。这可能是因为我对stringIO库和流媒体还不熟悉,但我不确定如何将LimitedStream(request.stream
)转换为stringIO。我也没有在网上找到太多的信息。顺便说一句,我使用的是一个标准的multipart/formdata POST请求,所以应该可以预料到它的设置,因为它没有异常功能。我只有两个文本字段和一个文件字段。你不应该按照说法转换它,但你应该阅读它。在我看来,如果你不能做到这一点,这可能太复杂了,如果你想从中获得额外的性能,你可能需要做一些更复杂的事情,比如控制缓冲区的大小。另外,不投票或不接受也有点粗鲁。你处理好这个问题了吗?