Como ler e gravar no Cloud Storage

Neste documento, você verá a descrição de como armazenar e recuperar dados usando a biblioteca de cliente do App Engine para Cloud Storage. O ideal é que você já tenha concluído as tarefas descritas na seção Como configurar o Google Cloud Storage para ativar um bucket do Cloud Storage e fazer o download das bibliotecas de cliente. Também é necessário que você saiba criar um aplicativo do App Engine, conforme descrito em Guia de início rápido do ambiente padrão do App Engine para Python 2.

Importações obrigatórias

O arquivo main.py contém as importações típicas usadas para acessar o Cloud Storage pela biblioteca de cliente:

import logging
import os
import cloudstorage as gcs
import webapp2

from google.appengine.api import app_identity

Você precisa do módulo os e da API app_identity para receber o nome do bucket padrão no ambiente de execução. Observe que será preciso encontrar outra maneira de fornecer o nome do bucket caso o bucket padrão não seja usado.

Como especificar o bucket do Cloud Storage

Antes de realizar qualquer operação no Cloud Storage, é necessário fornecer o nome do bucket. A maneira mais fácil de fazer isso é usando o bucket padrão do projeto, que pode ser recebido da seguinte maneira:

def get(self):
  bucket_name = os.environ.get('BUCKET_NAME',
                               app_identity.get_default_gcs_bucket_name())

  self.response.headers['Content-Type'] = 'text/plain'
  self.response.write('Demo GCS Application running from Version: '
                      + os.environ['CURRENT_VERSION_ID'] + '\n')
  self.response.write('Using bucket name: ' + bucket_name + '\n\n')

A chamada para get_default_gcs_bucket_name terá êxito se você tiver criado o bucket padrão para seu projeto.

Como gravar no Cloud Storage

No exemplo a seguir, mostramos como gravar no bucket:

def create_file(self, filename):
  """Create a file.

  The retry_params specified in the open call will override the default
  retry params for this particular file handle.

  Args:
    filename: filename.
  """
  self.response.write('Creating file %s\n' % filename)

  write_retry_params = gcs.RetryParams(backoff_factor=1.1)
  gcs_file = gcs.open(filename,
                      'w',
                      content_type='text/plain',
                      options={'x-goog-meta-foo': 'foo',
                               'x-goog-meta-bar': 'bar'},
                      retry_params=write_retry_params)
  gcs_file.write('abcde\n')
  gcs_file.write('f'*1024*4 + '\n')
  gcs_file.close()
  self.tmp_filenames_to_clean_up.append(filename)

Observe que, na chamada para abrir o arquivo para gravação, a amostra especifica determinados cabeçalhos do Cloud Storage que gravam metadados personalizados para o arquivo. Esses metadados podem ser recuperados usando cloudstorage.stat(). Encontre a lista de cabeçalhos compatíveis na referência cloudstorage.open().

Observe também que o cabeçalho x-goog-acl não está definido. Isso significa que a ACL padrão do Cloud Storage de leitura pública será aplicada ao objeto quando ele for gravado no bucket.

Por último, observe a chamada para fechar o arquivo depois de terminar a gravação. Se não a usar, o arquivo não será gravado no Cloud Storage. Depois de chamar a função do arquivo em Python close(), não será possível anexar ao arquivo. Se você precisar modificar um arquivo, precisará chamar a função do arquivo em Python open() para abrir o arquivo novamente no modo de gravação, o que gera uma substituição, não um anexo.

Como fazer a leitura do Cloud Storage

No exemplo a seguir, mostramos como ler um arquivo pelo bucket:

def read_file(self, filename):
  self.response.write('Reading the full file contents:\n')

  gcs_file = gcs.open(filename)
  contents = gcs_file.read()
  gcs_file.close()
  self.response.write(contents)

Para ler as linhas selecionadas no arquivo, use seek():

def read_partial_file(self, filename):
  self.response.write('Abbreviated file content (first line and last 1K):\n')

  gcs_file = gcs.open(filename)
  self.response.write(gcs_file.readline())
  gcs_file.seek(-1024, os.SEEK_END)
  self.response.write(gcs_file.read())
  gcs_file.close()

Em ambos os exemplos, o argumento filename que você transmite para cloudstorage.open() é o caminho para seu arquivo no formato YOUR_BUCKET_NAME/PATH_IN_GCS. O padrão para cloudstorage.open() é o modo somente leitura. Não é preciso especificar um modo ao abrir um arquivo para lê-lo.

Como listar conteúdo do bucket

No código de exemplo, veja como percorrer um bucket com muitos arquivos usando os parâmetros marker e max_keys, que percorrem uma lista do conteúdo do bucket:

def list_bucket(self, bucket):
  """Create several files and paginate through them.

  Production apps should set page_size to a practical value.

  Args:
    bucket: bucket.
  """
  self.response.write('Listbucket result:\n')

  page_size = 1
  stats = gcs.listbucket(bucket + '/foo', max_keys=page_size)
  while True:
    count = 0
    for stat in stats:
      count += 1
      self.response.write(repr(stat))
      self.response.write('\n')

    if count != page_size or count == 0:
      break
    stats = gcs.listbucket(bucket + '/foo', max_keys=page_size,
                           marker=stat.filename)

Observe que o nome completo do arquivo é exibido como uma string sem delimitadores de diretório. Se você quiser exibir o arquivo com a hierarquia de diretórios mais reconhecível, defina o parâmetro delimiter como o delimitador de diretório que quer usar.

Como excluir arquivos no Cloud Storage

O código abaixo demonstra como excluir um arquivo do Cloud Storage usando o método cloudstorage.delete() (importado como gcs).

def delete_files(self):
  self.response.write('Deleting files...\n')
  for filename in self.tmp_filenames_to_clean_up:
    self.response.write('Deleting file %s\n' % filename)
    try:
      gcs.delete(filename)
    except gcs.NotFoundError:
      pass

Este exemplo limpa os arquivos que foram gravados no bucket na seção Como gravar no Cloud Storage.

A seguir