I have managed to create a file in GCS in the post method of a webapp2 handler of a Google App Engine application. I can't see how to copy the content of a posted file in the file created in GCS. Here is my code
我已经设法在Google App Engine应用程序的webapp2处理程序的post方法中使用GCS创建文件。我看不到如何在GCS中创建的文件中复制已发布文件的内容。这是我的代码
inFile = self.request.POST.multi['file'].file
gcs_file = gcs.open(filename,
'w',
content_type='text/plain',
options={'x-goog-meta-foo': 'foo',
'x-goog-meta-bar': 'bar'},
retry_params=write_retry_params)
while 1:
line = inFile.readline()
if not line: break
gcs_file.write(line)
gcs_file.close()
At the end of the process the file in GCS is 0 byte
在过程结束时,GCS中的文件是0字节
UPDATE There is a reason why I am not using the blobstore. When using the Blobstore you have to create an url and sand it back to the client. it is the client that performs the actual upload. INSTEAD I need to encrypt the file on the server before to put it in the GCS. Thus I need to receive the file from the client, encrypt it on the server and store it in the GCS.
更新有一个原因我没有使用blobstore。使用Blobstore时,您必须创建一个URL并将其打磨回客户端。是客户端执行实际上传。 INSTEAD我需要先加密服务器上的文件,然后再把它放到GCS中。因此,我需要从客户端接收文件,在服务器上对其进行加密并将其存储在GCS中。
2 个解决方案
#1
I've successfully POST'ed a file to GCS with the following method:
我已经使用以下方法成功地将文件POST到GCS:
def post(self):
write_retry_params = gcs.RetryParams(backoff_factor=1.1)
filename = '/{MY-BUCKET-NAME}/static.txt'
gcs_file = gcs.open(
filename,
'w',
content_type='text/plain',
options={'x-goog-meta-foo': 'foo',
'x-goog-meta-bar': 'bar'},
retry_params=write_retry_params)
inFile = self.request.POST.multi['file'].file
while 1:
line = inFile.readline()
if not line:
break
gcs_file.write(line)
logging.info('Wrote line: {}'.format(line))
gcs_file.close()
Here's the little log message from Console:
这是来自Console的小日志消息:
I 09:20:32.979 2015-05-07 200 84 B 1.13s /static
76.176.106.172 - - [07/May/2015:09:20:32 -0700] "POST /static HTTP/1.1" 200 84 - "curl/7.37.1" "{MY-APP}" ms=1131 cpu_ms=1355 cpm_usd=0.000009 loading_request=1 instance=00c61b117cee89e66d34a42c5bbe3cf2b0bb06b5 app_engine_release=1.9.20
I 09:20:32.832 Wrote line: stack
I 09:20:32.833 Wrote line: overflow
Here's the test.txt
file I uploaded:
这是我上传的test.txt文件:
stack
overflow
And the cURL command I used:
我使用的cURL命令:
curl -F"file=@/Users/{name}/test.txt" http://{MY-APP}/videostatic
If you're still getting 0 bytes from readline()
or read()
I'm going to have to assume that your client is not sending the correct multipart message.
如果您仍然从readline()或read()获得0个字节,我将不得不假设您的客户端没有发送正确的多部分消息。
#2
The recommended way to upload a file to GCS in a Google App Engine application seems to be to use the blobstore with a gcs bucket backing.
在Google App Engine应用程序中将文件上传到GCS的推荐方法似乎是使用带有gcs存储桶支持的blobstore。
There are many reasons why you should not upload directly to your webapp2 handler.
您不应该直接上传到webapp2处理程序的原因有很多。
- Limitations in file size.
- Limitations in request duration.
- Additional charges since you are billed when your handler is running.
文件大小的限制。
请求持续时间的限制。
由于您在处理程序运行时收费,因此需要支付额外费用。
to name a few...
仅举几例......
UPDATE
To address the update to the question: You should STILL upload to the blobstore. Do this in 3 steps:
要解决问题的更新:您应该仍然上传到blobstore。通过3个步骤执行此操作:
- Upload to blobstore.
- Read from blobstore, and write encrypted to GCS.
- Delete from blobstore.
上传到blobstore。
从blobstore读取,并加密写入GCS。
从blobstore中删除。
#1
I've successfully POST'ed a file to GCS with the following method:
我已经使用以下方法成功地将文件POST到GCS:
def post(self):
write_retry_params = gcs.RetryParams(backoff_factor=1.1)
filename = '/{MY-BUCKET-NAME}/static.txt'
gcs_file = gcs.open(
filename,
'w',
content_type='text/plain',
options={'x-goog-meta-foo': 'foo',
'x-goog-meta-bar': 'bar'},
retry_params=write_retry_params)
inFile = self.request.POST.multi['file'].file
while 1:
line = inFile.readline()
if not line:
break
gcs_file.write(line)
logging.info('Wrote line: {}'.format(line))
gcs_file.close()
Here's the little log message from Console:
这是来自Console的小日志消息:
I 09:20:32.979 2015-05-07 200 84 B 1.13s /static
76.176.106.172 - - [07/May/2015:09:20:32 -0700] "POST /static HTTP/1.1" 200 84 - "curl/7.37.1" "{MY-APP}" ms=1131 cpu_ms=1355 cpm_usd=0.000009 loading_request=1 instance=00c61b117cee89e66d34a42c5bbe3cf2b0bb06b5 app_engine_release=1.9.20
I 09:20:32.832 Wrote line: stack
I 09:20:32.833 Wrote line: overflow
Here's the test.txt
file I uploaded:
这是我上传的test.txt文件:
stack
overflow
And the cURL command I used:
我使用的cURL命令:
curl -F"file=@/Users/{name}/test.txt" http://{MY-APP}/videostatic
If you're still getting 0 bytes from readline()
or read()
I'm going to have to assume that your client is not sending the correct multipart message.
如果您仍然从readline()或read()获得0个字节,我将不得不假设您的客户端没有发送正确的多部分消息。
#2
The recommended way to upload a file to GCS in a Google App Engine application seems to be to use the blobstore with a gcs bucket backing.
在Google App Engine应用程序中将文件上传到GCS的推荐方法似乎是使用带有gcs存储桶支持的blobstore。
There are many reasons why you should not upload directly to your webapp2 handler.
您不应该直接上传到webapp2处理程序的原因有很多。
- Limitations in file size.
- Limitations in request duration.
- Additional charges since you are billed when your handler is running.
文件大小的限制。
请求持续时间的限制。
由于您在处理程序运行时收费,因此需要支付额外费用。
to name a few...
仅举几例......
UPDATE
To address the update to the question: You should STILL upload to the blobstore. Do this in 3 steps:
要解决问题的更新:您应该仍然上传到blobstore。通过3个步骤执行此操作:
- Upload to blobstore.
- Read from blobstore, and write encrypted to GCS.
- Delete from blobstore.
上传到blobstore。
从blobstore读取,并加密写入GCS。
从blobstore中删除。