【问题标题】:I can't create a Google Cloud Storage file working on "dev_appserver.py."我无法创建处理“dev_appserver.py”的 Google Cloud Storage 文件。
【发布时间】:2014-07-07 13:59:01
【问题描述】:

我发现如下错误。

INFO     ~ module.py:639] default: "HEAD /_ah/gcs/app_default_bucket/multibytes.txt HTTP/1.1" 404 -
ERROR    ~ gcs.py:99] Expect status [200] from Google Storage. But got status 404.
Path: '/app_default_bucket/multibytes.txt'.
Request headers: None.
Response headers: {'date': 'Mon, 07 Jul 2014 12:59:44 GMT', 'server': 'Development/2.0', 'connection': 'close'}.
Body: ''.
Extra info: None.
Traceback (most recent call last):
  File "/gcs.py", line 97, in status
        stat = gcs.stat("/%s/%s" % (b,nm))
  File "/cloudstorage/cloudstorage_api.py", line 142, in stat
        body=content)
  File "/cloudstorage/errors.py", line 132, in check_status
        raise NotFoundError(msg)
NotFoundError: Expect status [200] from Google Storage. But got status 404.
Path: '/app_default_bucket/multibytes.txt'.
Request headers: None.
Response headers: {'date': 'Mon, 07 Jul 2014 12:59:44 GMT', 'server': 'Development/2.0', 'connection': 'close'}.
Body: ''.
Extra info: None.

例如,这是我的自定义 GCS 客户端类。

# encoding: utf-8

import cloudstorage as gcs

class mycustomgcsclient:

  #...

  def create(self,name,data,**options):
    options['retry_params'] = gcs.RetryParams(backoff_factor=1.1)

    if not options.get('content_type'):
      options['content_type'] = 'octet-stream'

    if isintance(name,unicode):
      name = name.encode('utf-8')

    path = '/mybucketname/%s' % name
    try:
      with gcs.open(path,'w',**options) as f:
        f.write(data)
      return True
    except Exception as e:
      logging.exception(e)

    return False

if __name__=='__main__':
  data = 'some data ...¥n'

  filename = 'somedir/%s' % u'sample.txt'
  mycustomgcsclient().create(filename,data) # no error occured.

  filename = 'somedir/%s' % u'あいうえお.txt'
  mycustomgcsclient().create(filename,data) # error occured in this line.

我在仅使用多字节文件名时发现了上述错误。

我在使用 ascii 文件名时没有发现任何错误。

我正在使用https://developers.google.com/appengine/docs/python/googlecloudstorageclient/download 提供的“GCS 客户端库(Python)”。

我的 dev_appserver.py 的版本是 Development SDK 1.9.6, 这适用于 MacOS X Marve..(?忘记了)。

有什么解决办法吗?

【问题讨论】:

  • 您好,能否提供一个示例代码来说明问题?
  • 另外,似乎一开始就找不到多字节文件。您能否在创建后验证该文件是否确实存在?在 dev_appserver 上,您应该能够在 blobstore 查看器中看到它:localhost:8000/blobstore 在应用引擎本身上,您可以在 Cloud Storage 的存储浏览器中看到它们:console.developers.google.com/project/apps~YOURAPPIDHERE/…
  • 谢谢大家。我添加了我的源代码。
  • 我无法验证存储的数据,因为存储事务未完成。错误发生在 GAE 或 GCS 库内部运行的“/_ah/~”请求中。

标签: python google-app-engine google-cloud-storage dev-appserver dev-appserver-2


【解决方案1】:

我认为您可能需要在将名称编码为 utf8 后调用 urllib.quote()

这是 GCS Python 演示 (http://appengine-gcs-client.googlecode.com/svn/trunk/python/demo/main.py) 的修改版本,它使用多字节文件名可以正常工作:

# Copyright 2012 Google Inc. All Rights Reserved.
# encoding: utf-8

"""A modified version of the sample app that uses GCS client to operate on
   bucket and file.
"""

import logging
import os
import cloudstorage as gcs
import webapp2
import urllib

from google.appengine.api import app_identity

my_default_retry_params = gcs.RetryParams(initial_delay=0.2,
                                          max_delay=5.0,
                                          backoff_factor=2,
                                          max_retry_period=15)
gcs.set_default_retry_params(my_default_retry_params)


class MainPage(webapp2.RequestHandler):
  """Main page for GCS demo application."""

  def get(self):
    bucket_name = os.environ.get('BUCKET_NAME',
                                 app_identity.get_default_gcs_bucket_name())

    self.response.headers['Content-Type'] = 'text/plain'
    self.response.write('Demo GCS Application running from Version: '
                        + os.environ['CURRENT_VERSION_ID'] + '\n')
    self.response.write('Using bucket name: ' + bucket_name + '\n\n')

    bucket = '/' + bucket_name
    filename = bucket + '/' + urllib.quote(u'あいうえお.txt'.encode('utf8'))
    self.tmp_filenames_to_clean_up = []

    try:
      self.create_file(filename)
      self.response.write('\n\n')

      self.read_file(filename)
      self.response.write('\n\n')

    except Exception, e:
      logging.exception(e)
      self.delete_files()
      self.response.write('\n\nThere was an error running the demo! '
                          'Please check the logs for more details.\n')

    else:
      self.delete_files()
      self.response.write('\n\nThe demo ran successfully!\n')

  def create_file(self, filename):
    """Create a file.

    The retry_params specified in the open call will override the default
    retry params for this particular file handle.

    Args:
      filename: filename.
    """
    self.response.write('Creating file %s\n' %
                        urllib.unquote(filename).decode('utf-8'))

    write_retry_params = gcs.RetryParams(backoff_factor=1.1)
    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)
    gcs_file.write('some data ...¥n\n')
    gcs_file.close()
    self.tmp_filenames_to_clean_up.append(filename)


  def read_file(self, filename):
    self.response.write('File Content:\n')

    gcs_file = gcs.open(filename)
    self.response.write(gcs_file.readline())
    gcs_file.close()

  def delete_files(self):
    self.response.write('Deleting files...\n')
    for filename in self.tmp_filenames_to_clean_up:
      self.response.write('Deleting file %s\n' %
                          urllib.unquote(filename).decode('utf-8'))
      try:
        gcs.delete(filename)
      except gcs.NotFoundError:
        pass

app = webapp2.WSGIApplication([('/', MainPage)],
                              debug=True)

【讨论】:

    猜你喜欢
    • 2018-01-03
    • 2015-10-15
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 2020-09-30
    • 2020-08-08
    相关资源
    最近更新 更多