Boto 客户端库插件

本教程向您展示了如何编写一个使用 XML API 执行基本 Cloud Storage 操作的简单 Python 程序。本文档假定您熟悉控制台快速入门中介绍的 Python 和 Cloud Storage 概念及操作。

您应该改用 Cloud Storage 客户端库吗?

通常,您应该使用适用于 Python 的 Cloud Storage 客户端库对 Cloud Storage 存储分区和对象进行操作。Cloud Storage 客户端库提供了更大的灵活性,Cloud Storage 指南中的代码示例便使用了 Cloud Storage 客户端库。如果您希望通过 XML API 和 boto 库与 Cloud Storage 进行交互,请参阅本指南。

设置您的环境

在开始本教程之前,您必须执行以下操作:

  1. 在您的计算机上安装独立版 gsutil

  2. 安装 boto 库和 gcs-oauth2-boto-plugin

    boto 是一个开源 Python 库,用作 Cloud Storage 的接口。gcs-oauth2-boto-plugin 是 boto 身份验证插件框架的身份验证插件。它提供了可与 Cloud Storage 结合使用的 OAuth 2.0 凭据。

    boto 库和 oauth2 插件的使用设置取决于您使用的系统。请以下面的设置示例作为指导。这些命令可以安装 pip,然后使用 pip 安装其他软件包。最后三个命令用于测试这两个模块的导入,以便对安装进行验证。

    Debian 和 Ubuntu

    wget https://bootstrap.pypa.io/get-pip.py
    sudo python get-pip.py
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install gcc python-dev python-setuptools libffi-dev libssl-dev
    sudo pip install virtualenv
    virtualenv venv
    source ./venv/bin/activate
    (venv)pip install gcs-oauth2-boto-plugin
    (venv)python
    >>>import boto
    >>>import gcs_oauth2_boto_plugin

    CentOS、RHEL 和 Fedora

    wget https://bootstrap.pypa.io/get-pip.py
    sudo python get-pip.py
    sudo yum install gcc openssl-devel python-devel python-setuptools libffi-devel
    sudo pip install virtualenv
    virtualenv venv
    source ./venv/bin/activate
    (venv)pip install gcs-oauth2-boto-plugin
    (venv)python
    >>>import boto
    >>>import gcs_oauth2_boto_plugin
  3. 设置 boto 配置文件以使用 OAuth2.0。

    您可以配置 boto 配置文件,以使用服务帐号凭据或用户帐号凭据。代表服务或应用进行身份验证时,服务帐号凭据是要使用的首选凭据类型。代表特定用户(即某人)对请求进行身份验证时,用户帐号凭据是要使用的首选凭据类型。如需详细了解这两种凭据类型,请参阅支持的凭据类型

    服务帐号

    如需使用服务帐号凭据,请执行以下操作:

    1. 使用现有服务帐号或创建一个新帐号,然后下载关联的私钥。将密钥下载为 .json 文件是默认和首选设置,但也支持使用 .p12 格式。

    2. 使用服务帐号配置 .boto 文件。您可以使用 gsutil 完成此操作:

      gsutil config -e

      命令会提示您输入服务帐号电子邮件地址和服务帐号私钥(.json.p12)的位置。请务必在运行 gsutil 命令的计算机上保存私钥。

    用户帐号

    如需使用用户帐号凭据,请执行以下操作:

    1. 如果您还没有 .boto 文件,请创建一个文件。您可以使用 gsutil 完成此操作。

      gsutil config
    2. 使用应用的现有客户端 ID 或创建新的客户端 ID。

    3. 修改 .boto 文件。在 [OAuth2] 部分中,使用您生成的值指定 client_idclient_secret 值。

    4. 再次运行 gsutil config 命令,以便根据您输入的客户端 ID 和密钥生成刷新令牌。

      如果您收到一条错误消息(表明无法备份 .boto),请移除或重命名备份配置文件 .boto.bak

    5. 配置刷新令牌回退逻辑。

      当您使用应用凭据时,gcs-oauth2-boto-plugin 需要通过回退逻辑来生成身份验证令牌。使用服务帐号时,不需要回退逻辑。

      您可以使用以下选项启用回退:

      • .boto 配置文件中设置 client_idclient_secret。建议您选择此选项;如果要结合使用 gsutil 和新的 .boto 配置文件,则您必须使用此选项。

      • 设置环境变量 OAUTH2_CLIENT_IDOAUTH2_CLIENT_SECRET

      • 使用 SetFallbackClientIdAndSecret 函数(如下面的示例所示)。

使用 Cloud Storage

设置 Python 源文件

如需开始本教程,请使用您首选的文本编辑器来创建新的 Python 文件。然后,添加以下指令,导入所示的语句、配置和常量赋值。

请注意,以下代码使用 SetFallbackClientIdAndSecret 函数作为回退,以便生成刷新令牌。如需了解其他指定回退的方法,请参阅设置环境。如果您使用服务帐号进行身份验证,则无需包含回退逻辑。

#!/usr/bin/python

import boto
import gcs_oauth2_boto_plugin
import os
import shutil
import StringIO
import tempfile
import time

# URI scheme for Cloud Storage.
GOOGLE_STORAGE = 'gs'
# URI scheme for accessing local files.
LOCAL_FILE = 'file'

# Fallback logic. In https://console.cloud.google.com/
# under Credentials, create a new client ID for an installed application.
# Required only if you have not configured client ID/secret in
# the .boto file or as environment variables.
CLIENT_ID = 'your client id'
CLIENT_SECRET = 'your client secret'
gcs_oauth2_boto_plugin.SetFallbackClientIdAndSecret(CLIENT_ID, CLIENT_SECRET)

创建存储分区

以下代码会创建两个存储分区。由于存储分区名称必须具有全局唯一性(请参阅命名准则),因此,系统将向每个存储分区名称附加时间戳以确保名称的唯一性。

如果这些存储分区名称已被使用,您需要修改代码以生成唯一的存储分区名称。

now = time.time()
CATS_BUCKET = 'cats-%d' % now
DOGS_BUCKET = 'dogs-%d' % now

# Your project ID can be found at https://console.cloud.google.com/
# If there is no domain for your project, then project_id = 'YOUR_PROJECT'
project_id = 'YOUR_DOMAIN:YOUR_PROJECT'

for name in (CATS_BUCKET, DOGS_BUCKET):
  # Instantiate a BucketStorageUri object.
  uri = boto.storage_uri(name, GOOGLE_STORAGE)
  # Try to create the bucket.
  try:
    # If the default project is defined,
    # you do not need the headers.
    # Just call: uri.create_bucket()
    header_values = {"x-goog-project-id": project_id}
    uri.create_bucket(headers=header_values)

    print 'Successfully created bucket "%s"' % name
  except boto.exception.StorageCreateError, e:
    print 'Failed to create bucket:', e

列出存储分区

如需检索所有存储分区的列表,请调用 storage_uri() 以实例化一个 BucketStorageUri 对象(将空字符串指定为 URI)。然后调用 get_all_buckets() 实例方法。

uri = boto.storage_uri('', GOOGLE_STORAGE)
# If the default project is defined, call get_all_buckets() without arguments.
for bucket in uri.get_all_buckets(headers=header_values):
  print bucket.name

上传对象

如需上传对象,请创建指向本地文件的文件对象(已打开进行读取)以及指向 Cloud Storage 上的目标对象的存储空间 URI 对象。调用 set_contents_from_file() 实例方法,将文件句柄指定为参数。

# Make some temporary files.
temp_dir = tempfile.mkdtemp(prefix='googlestorage')
tempfiles = {
    'labrador.txt': 'Who wants to play fetch? Me!',
    'collie.txt': 'Timmy fell down the well!'}
for filename, contents in tempfiles.iteritems():
  with open(os.path.join(temp_dir, filename), 'w') as fh:
    fh.write(contents)

# Upload these files to DOGS_BUCKET.
for filename in tempfiles:
  with open(os.path.join(temp_dir, filename), 'r') as localfile:

    dst_uri = boto.storage_uri(
        DOGS_BUCKET + '/' + filename, GOOGLE_STORAGE)
    # The key-related functions are a consequence of boto's
    # interoperability with Amazon S3 (which employs the
    # concept of a key mapping to localfile).
    dst_uri.new_key().set_contents_from_file(localfile)
  print 'Successfully created "%s/%s"' % (
      dst_uri.bucket_name, dst_uri.object_name)

shutil.rmtree(temp_dir)  # Don't forget to clean up!

列出对象

如需列出存储分区中的所有对象,请调用 storage_uri() 并将存储分区的 URI 和 Cloud Storage URI 架构指定为参数。然后,使用 get_bucket() 实例方法检索对象列表。

uri = boto.storage_uri(DOGS_BUCKET, GOOGLE_STORAGE)
for obj in uri.get_bucket():
  print '%s://%s/%s' % (uri.scheme, uri.bucket_name, obj.name)
  print '  "%s"' % obj.get_contents_as_string()

下载和复制对象

以下代码可读取 DOGS_BUCKET 中的对象并将它们复制到主目录和 CATS_BUCKET 中。该代码还演示了一个场景,即您可以使用 boto 库,通过相同的界面对本地文件和 Cloud Storage 对象执行操作。

dest_dir = os.getenv('HOME')
for filename in ('collie.txt', 'labrador.txt'):
  src_uri = boto.storage_uri(
      DOGS_BUCKET + '/' + filename, GOOGLE_STORAGE)

  # Create a file-like object for holding the object contents.
  object_contents = StringIO.StringIO()

  # The unintuitively-named get_file() doesn't return the object
  # contents; instead, it actually writes the contents to
  # object_contents.
  src_uri.get_key().get_file(object_contents)

  local_dst_uri = boto.storage_uri(
      os.path.join(dest_dir, filename), LOCAL_FILE)

  bucket_dst_uri = boto.storage_uri(
      CATS_BUCKET + '/' + filename, GOOGLE_STORAGE)

  for dst_uri in (local_dst_uri, bucket_dst_uri):
    object_contents.seek(0)
    dst_uri.new_key().set_contents_from_file(object_contents)

  object_contents.close()

流式传输

如需以流式传输方式执行上传过程,请使用以下代码:

dst_uri = boto.storage_uri(<bucket> + '/' + <object>, 'gs')
dst_uri.new_key().set_contents_from_stream(<stream object>)

例如,以下代码通过流式传输将名为 data_file 的文件上传到具有相同名称的对象:

filename = 'data_file'
MY_BUCKET = 'my_app_bucket'
my_stream = open(filename, 'rb')
dst_uri = boto.storage_uri(MY_BUCKET + '/' + filename, 'gs')
dst_uri.new_key().set_contents_from_stream(my_stream)

如需以流式传输方式执行下载过程,请使用以下代码:

import sys

src_uri = boto.storage_uri(<bucket> + '/' + <object>, 'gs')
src_uri.get_key().get_file(sys.stdout)

例如,以下代码以流式传输方式下载名为 data_file 的对象:

downloaded_file = 'saved_data_file'
MY_BUCKET = 'my_app_bucket'
object_name = 'data_file'
src_uri = boto.storage_uri(MY_BUCKET + '/' + object_name, 'gs')
src_uri.get_key().get_file(sys.stdout)

更改对象 ACL

以下代码可向指定的 Google 帐号授予 labrador.txt 的 FULL_CONTROL 权限。请务必使用有效的 Google 帐号电子邮件地址替换 valid-email-address

uri = boto.storage_uri(DOGS_BUCKET + '/labrador.txt', GOOGLE_STORAGE)
print str(uri.get_acl())
uri.add_email_grant('FULL_CONTROL', 'valid-email-address')
print str(uri.get_acl())

读取存储分区和对象元数据

此代码可检索并输出与存储分区和对象关联的元数据。

# Print ACL entries for DOGS_BUCKET.
bucket_uri = boto.storage_uri(DOGS_BUCKET, GOOGLE_STORAGE)
for entry in bucket_uri.get_bucket().get_acl().entries.entry_list:
  entry_id = entry.scope.id
  if not entry_id:
    entry_id = entry.scope.email_address
  print 'SCOPE: %s' % entry_id
  print 'PERMISSION: %s\n' % entry.permission

# Print object metadata and ACL entries.
object_uri = boto.storage_uri(DOGS_BUCKET + '/labrador.txt', GOOGLE_STORAGE)
key = object_uri.get_key()
print ' Object size:\t%s' % key.size
print ' Last mod:\t%s' % key.last_modified
print ' MIME type:\t%s' % key.content_type
print ' MD5:\t%s' % key.etag.strip('"\'') # Remove surrounding quotes
for entry in key.get_acl().entries.entry_list:
  entry_id = entry.scope.id
  if not entry_id:
    entry_id = entry.scope.email_address
  print 'SCOPE: %s' % entry_id
  print 'PERMISSION: %s\n' % entry.permission

删除对象和存储分区

在本教程结束时,此代码将删除您创建的对象和存储分区。在删除存储分区之前,存储分区必须清空数据,因此,系统将首先删除存储分区中的对象。

for bucket in (CATS_BUCKET, DOGS_BUCKET):
  uri = boto.storage_uri(bucket, GOOGLE_STORAGE)
  for obj in uri.get_bucket():
    print 'Deleting object: %s...' % obj.name
    obj.delete()
  print 'Deleting bucket: %s...' % uri.bucket_name
  uri.delete_bucket()
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Cloud Storage
需要帮助?请访问我们的支持页面