更新:(2020年5月18日)本帖末尾的解决方案!
我正在尝试将大型CSV文件(30MB-2GB)从浏览器上载到运行Python3.7Flask的GCP应用程序引擎,然后将这些文件推送到GCP存储。这在大型文件的本地测试中效果很好,但如果文件大小超过20MB,则在GCP上会立即出现错误,出现“413-您的客户端发出了太大的请求”。这个错误在上传时立即发生,甚至在它到达我的自定义Python逻辑之前(我怀疑应用程序引擎正在检查内容长度
标题)。在进行了大量的SO/博客研究之后,我尝试了许多解决方案,但都无济于事。请注意,我使用的是运行Gunicorn服务器的F1实例的基本/免费应用程序引擎设置。
首先,我尝试设置应用程序。config['MAX_CONTENT_LENGTH']=2147483648
但这并没有改变任何东西(所以发布)。我的应用程序在到达Python代码之前仍然抛出错误:
# main.py
app.config['MAX_CONTENT_LENGTH'] = 2147483648 # 2GB limit
@app.route('/', methods=['POST', 'GET'])
def upload():
# COULDN'T GET THIS FAR WITH A LARGE UPLOAD!!!
if flask.request.method == 'POST':
uploaded_file = flask.request.files.get('file')
storage_client = storage.Client()
storage_bucket = storage_client.get_bucket('my_uploads')
blob = storage_bucket.blob(uploaded_file.filename)
blob.upload_from_string(uploaded_file.read())
<!-- index.html -->
<form method="POST" action='/upload' enctype="multipart/form-data">
<input type="file" name="file">
</form>
经过进一步的研究,我切换到使用Flask-Dropzone
的分块上传,希望我可以批量上传数据,然后将CSV文件追加/构建为存储Blob:
# main.py
app = flask.Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 2147483648 # 2GB limit
dropzone = Dropzone(app)
@app.route('/', methods=['POST', 'GET'])
def upload():
if flask.request.method == 'POST':
uploaded_file = flask.request.files.get('file')
storage_client = storage.Client()
storage_bucket = storage_client.get_bucket('my_uploads')
CHUNK_SIZE = 10485760 # 10MB
blob = storage_bucket.blob(uploaded_file.filename, chunk_size=self.CHUNK_SIZE)
# hoping for a create-if-not-exists then append thereafter
blob.upload_from_string(uploaded_file.read())
JS/超文本标记语言直接来自我在网上找到的几个样本:
<script>
Dropzone.options.myDropzone = {
timeout: 300000,
chunking: true,
chunkSize: 10485760 };
</script>
....
<form method="POST" action='/upload' class="dropzone dz-clickable"
id="dropper" enctype="multipart/form-data">
</form>
上面的内容是分块上传的(我可以看到对POST/upload的重复调用),但是对blob的调用。从\u字符串上载(上载的\u file.read())
只需将blob内容替换为上载的最后一个块,而不是追加。即使我去掉chunk\u size=self,这也不起作用。块大小
参数。
接下来,我研究了如何写入/tmp
,然后是如何写入存储,但文档说写入/tmp
占用了我仅有的少量内存,而其他地方的文件系统是只读的,因此这两种方式都不起作用。
是否有附加API或经批准的方法将大文件上载到GCP应用程序引擎并推送/流式存储?鉴于代码在我的本地服务器上运行(并且很高兴地上传到GCP存储),我假设这是应用程序引擎中的一个内置限制,需要解决。
解决方案(5/18/2020)我能够使用Flask-Dropzone让JavaScript将上载分割成许多10MB块,并一次将这些块发送到Python服务器。在Python方面,我们会继续 /tmp附加到文件中,以“构建”内容,直到所有块都进来。最后,在最后一块,我们将上传到GCP存储,然后删除 /tmp文件。
@app.route('/upload', methods=['POST'])
def upload():
uploaded_file = flask.request.files.get('file')
tmp_file_path = '/tmp/' + uploaded_file.filename
with open(tmp_file_path, 'a') as f:
f.write(uploaded_file.read().decode("UTF8"))
chunk_index = int(flask.request.form.get('dzchunkindex')) if (flask.request.form.get('dzchunkindex') is not None) else 0
chunk_count = int(flask.request.form.get('dztotalchunkcount')) if (flask.request.form.get('dztotalchunkcount') is not None) else 1
if (chunk_index == (chunk_count - 1)):
print('Saving file to storage')
storage_bucket = storage_client.get_bucket('prairi_uploads')
blob = storage_bucket.blob(uploaded_file.filename) #CHUNK??
blob.upload_from_filename(tmp_file_path, client=storage_client)
print('Saved to Storage')
print('Deleting temp file')
os.remove(tmp_file_path)
<!-- index.html -->
<script>
Dropzone.options.myDropzone = {
... // configs
timeout: 300000,
chunking: true,
chunkSize: 1000000
};
</script>
请注意/tmp与RAM共享资源,因此您需要的RAM至少与上载的文件大小相同,而且Python本身需要更多(我必须使用一个F4实例)。我想有更好的解决方案来写块存储,而不是/tmp,但我还没有做到这一点。
答案是不能在单个HTTP请求中上传或下载大于32 MB的文件。来源
您需要重新设计服务以在多个HTTP请求中传输数据,使用预签名URL直接将数据传输到云存储,或者选择不使用全局前端(GFE)的不同服务,如计算引擎。这不包括云功能、云运行、应用引擎灵活等服务。
如果使用多个HTTP请求,则需要管理内存,因为所有临时文件都存储在内存中。这意味着在接近2 GB的最大实例大小时会出现问题。
html代码 用于遍历文件列表并一次上载一个文件列表的上载逻辑 一次上载一个文件的Servicecall逻辑 2020-09-21 00:38:24.114错误11348---[nio-5200-exec-5]O.a.C.C.C.[.[.[/].[dispatcherServlet]:路径为[]的上下文中servlet[dispatcherServlet]的servlet.Service()引发异
我正在appengine虚拟机上开发一个Flask应用程序。我想上传文件到谷歌云存储,所以我使用连接到云存储。仅在VM中测试时,我的应用程序运行正常,没有错误。但是,在我使用部署并在部署的应用程序上测试上载功能后,它失败并返回错误。日志显示了回溯,这是由于连接到云存储的代码行: 具体错误是
我试图上传一个图像约1.62MB到终端写使用flask.request.files对象总是空的。我检查了以下问题,但没有运气: 烧瓶request.files是空的 https://github.com/requests/requests/issues/2505 如何在烧瓶中使用ajax调用上传文件 这是我的服务器: 我的客户: 在我看来,一切都很干净,我不知道哪里出了问题。请求对象中的“文件”属
这可能吗?
我试图设置NGINX,uWSGI和烧瓶。我目前正在得到, uWSGI错误 找不到Python应用程序 我得到了一些奇怪的错误在我的uwsgi错误文件,你可以在我的文章底部找到。 我会直截了当地说,这是在运行Ubuntu 13.04 64位的新VPS上,这些是我运行的命令。 sudo apt-get更新 sudo apt-get安装构建基本 sudo apt-get安装python-dev sudo
我已经创建了一个blob触发器,它从一个blob接受一个文件,解压缩它,并使用streams将它移动到另一个blob。 我的代码如下所示 实际上,这将在本地运行时使用我的local.settings.json文件中的“azurewebjobstorage”:“UseDevelopmentStorage = true”。 然而,一旦我部署了这个应用程序,并使用Azure Storage Explor