1

我想让我的 Python GAE 应用程序的客户端使用我预先设置的特定对象名称和 GCS 参数(例如缓存控制和 ACL)直接将文件上传到 GCS,并在上传完成后执行一些操作。

我目前使用blobstore.create_upload_url这个。但是,由于我不能预先给出任何参数或对象名称,我需要从“上传”回调处理程序中将整个文件复制到 GCS 上的新位置。这是时间和(计算)资源的消耗,听起来可以避免。

有没有办法优化这个过程?

  • 我可以创建一个上传 URL 来立即上传具有正确名称和正确 ACL + 缓存控制参数的对象吗?(我简要地查看了签名的 URL,但它们似乎不支持像 blobstore API 那样的回调处理程序)
  • 如果没有,有没有办法不必逐字节地将文件复制到新位置并在完成后将其删除?(能够移动文件并更改其属性会很好)

更新:我刚刚注意到 GCS python 客户端库copy2现在有了。我可以发誓这以前不存在,但听起来它回答了第二个问题。

4

1 回答 1

2

这是我的 Python、webapp2、jinja 代码,用于使用带有策略文档的签名表单直接上传(发布)到 GCS:

def gcs_upload(acl='bucket-owner-read'):
    """ jinja2 upload form context """

    default_bucket = app_identity.get_default_gcs_bucket_name()
    google_access_id = app_identity.get_service_account_name()
    succes_redirect = webapp2.uri_for('_gcs_upload_ok', _full=True)
    expiration_dt = datetime.now() + timedelta(seconds=300)

    policy_string = """
    {"expiration": "%s",
              "conditions": [
                  ["starts-with", "$key", ""],
                  {"acl": "%s"},
                  {"success_action_redirect": "%s"},
                  {"success_action_status": "201"},
              ]}""" % (expiration_dt.replace(microsecond=0).isoformat() + 'Z', acl, succes_redirect)

    policy = base64.b64encode(policy_string)
    _, signature_bytes = app_identity.sign_blob(policy)
    signature = base64.b64encode(signature_bytes)

    return dict(form_bucket=default_bucket, form_access_id=google_access_id, form_policy=policy, form_signature=signature,
            form_succes_redirect=succes_redirect, form_acl=acl)


class GcsUpload(BaseHandler):

    def get(self):

        self.render_template('gcs_upload.html', **gcs_upload())

和表单字段:

<form method="post" action="https://storage.googleapis.com/{{ form_bucket }}" enctype="multipart/form-data">
    <input type="hidden" id="key" name="key" value="images/test.png">
    <input type="hidden" name="GoogleAccessId" value="{{ form_access_id }}">
    <input type="hidden" name="acl" value="{{ form_acl }}">
    <input type="hidden" name="success_action_redirect" value="{{ form_succes_redirect }}">
    <input type="hidden" name="success_action_status" value="201">
    <input type="hidden" name="policy" value="{{ form_policy }}">
    <input type="hidden" name="signature" value="{{ form_signature }}">
    <input name="file" type="file">
    <input type="submit" value="Upload">
</form>

Docs GCS在此处使用表单上传

于 2015-07-17T05:00:14.620 回答