Como implantar um aplicativo da Web Python Flask no ambiente flexível do App Engine

Resumo

Neste codelab, você vai aprender a implantar um aplicativo da Web Python Flask no ambiente flexível do App Engine. Com o aplicativo de exemplo, o usuário pode fazer upload da foto do rosto de alguém e descobrir se a pessoa está feliz. O aplicativo usa as APIs do Google Cloud para o Vision, o Storage e o Datastore.

Sobre o App Engine

Os aplicativos do Google App Engine são fáceis de criar, manter e escalonar de acordo com as alterações necessárias no tráfego e no armazenamento de dados. Com o App Engine, você não precisa se preocupar com a manutenção dos servidores. Basta fazer upload do seu aplicativo.

Os aplicativos do App Engine têm escalonamento automático com base em tráfego de entrada, balanceamento de carga, microsserviços, autorização, bancos de dados SQL e NoSQL, divisão de tráfego, geração de registros, pesquisa, controle de versões, implantações, reversões e verificações de segurança. Tudo isso tem compatibilidade nativa e é altamente personalizável.

O ambiente flexível do App Engine é compatível com todas as seguintes linguagens de programação: C#, Go, Java, Node.js, PHP, Python e Ruby. O ambiente flexível do App Engine executa seu aplicativo em contêineres do Docker nas máquinas virtuais do Google Compute Engine. O ambiente padrão do App Engine é uma opção alternativa para determinadas linguagens, incluindo Python. O ambiente padrão do App Engine executa seu aplicativo em um ambiente de sandbox mais restritivo. Confira mais informações em Como escolher um ambiente do App Engine.

O que você vai aprender

  • Como implantar um aplicativo da Web simples no ambiente flexível do App Engine
  • Como acessar bibliotecas de cliente do Google Cloud para o Vision, o Storage e o Datastore
  • Como usar o console do Google Cloud e o SDK Google Cloud para gerenciar vários recursos da nuvem
  • Como usar o Cloud Shell

O que é necessário

  • Familiaridade com Python
  • Conhecer os editores de texto padrão do Linux (vim, emacs ou nano, por exemplo)

Criação de projetos

Se você ainda não tem uma Conta do Google (Gmail ou Google Apps), crie uma. Faça login no Console do Google Cloud Platform (console.cloud.google.com) e crie um projeto:

Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.

Faturamento

Em seguida, ative o faturamento no console do Cloud para usar os recursos do Google Cloud.

A execução deste codelab não deve custar mais do que alguns dólares, mas pode ser mais se você decidir usar mais recursos ou deixá-los em execução.

Novos usuários do Google Cloud Platform têm direito a uma avaliação sem custo financeiro de US$300.

Embora o Google Cloud possa ser operado remotamente em seu laptop, neste codelab vamos usar o Google Cloud Shell, um ambiente de linha de comando executado no Cloud. Essa máquina virtual baseada em Debian tem todas as ferramentas de desenvolvimento necessárias (gcloud, python, virtualenv, pip e muito mais), oferece um diretório principal permanente de 5 GB e é executada no Google Cloud, melhorando muito o desempenho e a autenticação da rede. Isso significa que tudo que você precisa para este codelab é um navegador (sim, funciona em um Chromebook).

Para ativar o Google Cloud Shell, clique no botão no canto superior direito do console do desenvolvedor. Leva apenas alguns instantes para provisionar e se conectar ao ambiente:

Depois de se conectar ao Cloud Shell, você vai ver que sua conta já está autenticada e que o projeto está configurado com seu PROJECT_ID:

gcloud auth list
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
[core]
Project = <PROJECT_ID>

Se, por algum motivo, o projeto não estiver definido, basta emitir o seguinte comando:

gcloud config set project <PROJECT_ID>

Quer encontrar seu PROJECT_ID? Confira qual ID do projeto você usou nas etapas de configuração ou procure-o no painel do console:

No Cloud Shell, na linha de comando, execute o seguinte comando para clonar o repositório do GitHub:

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

Altere o diretório em python-docs-samples/codelabs/flex_and_vision:

cd python-docs-samples/codelabs/flex_and_vision

Antes de começar a usar as APIs Vision, Storage e Datastore, ative-as com os seguintes comandos:

gcloud services enable vision.googleapis.com
gcloud services enable storage-component.googleapis.com
gcloud services enable datastore.googleapis.com

Para fazer solicitações às APIs Vision, Storage e Datastore, você precisará ter credenciais da conta de serviço. As credenciais da conta de serviço do seu projeto podem ser geradas usando a ferramenta gcloud.

Defina uma variável de ambiente para PROJECT_ID, substituindo [YOUR_PROJECT_ID] pelo ID do seu projeto:

export PROJECT_ID=[YOUR_PROJECT_ID]

Crie uma conta de serviço para acessar as APIs do Google Cloud quando testar localmente:

gcloud iam service-accounts create codelab \
  --display-name "My Codelab Service Account"

Dê as permissões adequadas à nova conta de serviço:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:codelab@${PROJECT_ID}.iam.gserviceaccount.com \
--role roles/owner

Após criar a conta de serviço, crie uma chave de conta de serviço:

gcloud iam service-accounts keys create ~/key.json \
--iam-account codelab@${PROJECT_ID}.iam.gserviceaccount.com

Esse comando gera uma chave de conta de serviço armazenada em um arquivo JSON chamado key.json no seu diretório principal.

Usando o caminho absoluto da chave gerada, defina uma variável de ambiente para a chave de conta de serviço no Cloud Shell:

export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/key.json"

Leia mais sobre autenticação da API Vision.

Como iniciar seu ambiente virtual e instalar dependências

Crie um ambiente Python 3 isolado chamado env com o virtualenv:

virtualenv -p python3 env

Entre no novo virtualenv, chamado env:

source env/bin/activate

Use pip para instalar as dependências do seu projeto pelo arquivo requirements.txt:

pip install -r requirements.txt

O arquivo requirements.txt é uma lista de dependências de pacote necessárias para o projeto. O comando acima fez o download de todas essas dependências listadas para o virtualenv.

Como criar um aplicativo do App Engine

Em seguida, crie uma instância do App Engine usando:

gcloud app create

Como criar um bucket de armazenamento

Primeiro, defina a variável de ambiente CLOUD_STORAGE_BUCKET com o mesmo nome do seu PROJECT_ID. Para facilitar, recomendamos dar ao bucket o mesmo nome do PROJECT_ID.

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

Nosso aplicativo usa um bucket do Cloud Storage, que você precisa criar no Cloud Shell com uma ferramenta chamada gsutil. Execute o comando a seguir, que cria um bucket com o mesmo nome do seu PROJECT_ID.

gsutil mb gs://${PROJECT_ID}

Como executar o aplicativo

python main.py

Assim que o aplicativo for iniciado, clique no ícone de visualização da Web na barra de ferramentas do Cloud Shell e selecione "Visualizar na porta 8080".

Uma guia será aberta no navegador, conectando você ao servidor que acabou de iniciar. Você verá algo como:

Screen Shot 2017-02-23 at 7.22.50 PM.png

Tente fazer upload de uma foto que contenha um rosto humano. Clique no botão Escolher arquivo, selecione uma imagem no seu computador e clique em Enviar.

Quando o upload da foto for concluído, aparecerá algo assim:

Screen Shot 2017-02-23 at 7.32.08 PM.png

Layout do código de amostra

O exemplo tem o seguinte layout:

templates/
  homepage.html   /* HTML template that uses Jinja2 */
app.yaml          /* App Engine application configuration file */
main.py           /* Python Flask web application */
requirements.txt  /* List of dependencies for the project */

main.py

Esse arquivo Python é um aplicativo Flask da Web. O aplicativo permite que usuários enviem fotos (preferencialmente de rostos), que são armazenadas no Cloud Storage e analisadas com o recurso de detecção facial da API Cloud Vision. Informações importantes sobre cada uma das fotos são armazenadas no Datastore, o banco de dados NoSQL do Google Cloud Platform. Essas informações são acessadas nesse local toda vez que um usuário acessa o site.

Esse aplicativo usa as bibliotecas de cliente do Google Cloud Platform para o Storage, o Datastore e o Vision. Essas bibliotecas de cliente tornam fácil o acesso às APIs do Cloud com o uso das suas linguagens preferidas de programação.

Agora analisaremos alguns snippets importantes do código.

A seção de importações, na parte de cima, é onde importamos os diversos pacotes de que precisamos para nosso código. É assim que importamos as bibliotecas de cliente do Google Cloud para o Datastore, o Storage e o Vision:

from google.cloud import datastore
from google.cloud import storage
from google.cloud import vision

Este é o código para o que acontece quando um usuário acessa o URL raiz do site. Criamos um objeto cliente do Datastore, que é usado para acessar a biblioteca de cliente do Datastore. Em seguida, executamos uma consulta no Datastore para entidades do tipo Faces. Por fim, renderizamos o modelo HTML, transmitindo image_entities que extraímos do Datastore como uma variável.

@app.route('/')
def homepage():
    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Use the Cloud Datastore client to fetch information from Datastore about
    # each photo.
    query = datastore_client.query(kind='Faces')
    image_entities = list(query.fetch())

    # Return a Jinja2 HTML template and pass in image_entities as a parameter.
    return render_template('homepage.html', image_entities=image_entities)

Agora veremos como as entidades são salvas no Datastore. O Datastore é solução de banco de dados NoSQL do Google Cloud. Os dados são armazenados em objetos denominados entidades. A cada entidade é atribuída uma chave de identificação exclusiva, que pode ser criada usando um tipo e uma string de nome da chave. Um tipo é um bucket organizacional para determinar o tipo da entidade. Por exemplo, podemos configurar tipos para Fotos, Pessoas e Animais.

Cada entidade pode ter diversas propriedades definidas pelo desenvolvedor. Elas podem ter valores de diversos tipos, incluindo: números inteiros, flutuantes, strings, data ou dados binários.

    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Fetch the current date / time.
    current_datetime = datetime.now()

    # The kind for the new entity.
    kind = 'Faces'

    # The name/ID for the new entity.
    name = blob.name

    # Create the Cloud Datastore key for the new entity.
    key = datastore_client.key(kind, name)

    # Construct the new entity using the key. Set dictionary values for entity
    # keys blob_name, storage_public_url, timestamp, and joy.
    entity = datastore.Entity(key)
    entity['blob_name'] = blob.name
    entity['image_public_url'] = blob.public_url
    entity['timestamp'] = current_datetime
    entity['joy'] = face_joy

    # Save the new entity to Datastore.
    datastore_client.put(entity)

Assim como o Datastore, as bibliotecas de cliente do Vision e do Storage podem ser acessadas de modo programático. Você pode abrir o arquivo main.py usando o vim, o emacs ou o nano para explorar todo o código de exemplo.

Saiba mais sobre o Flask em http://flask.pocoo.org/.

Saiba mais sobre bibliotecas de clientes em https://googlecloudplatform.github.io/google-cloud-python/.

homepage.html

O framework da Web para o Flask aproveita o Jinja2 como mecanismo do modelo. Isso nos permite transmitir variáveis e expressões de main.py em homepage.html que são substituídas por valores quando a página é renderizada.

Saiba mais sobre Jinja2 em http://jinja.pocoo.org/docs/2.9/templates/.

Esse modelo Jinja2 HTML exibe um formulário para os usuários enviarem fotos ao banco de dados. O modelo também exibe cada uma das imagens enviadas anteriormente com o nome do arquivo e a data e a hora do upload. Além disso, ele mostra a probabilidade de a pessoa que teve o rosto detectado pela API Vision estar feliz.

homepage.html

<h1>Google Cloud Platform - Face Detection Sample</h1>

<p>This Python Flask application demonstrates App Engine Flexible, Google Cloud
Storage, Datastore, and the Cloud Vision API.</p>

<br>

<html>
  <body>
    <form action="upload_photo" method="POST" enctype="multipart/form-data">
      Upload File: <input type="file" name="file"><br>
      <input type="submit" name="submit" value="Submit">
    </form>
    
  </body>
</html>

O ambiente flexível do App Engine usa um arquivo denominado app.yaml para descrever a configuração de implantação do aplicativo. Se o arquivo estiver faltando, o App Engine tentará deduzir essa configuração. No entanto, convém incluir esse arquivo.

Em seguida, você vai modificar o app.yaml usando um editor de sua preferência: vim, nano ou emacs. Vamos usar o editor nano:

nano app.yaml

app.yaml

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
    python_version: 3

env_variables:
    CLOUD_STORAGE_BUCKET: <your-cloud-storage-bucket>

Esta é a configuração básica necessária para implantar um aplicativo do ambiente flexível do App Engine para Python 3. Saiba mais sobre como configurar o App Engine aqui.

Com o app.yaml aberto, substitua < your-cloud-storage-bucket > pelo nome do bucket do Cloud Storage. Se você esqueceu o nome do bucket do Cloud Storage, copie o ID do projeto do GCP do Qwiklabs, que é o mesmo. A seção env_variables define variáveis de ambiente que serão usadas no main.py quando o aplicativo estiver implantado.

Agora salve e feche o arquivo no nano usando o Ctrl + x, que exibirá o prompt:

Screen Shot 2017-02-17 at 4.47.12 PM.png

Digite a letra y e depois pressione mais uma vez a tecla ENTER para confirmar o nome do arquivo no seguinte prompt:

Screen Shot 2017-02-24 at 4.18.23 PM.png

Implante o app no App Engine usando o gcloud:

gcloud app deploy

Depois que o aplicativo for implantado, abra o URL https://< PROJECT_ID >.appspot.com no navegador da Web para acessá-lo.

Resumo

Nesta etapa, você configurou um aplicativo da Web em Python e o implantou no ambiente flexível do App Engine.

Você aprendeu a escrever e implantar seu primeiro aplicativo da Web flexível do App Engine.

Limpeza

Para evitar a cobrança na sua conta do Google Cloud Platform pelo uso de recursos neste guia de início rápido, siga estas etapas:

  • Acesse o Console do Cloud Platform.
  • Selecione o projeto que você quer encerrar e clique em "Excluir" na parte de cima. Isso programa a exclusão do projeto.

Saiba mais

Licença

Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.