Esta série de codelabs (tutoriais práticos e autoguiados) destina-se a ajudar os desenvolvedores do Google App Engine (Padrão) a modernizar os aplicativos por meio de uma série de migrações. A etapa mais significativa é deixar de usar os serviços originais de pacote em tempo de execução porque os ambientes de execução de última geração são mais flexíveis, oferecendo aos usuários uma variedade maior de opções de serviços. A migração para o ambiente de execução de geração mais recente permite uma integração com os produtos do Google Cloud mais facilmente, usa uma variedade maior de serviços compatíveis e oferece suporte às versões de linguagem atuais.
Esse codelab ajuda os usuários a migrar de tarefas push do App Engine e de sua API/biblioteca taskqueue
para o Cloud Tasks. Se seu aplicativo não usa filas de tarefas, você pode usar este codelab como um exercício para saber como migrar tarefas push do App Engine para o Cloud Tasks.
Você aprenderá como realizar as seguintes tarefas:
- Migrar do App Engine
taskqueue
para o Cloud Tasks - Criar tarefas push com o Cloud Tasks
- Migrar do App Engine
ndb
para o Cloud NDB (mesmo que o Módulo 2)
Pré-requisitos
- Um projeto do Google Cloud Platform com:
- Habilidades básicas em Python
- Conhecimento prático de comandos comuns do Linux
- Conhecimento básico sobre como desenvolver e implantar aplicativos do App Engine
- É recomendável concluir o codelab do Módulo 7 antes de começar este (Módulo 8).
- Um aplicativo do Module 7 funcional
Pesquisa
Como você usará este codelab?
Como adicionamos tarefas push do App Engine ao aplicativo de amostra no codelab anterior (Módulo 7), agora podemos migrá-lo para o Cloud Tasks. Estes são os principais passos para a migração deste tutorial:
- Configuração/Pré-trabalho
- Atualizar os arquivos de configuração
- Atualizar aplicativo principal
Antes de prosseguirmos com a parte principal do tutorial, vamos configurar o nosso projeto, obter o código e, em seguida, implantar o aplicativo de referência para saber que começamos a trabalhar com o código em funcionamento.
1. Configurar projeto
Recomendamos que você reutilize o mesmo projeto usado para concluir o Módulo 7. Se preferir, crie um novo projeto ou reutilize outro. Verifique se o projeto tem uma conta de faturamento ativa e o App Engine (aplicativo) está ativado.
2. Receber app de amostra do valor de referência
Um dos pré-requisitos para este codelab é ter um aplicativo de amostra do Módulo 7. Se você não tiver um, recomendamos concluir o tutorial do Módulo 7 (link acima) antes de prosseguir. Caso contrário, se você já estiver familiarizado com o conteúdo, comece pegando o código do Módulo 7 abaixo.
Não importa se você usa o seu ou o nosso, o código do Módulo 7 será onde vamos. Este codelab do Módulo 2 orienta você em cada etapa e, quando concluído, deve ser semelhante ao código no ponto FINISH (incluindo uma porta opcional do Python 2 para 3).
- INICIAR: repositório do módulo 7
- CONCLUIR: repositório do módulo 8
- Repositório completo (clique ou faça o download do ZIP)
O diretório dos arquivos do Módulo 7 (seu ou de nosso) deve ter a seguinte aparência:
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
Se você concluiu o tutorial do Módulo 7, você também terá uma pasta lib
com o Flask e as dependências correspondentes.
3. (Re)Implantar aplicativo do módulo 7
As etapas de pré-trabalho restantes para serem executadas agora:
- Familiarize-se com a ferramenta de linha de comando do
gcloud
(se necessário). - (Re)implantar o código do Módulo 7 no App Engine (se necessário)
Depois que você concluir essas etapas e confirmar que está em operação, seguiremos neste tutorial, começando com os arquivos de configuração.
requirements.txt
O requirements.txt
do Módulo 7 lista somente o Flask como um pacote obrigatório. O Cloud NDB e o Cloud Tasks têm as próprias bibliotecas de cliente. Portanto, nesta etapa, adicione esses pacotes a requirements.txt
para que ele fique assim:
Flask==1.1.2
google-cloud-ndb==1.7.1
google-cloud-tasks==1.5.0
Recomendamos o uso das versões mais recentes de cada biblioteca. Os números de versão acima são as mais recentes para o Python 2 no momento da redação deste tutorial. Os pacotes equivalentes do Python 3 estarão em versões mais recentes. O código na pasta do repositório FINISH é atualizado com mais frequência e pode ter versões mais recentes, embora isso seja menos provável para as bibliotecas do Python 2 que geralmente são congeladas.
app.yaml
Consulte as bibliotecas integradas grpcio
e setuptools
em app.yaml
em uma seção libraries
:
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
appengine_config.py
Atualize appengine_config.py
para usar pkg_resources
para vincular essas bibliotecas integradas às bibliotecas de terceiros copiadas, como Flask e bibliotecas de cliente do Google Cloud:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Há apenas um arquivo de aplicativo, main.py
, então todas as alterações nesta seção afetam apenas esse arquivo.
Atualizar importações e inicialização
No momento, nosso app usa as bibliotecas google.appengine.api.taskqueue
e google.appengine.ext.ndb
integradas:
- Antes:
from datetime import datetime
import logging
import time
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
Substitua ambos por google.cloud.ndb
e google.cloud.tasks
. Além disso, o Cloud Tasks requer a codificação JSON do payload da tarefa, portanto, também importe json
. Quando terminar, veja a aparência da seção import
de main.py
:
- Depois:
from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
from google.cloud import ndb, tasks
Migrar para o Cloud Tasks (e o Cloud NDB)
- Antes:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
Não há alterações no store_visit()
além do que você fez no Módulo 2: adicione um gerenciador de contexto a todo o acesso ao Datastore. Isso ocorre na forma de criar uma nova entidade Visit
encapsulada em uma instrução with
.
- Depois:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
No momento, o Cloud Tasks exige a ativação do App Engine no projeto do Google Cloud para que você possa usá-lo (mesmo se não tiver o código do App Engine). Caso contrário, as filas de tarefas não funcionarão. Consulte esta seção nos documentos para mais informações. O Cloud Tasks é compatível com tarefas em execução no App Engine (destinos do App Engine), mas também pode ser executado em qualquer endpoint HTTP (destinos HTTP) com um endereço IP público, como Cloud Functions, Cloud Run, GKE, Compute Engine ou até mesmo um servidor da Web local. Nosso aplicativo simples usa um alvo do App Engine para tarefas.
Algumas configurações são necessárias para usar o Cloud NDB e o Cloud Tasks. Na parte superior de main.py
, na inicialização do Flask, inicialize o Cloud NDB e o Cloud Tasks. Defina também algumas constantes que indicam onde suas tarefas push serão executadas.
app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()
PROJECT_ID = 'PROJECT_ID' # replace w/your own
REGION = 'REGION' # replace w/your own
QUEUE_NAME = 'default' # replace w/your own if desired
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION, QUEUE_NAME)
Depois de criar a fila de tarefas, preencha o PROJECT_ID
do projeto, o REGION
em que as tarefas serão executadas (precisam ser as mesmas da região do App Engine) e nome da sua fila push. O App Engine apresenta uma fila "default
", então usaremos esse nome (mas não é obrigatório).
A fila default
é especial e criada automaticamente em determinadas circunstâncias. Uma delas é ao usar APIs do App Engine, portanto, se você (re)usar o mesmo projeto que o Módulo 7, default
já existe. No entanto, se você criou um novo projeto especificamente para o Módulo 8, será necessário criar default
manualmente. Mais informações sobre a fila do default
podem ser encontradas na documentação do queue.yaml
.
A finalidade do ts_client.queue_path()
é criar o "nome de caminho totalmente qualificado" de uma fila de tarefas (QUEUE_PATH
) necessário para criar uma tarefa. Também é necessária uma estrutura JSON especificando os parâmetros da tarefa:
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
O que você está observando acima?
- Forneça as informações do destino da tarefa:
- Para destinos do App Engine, especifique
app_engine_http_request
como o tipo de solicitação erelative_uri
é o gerenciador de tarefas do App Engine. - Para destinos HTTP, use
http_request
eurl
.
- Para destinos do App Engine, especifique
body
: os parâmetros de codificação JSON e Unicode codificados em string para enviar à tarefa (push)- Especificar explicitamente o cabeçalho
Content-Type
codificado em JSON
Consulte a documentação para ver mais informações sobre suas opções aqui.
Com a configuração, vamos atualizar o app fetch_visits()
. Esta é a aparência do tutorial anterior:
- Antes:
def fetch_visits(limit):
'get most recent visits and add task to delete older visits'
data = Visit.query().order(-Visit.timestamp).fetch(limit)
oldest = time.mktime(data[-1].timestamp.timetuple())
oldest_str = time.ctime(oldest)
logging.info('Delete entities older than %s' % oldest_str)
taskqueue.add(url='/trim', params={'oldest': oldest})
return (v.to_dict() for v in data), oldest_str
As atualizações necessárias:
- Mudar do App Engine
ndb
para o Cloud NDB - Novo código para extrair o carimbo de data/hora da visita mais antiga exibida
- Use o Cloud Tasks para criar uma nova tarefa em vez do
taskqueue
do App Engine
Esta é a nova aparência do seu fetch_visits()
:
- Depois:
def fetch_visits(limit):
'get most recent visits and add task to delete older visits'
with ds_client.context():
data = Visit.query().order(-Visit.timestamp).fetch(limit)
oldest = time.mktime(data[-1].timestamp.timetuple())
oldest_str = time.ctime(oldest)
logging.info('Delete entities older than %s' % oldest_str)
task = {
'app_engine_http_request': {
'relative_uri': '/trim',
'body': json.dumps({'oldest': oldest}).encode(),
'headers': {
'Content-Type': 'application/json',
},
}
}
ts_client.create_task(parent=QUEUE_PATH, task=task)
return (v.to_dict() for v in data), oldest_str
Resumindo a atualização do código:
- Mudar para o Cloud NDB significa mover o código do Datastore em uma instrução
with
- Alternar para o Cloud Tasks significa usar
ts_client.create_task()
em vez detaskqueue.add()
- Transmita o caminho completo da fila e o payload
task
(descrito anteriormente)
Atualizar o gerenciador de tarefas (push)
Há poucas alterações que precisam ser feitas na função de gerenciador de tarefas (push).
- Antes:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = request.form.get('oldest', type=float)
keys = Visit.query(
Visit.timestamp < datetime.fromtimestamp(oldest)
).fetch(keys_only=True)
nkeys = len(keys)
if nkeys:
logging.info('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id()) for k in keys)))
ndb.delete_multi(keys)
else:
logging.info('No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
A única coisa que precisa ser feita é colocar todo o acesso ao Datastore na instrução with
do gerenciador de contexto, tanto a consulta quanto pela solicitação de exclusão. Com isso em mente, atualize seu gerenciador trim()
desta maneira:
- Depois:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = float(request.get_json().get('oldest'))
with ds_client.context():
keys = Visit.query(
Visit.timestamp < datetime.fromtimestamp(oldest)
).fetch(keys_only=True)
nkeys = len(keys)
if nkeys:
logging.info('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id()) for k in keys)))
ndb.delete_multi(keys)
else:
logging.info('No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
Não há mudanças em templates/index.html
neste ou no próximo codelab.
Implante o aplicativo
Verifique todas as alterações que o código compila e implanta novamente. Confirme se o aplicativo (ainda) funciona. Você deve esperar uma saída idêntica ao do Módulo 7. Como você acabou de reconectar as configurações, o processo continua funcionando como esperado.
Se você passou para este tutorial sem fazer o codelab do Módulo 7, o aplicativo em si não muda. Ele registra todas as visitas à página principal da web (/
) e tem esta aparência quando você visita o site vezes, e informa que excluiu todas as visitas anteriores ao décimo:
Isso conclui este codelab. Agora, seu código deve corresponder ao conteúdo no Repositório do módulo 8. Parabéns pela conclusão das migrações mais importantes das tarefas push! O módulo 9 (link do codelab abaixo) é opcional, ajudando os usuários a migrar para o Python 3 e o Cloud Datastore.
Opcional: limpar
E a limpeza para evitar cobrança até que você esteja pronto para passar para o próximo codelab de migração? Como você, os desenvolvedores já estão atualizados nas informações de preços do App Engine.
Opcional: desativar app
Se você ainda não estiver pronto para avançar para o próximo tutorial, desative seu app para evitar cobranças. Quando estiver pronto para passar para o próximo codelab, você poderá reativá-lo. Enquanto seu aplicativo estiver desativado, ele não receberá tráfego para custos. No entanto, o uso do Datastore pode ser cobrado se exceder a cota gratuita, Exclua o suficiente para ficar abaixo desse limite.
Por outro lado, se você não quiser continuar com as migrações e quiser excluir tudo completamente, poderá encerrar seu projeto.
Próximas etapas
Além deste tutorial, a próxima etapa é o Módulo 9 e seu codelab, além da portabilidade para o Python 3. É um pouco opcional porque nem todos estão prontos para a etapa. Há também uma porta opcional do Cloud NDB para o Cloud Datastore. Ela é definitivamente e somente para quem quer sair do NDB e consolidar o código que usa o Cloud Datastore. Essa migração é idêntica ao Codelab da migração do Módulo 3.
- Módulo 9 Migre do Python 2 para 3 e do Cloud NDB para o Cloud Datastore
- Portabilidade de módulo de migração opcional para o Python 3
- Também inclui migração opcional do Cloud NDB para o Cloud Datastore (igual ao Módulo 3) e
- uma pequena migração do Cloud Tasks v1 para a v2, uma vez que a biblioteca de cliente está congelada para o Python 2.
- Módulo 4: migre para o Cloud Run com o Docker
- Contentorize seu app para ser executado no Cloud Run com o Docker
- Essa migração permite que você permaneça no Python 2.
- Módulo 5: Migrar para o Cloud Run com o Cloud Buildpacks
- Contentorize seu app para ser executado no Cloud Run com o Cloud Buildpacks
- Não é preciso saber nada sobre o Docker, os contêineres ou as
Dockerfile
s. - Requer que seu app já tenha sido migrado para o Python 3 (o Buildpack não é compatível com o Python 2)
- Módulo 6: Migrar para o Cloud Firestore
- Migrar para o Cloud Firestore para acessar recursos do Firebase
- O Cloud Firestore é compatível com o Python 2, mas este codelab está disponível apenas no Python 3.
Problemas/comentários do módulo de migração do App Engine
Se você encontrar problemas com este codelab, pesquise seu problema antes de preenchê-lo. Links para pesquisar e criar novos problemas:
Recursos de migração
Os links para as pastas do repositório do módulo 7 (START) e Módulo 8 (FINISH) podem ser encontrados na tabela abaixo. Elas também podem ser acessadas no repositório de todas as migrações de codelab do App Engine, que você pode clonar ou fazer o download de um arquivo ZIP.
Codelab | Python 2 | Python 3 |
(n/a) | ||
Módulo 8 | (n/a) |
Recursos do App Engine
Veja abaixo mais recursos relacionados a essa migração específica:
- Referências do App Engine
ndb
e do Cloud NDB - Referências do App Engine
taskqueue
e do Cloud Tasks - Como migrar para o ambiente de execução de última geração do Python 3 e do GAE
- Geral