【问题标题】:Google Cloud Storage create_upload_url -- App Engine Flexible PythonGoogle Cloud Storage create_upload_url -- App Engine 灵活的 Python
【发布时间】:2017-02-07 10:10:43
【问题描述】:

在 Google App Engine 的常规(非灵活)实例上,您可以使用 Blobstore API 并创建一个 URL 以允许用户将文件直接上传到您的 Blobstore。上传后,您的应用引擎应用程序会收到文件位置通知并可以对其进行处理。 python代码的一个例子是:

from google.appengine.ext import blobstore
upload_url = blobstore.create_upload_url('/upload_photo')

the Blobstore docs

切换到 Google App Engine 柔性环境,usage of the Blobstore has been largely replaced by Cloud Storage。在这种情况下,是否有 create_upload_url 的等价物?

我当前的实现将标准文件上传到 python Flask 应用程序。然后继续进行如下操作:

from flask import request
from google.cloud import storage

uploaded_file = request.files.get('file')

gcs = storage.Client()
bucket = gcs.get_bucket(bucket_name)
blob = bucket.blob(blob_name)
blob.upload_from_string(
    uploaded_file.read(),
    content_type=uploaded_file.content_type
)

create_upload_url 相比,这似乎使网络负载增加了一倍,因为文件正在进入我的应用引擎实例,然后立即被复制出来。因此,在发生这种情况时,上传者将不得不等待额外的时间。据推测,我还将为此支付额外的 App Engine 费用。有没有更好的办法?

我有工作人员稍后处理上传的文件,但我倾向于在他们的代码中再次从 Cloud Storage 下载文件,因为我认为您不能假设工作人员仍然可以访问存储在实例中的文件文件系统。因此,将文件上传到我的实例而不是直接到它的存储位置并没有任何好处。

【问题讨论】:

  • 几天前我回答了一个类似的问题stackoverflow.com/questions/42002013/…,这可能会对您有所帮助。您可以使用创建上传处理程序的相同方法。
  • 感谢@Samson,但我认为google.appengine.ext.blobstore 包在 App Engine 柔性环境中不可用。也许我错了?
  • @JonG 你找到答案了吗?
  • 在@AneesHameed 下方添加了我的答案。

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


【解决方案1】:

我已经开始使用create_resumable_upload_session 创建一个签名 URL,我们的客户端应用程序可以将文件上传到该 URL。比如:

gcs = storage.Client()
bucket = gcs.get_bucket(BUCKET)
blob = bucket.blob(blob_name)
signed_url = blob.create_resumable_upload_session(content_type=content_type)

然后,当客户端成功将文件上传到我们的存储时,我使用此 Cloud Pub/Sub Notifications for Cloud Storage 订阅创建的 Pub/Sub 通知。

【讨论】:

  • 收到 Pub/Sub 通知后,您会如何处理? IIUC,这将来自一个完全独立的会话,与将浏览器重定向到应用程序中的另一个操作不同。所以我不知道如何根据他们上传的文件给用户一个响应。 (仅基于我猜它的工作原理。缺乏文档。)
  • 你是对的@philo,我没有在同一个请求中收到发布/订阅消息。相反,处理 pub/sub 消息的进程会更新数据库条目,然后将带有信息的消息发送到用户应用程序。对我来说,这是一条 Firebase 云消息,但也可能是其他东西:Web 套接字、轮询 api 的应用程序等。
【解决方案2】:

使用新的 Google 云存储客户端创建的每个 blob 都有一个 public_url 属性:

from flask import request
from google.cloud import storage

uploaded_file = request.files.get('file')

gcs = storage.Client()
bucket = gcs.get_bucket(bucket_name)
blob = bucket.blob('blob_name')
blob.upload_from_string(
    uploaded_file.read(),
    content_type=uploaded_file.content_type
)
url = blob.public_url

--

使用 Blobstore,您的实例中的 GAE 系统处理程序会处理您传递给创建的上传 URL 的上传文件。我不确定在您的代码中自己处理它是否是一个问题。如果您当前的方法有问题,您可能需要考虑执行上传客户端,并且根本不通过 App Engine 传递文件。 GCS有一个REST API,云存储客户端在下面使用它,所以如果更方便的话,你可以在客户端直接读取并上传文件到GCS。 firebase.google.com/docs/storage/web/upload-files 可帮助您轻松完成整个过程

【讨论】:

  • 感谢您的帮助。您的解决方案仍然需要将整个文件发送到我的应用引擎实例,然后转发到 Google Cloud Storage,这会在进出过程中产生费用,对吗?使用 create_upload_url,用户直接上传到 Blobstore,因此我只会为该上传产生费用。这有意义吗?
  • 嗯,通过 Blobstore,您实例中的 GAE 系统处理程序负责处理您传递给创建的上传 url 的上传文件。我不确定在您的代码中自己处理它是否是一个问题。如果您当前的方法有问题,您可能需要考虑进行上传客户端。 GCS有一个REST API,云存储客户端在下面使用它,所以如果更方便的话,你可以在客户端直接读取并上传文件到GCS。 firebase.google.com/docs/storage/web/upload-files 可以帮助您轻松完成整个过程
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
  • 2015-07-07
  • 2021-11-14
  • 2023-03-23
  • 2017-03-30
  • 2014-01-16
  • 2011-12-25
相关资源
最近更新 更多