【问题标题】:ForbiddenError when attempting to write file to GCS from GAE python App尝试从 GAE python App 将文件写入 GCS 时出现 ForbiddenError
【发布时间】:2013-06-20 23:44:40
【问题描述】:

我有这个代码:

def save_to_gcs(self, img, img_obj):
    '''
    Image data, Image metadata object -> Blob Key
    Given an image and image metadata, stores it in a GCS bucket
    '''
    bucket = '/foo'
    filename = bucket + '/' + str(img_obj['filename'])

    self.tmp_filenames_to_clean_up = []

    logging.info('Creating file %s\n' % img_obj['filename'])

    write_retry_params = gcs.RetryParams(backoff_factor=1.1)
    gcs_file = gcs.open(filename,
                        'w',
                        content_type=img_obj['mimetype'],
                        retry_params=write_retry_params)
    gcs_file.write(img)
    gcs_file.close()
    self.tmp_filenames_to_clean_up.append(filename)

    return blobstore.create_gs_key('/gs/' + filename)

但它失败并出现此错误:

Expect status [201] from Google Storage. But got status 403. Response headers: {'content-length': '145', 'via': 'HTTP/1.1 GWA', 'x-google-cache-control': 'remote-fetch', 'expires': 'Fri, 01 Jan 1990 00:00:00 GMT', 'server': 'HTTP Upload Server Built on Jun 7 2013 11:30:13 (1370629813)', 'pragma': 'no-cache', 'cache-control': 'no-cache, no-store, must-revalidate', 'date': 'Thu, 20 Jun 2013 23:13:55 GMT', 'content-type': 'application/xml; charset=UTF-8'}
Traceback (most recent call last):
  File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1536, in __call__
    rv = self.handle_exception(request, response, e)
  File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/python27_runtime/python27_lib/versions/third_party/webapp2-2.5.1/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/base/data/home/apps/s~foo/5.368231578716365248/main.py", line 409, in post
    blob_key = self.save_to_gcs(img, img_obj)  # Save the image to a GCS bucket. returns a blob_key
  File "/base/data/home/apps/s~foo/5.368231578716365248/main.py", line 448, in save_to_gcs
    retry_params=write_retry_params)
  File "/base/data/home/apps/s~foo/5.368231578716365248/external/cloudstorage/cloudstorage_api.py", line 69, in open
    return storage_api.StreamingBuffer(api, filename, content_type, options)
  File "/base/data/home/apps/s~foo/5.368231578716365248/external/cloudstorage/storage_api.py", line 527, in __init__
    errors.check_status(status, [201], headers)
  File "/base/data/home/apps/s~foo/5.368231578716365248/external/cloudstorage/errors.py", line 99, in check_status
    raise ForbiddenError(msg)
ForbiddenError: Expect status [201] from Google Storage. But got status 403. Response headers: {'content-length': '145', 'via': 'HTTP/1.1 GWA', 'x-google-cache-control': 'remote-fetch', 'expires': 'Fri, 01 Jan 1990 00:00:00 GMT', 'server': 'HTTP Upload Server Built on Jun 7 2013 11:30:13 (1370629813)', 'pragma': 'no-cache', 'cache-control': 'no-cache, no-store, must-revalidate', 'date': 'Thu, 20 Jun 2013 23:13:55 GMT', 'content-type': 'application/xml; charset=UTF-8'}

任何有关破译该错误并提出解决方案的帮助将不胜感激。

谢谢

【问题讨论】:

    标签: python google-app-engine google-cloud-storage


    【解决方案1】:

    文档对于授予对您的应用引擎应用程序的访问权限感到困惑(这很可能是您的问题)。这是最新的Google Cloud Console 中对我有用的内容:

    1. 在 Google Cloud Console 中,点击您的项目,然后点击“APIs & auth”。开启“Google Cloud Storage”和“Google Cloud Storage JSON API”。
    2. 点击返回“概览”界面,点击左侧菜单中的“云存储”。
    3. 点击您的存储桶旁边的复选框,然后点击“存储桶权限”按钮。
    4. 添加新的“用户”权限并指定您的应用引擎服务帐户名称,格式为 application-id@appspot.gserviceaccount.com。这可以在 AppEngine 控制台的应用程序设置中找到。查找此帐户名称的更好说明是 here
    5. 保存您的更改。

    【讨论】:

    • 一切都很棒
    • 我在任何地方都找不到关于添加新“用户”权限或格式 application-id@appspot.gserviceaccount.com 的说明。我发现的一切都是默认的。非常感谢。
    【解决方案2】:

    同样的事情发生在我身上,这让我很困惑。我按照先决条件部分下this page 上的步骤进行操作。不过有几点注意事项:

    • 对于 2 号,请确保您转到 APIs Console 并在“服务”下打开 GCS
    • 对于数字 5,请转到 Cloud Console,选择您的项目,单击设置扳手,然后单击团队。在此处添加您的 gserviceaccount.com 内容。
    • 对于数字 5,我认为您必须使用 gsutil 编辑 ACL 文件。按照提供的替代说明进行操作。

    这应该对你有用,因为它对我有用。

    【讨论】:

    • 谢谢。实际上,我只是放弃并使用 deprecated files api 将文件写入 blobstore。我现在没有时间测试您的答案,但无论如何都会将其标记为正确,因为它很有帮助。
    【解决方案3】:

    ...除了上述之外,还要转到“API's”(在“Cloud Console”中您的项目下的“API's and Auth”下,并确保“Google Cloud Storage”已打开。 在“结算”下,确保已开启。

    【讨论】:

      【解决方案4】:

      这对我不起作用。 谷歌说我们必须做下面提到的方法。

      为您的存储桶或对象授予权限。 要使您的应用能够在存储桶中创建新对象,您需要执行以下操作:

      登录 App Engine 管理控制台。 点击您要为 Cloud Storage 存储分区授权的应用程序。 单击左侧管理部分下的应用程序设置。 复制服务帐户名称下的值。这是您的应用程序的服务帐户名称,格式为 application-id@appspot.gserviceaccount.com。如果您使用的是 App Engine Premier 帐户,则应用程序的服务帐户名称的格式为 application-id.example.com@appspot.gserviceaccount.com。 使用以下方法之一授予访问权限: 授予应用访问存储桶的最简单方法是使用 Google Cloud Console 将应用的服务帐号名称作为团队成员添加到包含存储桶的项目中。您可以在 Google Cloud Console 左侧边栏中的权限下执行此操作。如果应用程序需要写入存储桶,它应该具有编辑权限。有关 Cloud Storage 中权限的信息,请参阅范围和权限。如果需要,将更多应用程序添加到项目团队。 注意:在某些情况下,您可能无法将服务帐户添加为团队成员。如果您无法添加服务帐号,请使用另一种方法,即存储桶 ACL,如下所述。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-16
        • 2016-02-05
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        • 2011-02-02
        • 2021-12-05
        • 1970-01-01
        相关资源
        最近更新 更多