Amostra do App Engine e do Google Cloud Storage

Saiba como ativar o acesso do Cloud Storage ao aplicativo Python do App Engine e criar, gravar, ler e listar arquivos no intervalo do Cloud Storage.

Neste tutorial, presumimos que você esteja familiarizado com Python e já tenha passado pelo Guia de início rápido do ambiente padrão do App Engine para Python.

Quando executada, esse exemplo executa um script e grava a saída no navegador. O script demonstra os seguintes recursos da biblioteca de cliente do Cloud Storage:

  • Como criar um arquivo e gravá-lo em um intervalo.
  • Como ler o arquivo e receber os respectivos metadados.
  • Como criar vários arquivos e listá-los no intervalo.
  • Como listar os arquivos recém-adicionados ao intervalo.
  • Como ler esse mesmo conjunto de arquivos.
  • Como excluir esse conjunto de arquivos.

Objetivos

  • Percorrer o projeto Python para visualizar o layout e os arquivos necessários.
  • Entender o código para se conectar ao Cloud Storage.
  • Entender o código para criar, gravar, ler, listar e excluir arquivos.
  • Entender o código para novas tentativas.
  • Criar e testar o aplicativo em seu servidor de desenvolvimento local.
  • Implantar o aplicativo para produção no Google App Engine.

Custos

O App Engine tem um nível de uso gratuito. Se o uso total do App Engine for inferior aos limites especificados na cota gratuita do App Engine, não haverá cobrança por realizar este tutorial.

Antes de começar

Antes de executar este exemplo, você precisa do código do projeto, da ferramenta de linha de comando gcloud e de um intervalo do Cloud Storage:

  1. Crie um novo projeto do Console do GCP ou recupere o código de um projeto atual no Console do Google Cloud Platform:

    Acessar a página "Projetos"

    Dica: recupere uma lista de códigos de projetos existentes com a ferramenta de linha de comando gcloud.

  2. Instale e inicialize o Google Cloud SDK.

    Fazer o download do SDK

  3. Ative o intervalo do Cloud Storage padrão.

Como clonar o projeto de tutorial

Para clonar o projeto:

  1. Clone a biblioteca de cliente e o aplicativo de exemplo (demonstração) na máquina local.

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    

    Outra opção é fazer o download do exemplo como um arquivo zip e extraí-lo.

  2. Navegue até o diretório apropriado no projeto clonado ou transferido por download:

    cd python-docs-samples/appengine/standard/storage/appengine-client
    

Como instalar dependências

A ferramenta virtualenv permite criar um ambiente Python limpo no sistema. Para o desenvolvimento do App Engine, isso ajuda a garantir que o código testado localmente seja semelhante ao ambiente no qual seu código será implantado. Para saber mais, leia Como usar bibliotecas terceirizadas.

Para instalar o virtualenv e as dependências do exemplo:

Mac OS/Linux

  1. Caso não tenha o virtualenv (link em inglês), instale-o em todo o sistema usando o pip.
    sudo pip install virtualenv
  2. Crie um ambiente Python isolado em um diretório externo ao projeto e ative-o:
    virtualenv env
    source env/bin/activate
  3. Navegue até o diretório do projeto e instale as dependências:
    cd YOUR_PROJECT
    pip install -t lib -r requirements.txt

Windows

Se você instalou o SDK do Cloud, já deve ter o Python 2.7 instalado, normalmente em C:\python27_x64\ (para sistemas de 64 bits). Use o PowerShell para executar seus pacotes Python.

  1. Localize a instalação do PowerShell.
  2. Clique com o botão direito do mouse no atalho do PowerShell e inicie-o como administrador.
  3. Tente executar o comando python. Se ele não for encontrado, adicione a pasta Python ao PATH do ambiente.
    $env:Path += ";C:\python27_x64\"
  4. Caso não tenha o virtualenv (link em inglês), instale-o em todo o sistema usando o pip:
    python -m pip install virtualenv
  5. Crie um ambiente Python isolado em um diretório externo ao projeto e ative-o:
    python -m virtualenv env
    env\Scripts\activate
  6. Navegue até o diretório do projeto e instale as dependências:
    cd YOUR_PROJECT
    python -m pip install -t lib -r requirements.txt

O código de exemplo que você clonou ou fez o download já contém um arquivo appengine_config.py, que é necessário para instruir o App Engine a usar a pasta lib para carregar as dependências localmente e quando implantadas.

Como executar no local

Para executar o exemplo localmente:

  1. No subdiretório do projeto python-docs-samples/appengine/standard/storage/appengine-client, execute o aplicativo no [servidor de desenvolvimento local]:

    dev_appserver.py .
    
  2. Aguarde até ser exibida uma mensagem de êxito parecida com esta:

    INFO     2016-04-12 21:33:35,446 api_server.py:205] Starting API server at: http://localhost:36884
    INFO     2016-04-12 21:33:35,449 dispatcher.py:197] Starting module "default" running at: http://localhost:8080
    INFO     2016-04-12 21:33:35,449 admin_server.py:116] Starting admin server at: http://localhost:8000
    
  3. Acesse este URL no navegador:

    http://localhost:8080/

    O aplicativo será executado no carregamento da página, exibindo a saída para o navegador para indicar o que foi executado. A saída é assim:

    Hello_Storage

  4. Encerre o servidor de desenvolvimento pressionando Control-C.

Instruções do app.yaml

O arquivo app.yaml especifica detalhes de configuração do aplicativo:

runtime: python27
api_version: 1
threadsafe: yes

env_variables:

handlers:
- url: /blobstore.*
  script: blobstore.app

- url: /.*
  script: main.app

Para mais informações sobre as opções de configuração disponíveis neste arquivo, consulte a referência do app.yaml.

Instruções sobre importações

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

import os

import cloudstorage
from google.appengine.api import app_identity

import webapp2

É necessário ter o módulo os e a API app_identity para receber o nome do intervalo padrão no ambiente de execução. Você precisará desse nome do intervalo para todas as operações de acesso ao Cloud Storage.

O exemplo também usa a biblioteca da Web webapp2.

Como especificar o intervalo do Cloud Storage

Antes de realizar qualquer operação no Cloud Storage, é necessário fornecer o nome do intervalo. A maneira mais fácil de fazer isso é usando o intervalo 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: {}\n'.format(
            os.environ['CURRENT_VERSION_ID']))
    self.response.write('Using bucket name: {}\n\n'.format(bucket_name))

Como gravar um arquivo no Cloud Storage

O exemplo a seguir mostra como gravar no intervalo:

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

    self.response.write('Creating file {}\n'.format(filename))

    # The retry_params specified in the open call will override the default
    # retry params for this particular file handle.
    write_retry_params = cloudstorage.RetryParams(backoff_factor=1.1)
    with cloudstorage.open(
        filename, 'w', content_type='text/plain', options={
            'x-goog-meta-foo': 'foo', 'x-goog-meta-bar': 'bar'},
            retry_params=write_retry_params) as cloudstorage_file:
                cloudstorage_file.write('abcde\n')
                cloudstorage_file.write('f'*1024*4 + '\n')
    self.tmp_filenames_to_clean_up.append(filename)

Observe que, na chamada para abrir (open) o arquivo para gravação, o exemplo especifica determinados cabeçalhos do Cloud Storage que gravam metadados personalizados do arquivo. Esses metadados podem ser recuperados por meio cloudstorage.stat. É possível encontrar a lista de cabeçalhos compatíveis na referência de 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 intervalo.

Por último, observe a chamada para fechar (close) o arquivo depois de terminar a gravação. Se não fizer isso, o arquivo não será gravado no Cloud Storage. Esteja ciente de que, depois de chamar close, você não poderá anexar ao arquivo. Se for necessário modificar um arquivo, você precisará abri-lo novamente no modo de gravação, o que gera uma substituição, não um anexo.

Como ler um arquivo do Cloud Storage

O exemplo a seguir mostra como ler um arquivo a partir do intervalo.

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

    with cloudstorage.open(filename) as cloudstorage_file:
        self.response.write(cloudstorage_file.readline())
        cloudstorage_file.seek(-1024, os.SEEK_END)
        self.response.write(cloudstorage_file.read())

O exemplo mostra como exibir as linhas selecionadas do arquivo que está sendo lido. Neste caso, a linha de abertura e as últimas mil linhas, usando seek.

Observe que nenhum modo é especificado no código acima quando o arquivo é aberto para leitura. O padrão para open é o modo somente leitura.

Como listar conteúdo do intervalo

O código de exemplo mostra como percorrer um intervalo com um grande número de arquivos usando os parâmetros marker e max_keys por uma lista do conteúdo do intervalo:

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

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

    # Production apps should set page_size to a practical value.
    page_size = 1
    stats = cloudstorage.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 = cloudstorage.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 sua hierarquia de diretório mais reconhecível, defina o parâmetro delimiter como o delimitador de diretório que quer usar.

Como excluir arquivos

O exemplo de código mostra a exclusão de todos os arquivos adicionados durante a execução do aplicativo. Não faça isso no seu código, já que isso é somente um recurso de limpeza deste exemplo:

def delete_files(self):
    self.response.write('Deleting files...\n')
    for filename in self.tmp_filenames_to_clean_up:
        self.response.write('Deleting file {}\n'.format(filename))
        try:
            cloudstorage.delete(filename)
        except cloudstorage.NotFoundError:
            pass

Como implantar o exemplo

Para implantar e executar o exemplo no App Engine:

  1. Carregue o aplicativo de exemplo executando o seguinte comando no diretório python-docs-samples/appengine/standard/storage/appengine-client em que o arquivo app.yaml está localizado:

    gcloud app deploy
    

    Sinalizações opcionais:

    • Inclua a sinalização --project para especificar uma ID do projeto no Console do GCP como alternativa àquela definida como padrão na ferramenta gcloud. Exemplo: --project [YOUR_PROJECT_ID]
    • Inclua a sinalização -v para especificar uma ID da versão. Caso contrário, será gerada uma automaticamente. Exemplo: -v [YOUR_VERSION_ID]

    Dica: se você especificar um código de versão de um aplicativo que foi carregado anteriormente, a implantação substituirá a versão existente no App Engine. Isso nem sempre é desejável, especialmente se a versão no App Engine estiver veiculando tráfego. Para evitar a interrupção do tráfego para o aplicativo, você pode implantar o aplicativo com um código de versão diferente e depois mover o tráfego para essa versão. Para mais informações sobre a movimentação do tráfego, consulte divisão de tráfego.

  2. Depois que o processo de implantação for concluído, você poderá visualizar o aplicativo em https://[YOUR_PROJECT_ID].appspot.com executando o seguinte comando:

    gcloud app browse
    

    O aplicativo de demo é executado no carregamento da página, da mesma forma que quando você o executava localmente. No entanto, agora o aplicativo realmente gravará e lerá a partir do intervalo do Cloud Storage.

Para saber mais sobre como implantar o aplicativo na linha de comando, consulte Como implantar um aplicativo do Python 2.

A seguir