【问题标题】:ferris2-framework, python, google app engine, cloud storage -- uploading an image and making it public?ferris2-framework、python、google app engine、云存储——上传图片并公开?
【发布时间】:2015-10-04 23:28:37
【问题描述】:

所以 google ferris2 框架似乎只使用 blobstore api 用于 Upload 组件,这让我质疑是否可以将图像上传到云存储公开而无需编写自己的上传方法并放弃使用 Upload 组件总的来说,这似乎在使用云存储客户端库(python)时也会产生兼容性问题。

背景故事/背景

  1. 使用-谷歌应用引擎、python、云存储客户端库

要求 0.5 我们要求将blob信息和文件存储在模型中。我们想要一个模型上的公共云服务 url,仅此而已。这似乎阻止了我们使用正常的 ferris 方法上传到云存储。

我已经知道的事情/路障 最大的障碍之一是使用 cgi / blobstore api 在表单上进行字段存储来处理 Ferris。这似乎会引起问题,因为到目前为止它还不允许通过谷歌云存储 python 客户端将数据发送到云存储。

我们对谷歌云存储python客户端和cgi的了解: 要将数据从我们的服务器写入云存储,需要使用 cloudstorage.open("/bucket/object", "w", ...) 调用云存储(云存储库方法)。但是,到目前为止,在将数据应用于模型之前,在应用数据之后,似乎从 wtforms.fields.FileField() 的帖子中返回了 cgi.FieldStorage(如简单的“打印图像”语句所示)对于模型来说,它是一个 blob 存储实例。

我想对此进行验证: 经过大量研究和测试,似乎由于ferris仅限于上传组件的blobstore api,因此使用blob store api和blob键来处理上传似乎基本上是不可避免的,而无需为云创建第二个上传功能存储调用。 Blob 实例似乎与该云存储客户端库不兼容,并且似乎除了从 Blob 文件中获取元数据之外没有其他方法(实际上没有调用云存储来获取原始文件)。但是,这似乎不需要在服务器上存储额外的数据。此外,我相信可以通过将整个存储桶设置为具有读取权限来解决公共链接问题。

澄清问题: 1. 要通过我们的应用程序向公众提供上传的图像(任何用户,而不是经过身份验证的用户),我是否必须使用 cloudstorage python 客户端库,或者有没有办法使用 blobstore api 做到这一点?

  1. 有没有一种方法可以从 blob 键(使用添加操作方法保存时)获取原始文件,而无需先调用云存储,以便可以使用该库上传文件?

  2. 如果没有,有没有办法从 cgi.FieldStorage 中抓取文件,然后使用 python 客户端库发送到云存储?似乎使用 cgi.FieldStorage.value 只是元数据而不是文件,与 cgi.FieldStorage.file.read() 相同

【问题讨论】:

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


    【解决方案1】:

    1) 您不能使用 GAE GCS 客户端更新 ACL。

    2) 您可以在 blobstore 上传到 GCS 后使用 GCS json API 并更改 ACL 以使其公开。您不必再次上传。 请参阅 this example code 插入 acl。

    3) 或使用 cgi.Fieldstorage 读取数据 (

    import cloudstorage as gcs
    import mimetypes
    
    class UploadHandler(webapp2.RequestHandler):
    
        def post(self):
    
            file_data = self.request.get("file", default_value=None)
            filename = self.request.POST["file"].filename
            content_type = mimetypes.guess_type(self.filename)[0]
    
            with gcs.open(filename, 'w', content_type=content_type or b'binary/octet-stream',
                          options={b'x-goog-acl': b'public-read'}) as f:
                f.write(file_data)
    

    第三种方法:使用带有 GCS 签名 url 和策略文档的表单 post upload 来控制上传。

    而且您始终可以使用公共下载处理程序,该处理程序从 blobstore 或 GCS 读取文件。

    【讨论】:

    • 那么有趣的是,几天前我创建了 webapp2.RequestHandler post 方法并使用 html 表单上传文件,正如您在此处所建议的那样,效果很好。为什么这不适用于 wtforms ?为什么它不适用于 ferris 框架?我什至尝试从 webapp2 以及 Controller 继承,但它仍然不喜欢它。而且我仍然不知道如何从 cgi.FileField 中获取文件,以便我可以使用“w”选项调用 gcs.open,似乎我只能从 cgi.FieldStorage 中获取元数据,这就是它。
    • 我想我应该补充一点,我成功地使用 blobstore api 上传了文件,因为它与 cgi 兼容,以及通过将整个存储桶设置为公开链接具有公共权限,但似乎此方法将 blob 放入 blob 存储中,创建更多存储数据.. 理想情况下,仍将使用 ferris 框架,并且上传方法将使用 gcs.open(...
    • 我不熟悉摩天轮。但我读到:自动处理需要使用 blobstore/云存储的文件上传字段。使用默认配置,这将上传到应用程序的默认 Google Cloud Storage 存储桶。此行为可在 app/settings.py 中配置。
    • 是的,ferris 云存储实现工作,正如您所描述的(几天前自己测试过),但它使用 blobstore api 这样做,导致 blob 被上传。此外,如文档中所建议的,要在不修改的情况下使用它,它需要模型上的一个额外字段,在数据存储中创建额外的存储......所以我们正在寻找一种 gcs.open(... 方式。摩天轮基本上是一个应用引擎的 MVC 框架。
    • 我的回答中的第三个选项是一个很好的解决方案。看到这个问题:stackoverflow.com/questions/31452720/…它不使用blobstore,你有很多选项来控制上传。
    【解决方案2】:

    您现在可以在将文件从 App Engine 上传到 Cloud Storage 时指定 ACL。不知道用了多久,只是想分享一下:

        filename = '/' + bucket_name + '/Leads_' + newUNID() + '.csv'
    
        write_retry_params = gcs.RetryParams(backoff_factor=1.1)
        gcs_file = gcs.open(filename,
                            'w',
                            content_type='text/csv',
                            options={'x-goog-acl': 'public-read'},
                            retry_params=write_retry_params)
    

    文档:https://cloud.google.com/storage/docs/xml-api/reference-headers#standard

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 2016-01-09
      • 2017-05-04
      • 2015-02-07
      • 2012-09-05
      相关资源
      最近更新 更多