Boto 用戶端程式庫外掛程式

本教學課程示範如何利用 XML API 編寫可執行基本 Cloud Storage 作業的簡單 Python 程式。本文假定您已熟悉 Python 以及在 Console 快速入門導覽課程中介紹的 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 設定檔,以使用 OAuth 2.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。這是建議的選項,是透過新 .boto 設定檔來使用 gsutil 的必備選項。

      • 設定環境變數 OAUTH2_CLIENT_IDOAUTH2_CLIENT_SECRET

      • 使用如下範例所示的 SetFallbackClientIdAndSecret 函式。

使用 Cloud Storage

設定您的 Python 來源檔案

如要開始本教學課程,請使用您慣用的文字編輯器來建立新的 Python 檔案。然後,新增以下顯示的指令、import 陳述式、組態及指派的常數值。

請注意,以下程式碼會使用 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 帳戶授予 FULL_CONTROL 的權限。請記得將「valid-email-address」取代為一個有效的 Google 帳戶電子郵件地址。

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
需要協助嗎?請前往我們的支援網頁