【问题标题】:How to directly send file to client from google storage in python?如何在python中从谷歌存储直接向客户端发送文件?
【发布时间】:2021-01-14 20:04:11
【问题描述】:

我想根据请求从谷歌存储向客户端发送任何文件,但它在服务器上本地下载。我不会在本地下载,而是可以通过任何方式直接将文件发送给客户端。

目前我正在这样做下载

def download_file(self, bucket, key, path_to_download):
        bucket = gc_storage.storage_client.bucket(bucket)
        blob = bucket.blob(key)
        blob.download_to_filename(path_to_download)

【问题讨论】:

  • 这是一个有趣的问题,我肯定看到了一个用例,尤其是在处理大文件时。我会看看smart_open,因为它现在支持 gcs。此外,this 应该为您指明正确的方向。

标签: python stream google-cloud-storage fastapi bytesio


【解决方案1】:

我认为没有 API 方法可以将数据从 GCS 加载到通用的第三个位置,尽管某些特定用例存在一些数据传输选项。

如 cmets 中所述,smart-open 可能是此处的一个选项,前提是您至少愿意通过您的服务器流式传输数据。也许是这样的:

from dotenv import load_dotenv
from google.cloud.storage import Client
from os import getenv
from smart_open import open


# load environment variables from a file
load_dotenv("<path/to/.env")

# get the path to a service account credentials file from an environment variable
service_account_path = getenv("GOOGLE_APPLICATION_CREDENTIALS")

# create a client using the service account credentials for authentication
gcs_client = Client.from_service_account_json(service_account_path)

# use this client to authenticate your transfer
transport = {"client": gcs_client}


with open("gs://my_bucket/my_file.txt", transport_params=transport) as f_in:
    with open("gs://other_bucket/my_file.txt", "wb", transport_params=transport) as f_out:
        for line in f_in:
            f_out.write(line)

在这里,我已经写出了使用服务帐户执行此操作的完整机制,假设您默认没有经过身份验证。我的理解是,如果您的计算机已经设置为使用一些默认凭据连接到 GCS,您也许可以删除其中的大部分内容:

from smart_open import open

with open("gs://my_bucket/my_file.txt") as f_in:
    with open("gs://other_bucket/my_file.txt", "wb") as f_out:
        for line in f_in:
            f_out.write(line)

另请注意,我编写此代码时就像您将文件从一个 GCS 存储桶传输到另一个存储桶一样 - 但这实际上是其中一种 内置 API 方法的情况实现目标!

# ... [obtain gcs_client as before] ...

my_bucket = gcs_client.get_bucket("my-bucket")
other_bucket = gcs_client.get_bucket("other-bucket")

my_file = my_bucket.get_blob("my-file.txt")

my_bucket.copy_blob(my_file, other_bucket)

听起来您实际上想要做的是将数据传递给第三方,因此内部 with 语句需要替换为您实际使用的任何实现。

【讨论】:

  • 我的重点是不要使用本地文件系统来下载文件,而是以字节存储,顺便说一句,谢谢你的努力。我知道了如何使用字节流来存储 gs 存储中的对象。所以从字节开始,我可以做我想做的事。
猜你喜欢
  • 2020-07-20
  • 2018-04-17
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
相关资源
最近更新 更多