Exemplo do App Engine e do Google Cloud Storage

ID da região

REGION_ID é um código abreviado que o Google atribui com base na região selecionada na criação de seu app. O código não corresponde a um país ou uma província, mesmo que alguns IDs de região pareçam semelhantes aos códigos de país e província mais usados. Para aplicativos criados após fevereiro de 2020, o REGION_ID.r está incluído nos URLs do App Engine. Para apps existentes criados antes dessa data, o ID da região é opcional no URL. Saiba mais sobre IDs da região.

Saiba como ativar o acesso do Cloud Storage ao app Python do App Engine, além de criar, gravar, ler e listar arquivos no bucket do Cloud Storage.

No tutorial, pressupomos que você esteja familiarizado com o Python e tenha configurado seu ambiente de desenvolvimento.

Quando executada, este 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 bucket.
  • Como ler o arquivo e receber os respectivos metadados.
  • Como criar vários arquivos e listá-los no bucket.
  • Como listar os arquivos recém-adicionados ao bucket.
  • 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 de um ID de projeto, da ferramenta de linha de comando gcloud e de um bucket do Cloud Storage:

  1. Crie um novo projeto do Console ou recupere o ID de um projeto existente no Console do Google Cloud:

    Acessar a página "Projetos"

    Dica: recupere uma lista dos IDs de projetos atuais com a ferramenta de linha de comando gcloud.

  2. Instale e inicialize a Google Cloud CLI:

    Fazer o download do SDK

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

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 em que seu código será implantado. Para saber mais, leia Como usar bibliotecas de terceiros.

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

Mac OS/Linux

  1. Se você não tiver o virtualenv, instale-o em todo o sistema usando pip (links em inglês).
    sudo pip install virtualenv
  2. Crie um ambiente Python isolado:
    virtualenv env
    source env/bin/activate
  3. Se você não estiver no diretório que contém o código de amostra, navegue até o diretório que contém o código de amostra hello_world. Em seguida, instale as dependências:
    cd YOUR_SAMPLE_CODE_DIR
    pip install -t lib -r requirements.txt

Windows

Se você instalou a Google Cloud CLI, certamente já tem o Python 2.7 instalado, normalmente em C:\python27_x64\ (sistemas de 64 bits). Use o PowerShell para executar os 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. Se você não tiver o virtualenv, instale-o em todo o sistema usando pip (links em inglês).
    python -m pip install virtualenv
  5. Crie um ambiente Python isolado.
    python -m virtualenv env
    . env\Scripts\activate
  6. Acesse o diretório do projeto e instale as dependências: Se você não estiver no diretório que contém o código de amostra, navegue até o diretório que contém o código de amostra hello_world. Em seguida, instale as dependências:
    cd YOUR_SAMPLE_CODE_DIR
    python -m pip install -t lib -r requirements.txt

O código de exemplo clonado ou salvo já contém um arquivo appengine_config.py, 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 python-docs-samples/appengine/standard/storage/appengine-client do projeto, execute o app 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 resposta é semelhante a esta:

    Hello_Storage

  4. Para encerrar o servidor de desenvolvimento, pressione Control+C.

Tutorial do app.yaml

O arquivo app.yaml especifica os 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.

Tutorial 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

Você precisa do módulo os e da API app_identity para receber o nome do bucket padrão no ambiente de execução. Você precisará desse nome do bucket em todas as operações de acesso ao Cloud Storage.

No exemplo, também usamos o framework da Web webapp2.

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: {}\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 bucket:

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)

Na chamada a open para abrir o arquivo para gravação, o exemplo específica 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 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 bucket.

Por fim, observe a chamada a close para fechar o arquivo depois de concluir a gravação. Se você não fizer isso, o arquivo não será gravado no Cloud Storage. Depois de chamar close, não será possível 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

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

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

No exemplo, veja 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 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."""

    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 única 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 pretende 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, porque é 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. Faça upload do aplicativo de exemplo executando o comando a seguir 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 um ID de projeto alternativo do Console para o que você inicializou como padrão na CLI gcloud. Exemplo: --project [YOUR_PROJECT_ID]
    • Inclua a sinalização -v para especificar um ID de versão, caso contrário, um será gerado para você. Exemplo: -v [YOUR_VERSION_ID]

    Dica: se você especificar um ID de versão de um aplicativo que foi carregado anteriormente, a implantação substituirá a versão atual 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. Após a conclusão do processo de implantação, visualize o aplicativo em https://PROJECT_ID.REGION_ID.r.appspot.com executando o comando a seguir:

    gcloud app browse
    

    O app demo é executado no carregamento da página, assim como ocorreu quando você o executou localmente. No entanto, agora o app realmente fará leitura e gravação no bucket 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