如何从远程谷歌云存储python中读取公共文件?

时间:2018-04-03 23:24:22

标签: python-3.x google-cloud-platform google-cloud-storage

我需要reed一些谷歌云存储中共享的CSV文件。我的脚本将从Google Cloud外部的另一台服务器运行。

我正在使用此代码:

from google.cloud import storage

client = storage.Client()
bucket = client.get_bucket('/stats/installs')
blob = storage.Blob('installs_overview.csv', bucket)  
content = blob.download_as_string()

print(content)

得到此错误:显然我还没有指定该项目,但我没有一个

OSError: Project was not passed and could not be determined from the environment.

3 个答案:

答案 0 :(得分:1)

首先,我认为可能存在一些关于云存储以及如何访问云存储的困惑。云存储是Google Cloud Platform产品,因此,要使用它,必须存在GCP Project。您可以在控制台的主页中找到项目的项目编号和项目ID,如this documentation page中所述。

话虽如此,让我推荐您关于Python Cloud Storage Client Library的文档页面。创建client以使用该服务时,您可以选择指定要使用的项目ID和/或凭证文件:

client = storage.Client(project="PROJECT_ID",credentials="OAUTH2_CREDS")

如果您未指定项目ID,则会从环境中推断出来。

另外,请注意您必须设置身份验证才能使用该服务。如果您在另一个GCP服务(计算引擎,App Engine等)中运行该应用程序,建议的方法是使用Application Default Credentials。但是,鉴于情况并非如此,您应该遵循this guide to set up authentication,下载有权使用云存储并在环境变量GOOGLE_APPLICATION_CREDENTIALS中指向它的服务帐户的密钥。

此外,考虑到您使用的存储桶名称('/stats/installs')无效,您的代码中的配置似乎不正确:

  

存储桶名称必须介于3到63个字符之间。 存储桶名称可以   包含小写字母数字字符,连字符和下划线。   如果它与a形成有效的域名,它可以包含点(。)   顶级域名(例如.com)。 存储桶名称必须以开头和结尾开头   一个字母数字字符

请注意,working with exceptions可以看到给定的存储分区不存在,特别是google.cloud.exceptions.NotFound。此外,鉴于您尝试访问的文件是公开的,我不建议共享存储桶和文件名,您只需使用<BUCKET_NAME>, <FILE_NAME>等代码对其进行模糊处理。

因此,作为总结,行动方针应该是:

  1. 确定您要使用的存储桶所属的项目。
  2. 获取正确的凭据以在该项目中使用GCS。
  3. 将项目和凭据添加到代码中。
  4. 使用正确的存储桶和文件名修复您共享的代码。请注意,如果文件位于文件夹中(即使在GCS中,目录的概念本身不存在,正如我在this other question中所解释的那样),storage.Blob()中的文件名应包含完整的路径,如{ {1}}。

答案 1 :(得分:1)

本主题先前的答案中存在一些错误的假设。

如果它是公共存储桶,则不必担心它连接到哪个项目。有据可查的文件,例如,您如何使用存储桶来托管浏览器可以访问的公共网站。显然,浏览器不必担心它属于哪个项目。

代码示例在使用公共存储桶和文件方面有些欠缺,在所有示例中,您都提供了项目和凭据,

1)在您提供的项目上,而不是在该桶所连接的项目上,进行比尔桶出口

2)假设您需要进行身份验证和授权。

对于公共文件或存储桶,您只需担心存储桶名称和文件位置即可。

您可以

from google.cloud import storage
source="path/to/file/in/bucket.txt"
target="/your/local/file.txt"
client = storage.Client.create_anonymous_client()
# you need to set user_project to None for anonymous access
# If not it will attempt to put egress bill on the project you specify,
# and then you need to be authenticated to that project.
bucket = client.bucket(bucket_name="your-bucket", user_project=None)
blob = storage.Blob(source, bucket)
blob.download_to_filename(filename=target, client=client)

重要的是,存储桶中的文件具有对“ AllUsers”的读取权限

答案 2 :(得分:0)

我不是谷歌云专家,但正如一些评论员所说,我认为问题在于你没有明确地告诉存储客户端你正在谈论哪个项目。该错误消息意味着存储客户端试图找出您所指的项目,如果它无法弄清楚,它会给出该错误消息。当我使用存储客户端时,我通常只提供项目名称作为参数,它似乎可以解决问题,例如:

client = storage.Client(project='my-uber-project')

另外,我刚刚看到你的评论说你的水桶“没有项目” - 我不明白这是怎么回事。如果您登录谷歌云控制台区域并转到存储,那么您的存储桶肯定会在那里列出,您可以在页面顶部看到您的项目名称吗?

正如@Mangu所说,你的代码中的存储桶名称可能只是为了隐藏真正的存储桶名称,因为存储桶名称中不允许使用正斜杠(但在blob名称中允许使用,也可以用来表示'文件夹' )。