我确信这个问题的答案很简单,但对我来说这被证明是非常令人沮丧的,因为我无法将我找到的任何解决方案放入实际代码中供我自己使用。
我正在应用引擎上构建一个应用程序,让用户上传一个文件,然后由该应用程序执行操作。文件的大小通常约为几 Mb,在某些情况下可能高达 20 Mb 左右。这足以触发 App Engine 中的 30 秒超时,因此我尝试按照各种网站(包括此处)上的建议直接上传到云存储。
我的表单的上传部分如下所示:
<form name="convert" action="/transform" method="post" enctype="multipart/form-data">
<input type="file" name="coords">
<input type="submit" name="submit" value="Transform">
</form>
处理程序看起来像这样(我只是从应用引擎开始,如果这看起来很愚蠢,我深表歉意。
class TransformPage(BaseHandler):
def get(self):
self.render_template('transform.html',name=self.request.get('form'))
def post(self):
filename = self.request.POST['coords'].filename
filesize = int(self.request.headers['Content_Length'])
if filesize>5242880:
self.redirect('/error')
else:
save_to_cloud(file.value,filename)
# Start processing file here
我将检查文件大小作为防止 30 秒超时的一种非常简单的方法,5Mb 似乎是我可以在 30 秒内在我的网络上推送的最大大小。
save_to_cloud() 只是我围绕 Google 云存储 API 编写的包装器,看起来像这样:
def save_to_cloud(f,filename):
filename = BUCKET + filename
create_file_and_write(f,filename)
以上都有效,我看到上传的文件最终存储在云存储中,但正如我上面所说,对于较大的文件会分解。 我已经看到有关使用 create_upload_url 搜索的提示,但我还不足以了解这与我的情况有何关系,特别是将上传文件的内容读入内存以便我可以将其写入云存储。
如果你知道它是如何完成的,这可能是世界上最简单的事情,但如果没有人在代码中向我展示如何完成它我就做不到:-(
谢谢
编辑:@Itamar:这确实是我想要完成的,尽管上传表单还包含一些由用户做出的其他选择。我现在已经将我的代码更改为此
class TransformPage(BaseHandler):
def get(self):
upload_url =blobstore.create_upload_url('/upload',gs_bucket_name='/my_bucket/')
self.render_template('transform.html',
{'name':self.request.get('form'),
{'upload_url':upload_url})
但我无法让 upload_url 显示在如下所示的模板 html 中
<form name="convert" action="{{ upload_url }}" method="post" enctype="multipart/form-data">
最佳答案
如果我没理解错的话,您要做的是从 App Engine 提供一个表单,允许用户选择要上传的文件。 由于上传的文件可能很大,您不想在 App Engine 中处理上传,而是将文件直接上传到 Google Cloud Storage。
这个是可以做到的,而且难度也不大。 事实上,这正是 App Engine Python Blobstore docs 中给出的例子。 . 当您想要 Cloud Storage 中的文件时,该示例引用 Blobstore 可能会造成混淆 - 但没关系 - 从版本 1.7.0 开始,您似乎可以这样做:
upload_url = blobstore.create_upload_url('/upload', gs_bucket_name='my_bucket')
(而不是我链接的示例中的第 1 步),上传 URL 将直接上传到 Cloud Storage。
现在,您的表单操作应该是 blobstore.create_upload_url
函数返回的字符串 upload_url
。
表单完成处理后(意味着文件已上传),它将重定向到您传递给该函数的参数(在示例中为 /upload
)。
您不需要像问题中描述的那样编写自己的 POST 处理函数。
关于python - 从 appengine 应用上传文件到谷歌云存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23823206/