Lee y escribe en Cloud Storage

En este documento, se describe cómo almacenar y recuperar datos mediante Cloud Storage en una app de App Engine que usa la biblioteca cliente de App Engine para Cloud Storage. Se supone que realizaste las tareas descritas en Configura Cloud Storage para activar un bucket de Cloud Storage y descargar las bibliotecas cliente. También se supone que sabes compilar una aplicación de App Engine, como se describe en la Guía de inicio rápido del entorno estándar de App Engine para Python 2.

Importaciones requeridas

El archivo main.py contiene las importaciones típicas que se usan para acceder a Cloud Storage a través de la biblioteca cliente:

import logging
import os
import cloudstorage as gcs
import webapp2

from google.appengine.api import app_identity

Necesitas el módulo os y la API de app_identity para obtener el nombre del bucket predeterminado en el entorno de ejecución. Ten en cuenta que si no usas el bucket predeterminado, necesitarás otra manera de proporcionar el nombre del bucket.

Cómo especificar el bucket de Cloud Storage

Antes de realizar cualquier operación en Cloud Storage, debes proporcionar el nombre del bucket. La forma más fácil de hacer esto es con el bucket predeterminado para tu proyecto, que puedes obtenerlo de la siguiente manera:

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')

La llamada a get_default_gcs_bucket_name se realiza de forma correcta solo si creaste el bucket predeterminado para tu proyecto.

Escribe en Cloud Storage

En el siguiente ejemplo, se muestra como escribir en el 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)

Ten en cuenta que en la llamada para abrir el archivo en el que deseas escribir, el ejemplo especifica determinados encabezados de Cloud Storage que escriben metadatos personalizados del archivo. Estos metadatos se pueden recuperar mediante cloudstorage.stat(). Puedes encontrar la lista de encabezados compatibles en la referencia de cloudstorage.open().

También, ten en cuenta que no se configuró el encabezado x-goog-acl. Esto significa que la LCA de Cloud Storage predeterminada de lectura pública se aplicará al objeto cuando se escriba en el bucket.

Por último, presta atención a la llamada para cerrar el archivo después de terminar la escritura. Si no lo haces, el archivo no se escribirá en Cloud Storage. Ten en cuenta que después de llamar a la función close() del archivo de Python, no puedes adjuntar el archivo. Si necesitas modificar un archivo, tienes que llamar a la función open() del archivo de Python para volver a abrirlo en el modo de escritura, lo cual reemplazará el archivo, no lo adjunta.

Lee en Cloud Storage

En el siguiente ejemplo, se muestra cómo leer un archivo del 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 leer las líneas seleccionadas del archivo, usa 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()

En ambos ejemplos, el argumento filename que pasas a cloudstorage.open() es la ruta de acceso al archivo en formato YOUR_BUCKET_NAME/PATH_IN_GCS. Ten en cuenta que la configuración predeterminada para cloudstorage.open() es el modo de solo lectura. No es necesario especificar un modo cuando se abre un archivo para leerlo.

Enumera el contenido del bucket

En el código de muestra, se indica cómo desplazarse por un bucket con una gran cantidad de archivos. A fin de desplazarse por una lista de contenidos del bucket, usa los parámetros marker y max_keys:

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)

Ten en cuenta que el nombre completo del archivo se muestra como una string sin delimitadores de directorio. Si deseas mostrar el archivo con su jerarquía de directorios más reconocible, establece el parámetro delimiter en el delimitador del directorio que deseas usar.

Borra archivos en Cloud Storage

En el siguiente código, se muestra cómo borrar un archivo de Cloud Storage mediante el 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 ejemplo limpia los archivos que se escribieron en el depósito en la sección Cómo escribir en Cloud Storage.

¿Qué sigue?