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

Resumo

Neste codelab, você 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 Google Cloud Vision, Storage e 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 são escalonados automaticamente com base no 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 são compatíveis de forma nativa e altamente personalizáveis.

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 App Engine Flexible executa seu aplicativo em contêineres do Docker em execução nas máquinas virtuais do Google Compute Engine. O ambiente padrão do App Engine é uma opção alternativa em determinadas linguagens, como o Python. O App Engine Standard executa o aplicativo em um ambiente sandbox mais restritivo. Para mais informações, leia Como escolher um ambiente do App Engine.

O que você 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 do 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 do projeto

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 novo 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ê. Ele será indicado posteriormente neste codelab como PROJECT_ID.

Faturamento

Em seguida, você precisará ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.

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

Novos usuários do Google Cloud Platform estão qualificados para um teste sem custo financeiro de US$ 300.

Embora o Google Cloud possa ser operado remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud. O Cloud Shell é uma máquina virtual com base em Debian que contém todas as ferramentas de desenvolvimento necessárias (gcloud, python, Podfile, pip etc.), além de oferecer um diretório principal permanente de 5 GB e ser executado 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, no console do desenvolvedor, clique no botão no canto superior direito (só leva alguns instantes para provisionar e se conectar ao ambiente):

Depois que você se conectar ao Cloud Shell, sua autenticação já terá sido feita, e o projeto estará definido 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>

Está procurando seu PROJECT_ID? Confira o ID do projeto que você usou nas etapas de configuração ou procure 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, você precisa ativar as APIs 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á das 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 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 à sua 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 da conta de serviço no Cloud Shell:

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

Leia mais sobre como autenticar a API Vision.

Como iniciar o ambiente virtual e instalar dependências

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

virtualenv -p python3 env

Digite o Podfile recém-criado, 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 do 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 igual ao 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ê precisará criar no Cloud Shell com uma ferramenta chamada gsutil. Execute o comando abaixo, que cria um bucket com o mesmo nome do PROJECT_ID.

gsutil mb gs://${PROJECT_ID}

Como executar o aplicativo

python main.py

Depois que o aplicativo for iniciado, clique no ícone 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 parecido com:

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

Faça upload de uma foto com um rosto humano. Clique no botão Escolher arquivo, escolha uma imagem no seu computador e clique em Enviar.

Quando o upload da foto for concluído, você verá algo assim:

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

Exemplo de layout de código

A amostra 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 por entidades do tipo Faces. Por fim, renderizamos nosso modelo HTML, transmitindo as image_entity 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)

As bibliotecas de cliente do Vision e do Storage podem ser acessadas pelo código de programação de uma forma parecida com o que ocorre com as bibliotecas de cliente do Datastore. 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/.

página inicial.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ê modificará o app.yaml usando o editor que preferir (vim, nano ou emacs). Usaremos 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 a configuração do App Engine neste link.

Quando o app.yaml estiver 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 no 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:

Captura de tela 2017-02-17 às 4.47.12 PM.png

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

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

Implante o aplicativo no App Engine usando o gcloud:

gcloud app deploy

Depois de implantar o aplicativo, acesse-o abrindo o URL https://< PROJECT_ID >.appspot.com no navegador da Web.

Resumo

Nesta etapa, você configura um aplicativo da Web em Python e o implanta 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 início rápido, siga a etapa abaixo:

  • Acesse o Console do Cloud Platform.
  • Selecione o projeto que você quer encerrar e clique em "Excluir" na parte superior: isso programa o projeto para exclusão.

Saiba mais

Licença

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