1. Visão geral
A série de codelabs da estação de migração sem servidor (tutoriais práticos e individualizados) e os vídeos relacionados têm como objetivo ajudar desenvolvedores sem servidor do Google Cloud a modernizar apps, orientando-os em uma ou mais migrações, principalmente para evitar serviços legados. Isso torna seus apps mais portáteis e oferece mais opções e flexibilidade, o que permite a integração e o acesso a uma variedade maior de produtos do Cloud e o upgrade para versões de idiomas mais recentes com mais facilidade. Embora inicialmente voltada para os primeiros usuários do Cloud, principalmente desenvolvedores do App Engine (ambiente padrão), esta série é ampla o suficiente para incluir outras plataformas sem servidor, como o Cloud Functions e o Cloud Run, ou outros lugares, se aplicável.
Este codelab ensina como migrar do App Engine Blobstore para o Cloud Storage. Há também migrações implícitas de:
- Framework da Web
webapp2
para Flask (abordado pelo Módulo 1) - Nadado do App Engine para Cloud NBS para acesso ao Datastore (abordado pelo Módulo 2)
- Python 2 a 3 (o aplicativo migrado é compatível com Python 2 e 3)
Consulte os módulos de migração relacionados para mais informações detalhadas.
Você vai aprender a
- Adicionar uso da biblioteca/API Blobstore do App Engine
- Armazenar uploads de usuários para o serviço Blobstore
- Prepare-se para a próxima etapa da migração para o Cloud Storage
O que é necessário
- Um projeto do Google Cloud Platform com uma conta de faturamento ativa do GCP.
- Habilidades básicas em Python
- Conhecimento prático de comandos comuns do Linux
- Conhecimento básico sobre desenvolvimento e implantação de apps no App Engine
- Um app do App Engine do Módulo 15: conclua o codelab do módulo 15 (recomendado) ou copie o app do módulo 15 do repositório.
Pesquisa
Como você vai usar este tutorial?
Como você classificaria sua experiência com Python?
Como você classificaria sua experiência de uso dos serviços do Google Cloud?
2. Contexto
Este codelab começa com o app de exemplo do Módulo 15 e demonstra como migrar do Blobstore (e do NBS) para o Cloud Storage (e o Cloud NBS). O processo de migração envolve a substituição de dependências nos pacotes de serviços legados do App Engine, o que permite mover os aplicativos para outra plataforma sem servidor do Cloud ou outra plataforma de hospedagem, se você quiser.
Essa migração requer um pouco mais de esforço em comparação com as outras migrações desta série. O Blobstore tem dependências na estrutura de webapp original. É por isso que o app de exemplo usa a biblioteca webapp2 em vez do Flask. Neste tutorial, apresentamos migrações para o Cloud Storage, o Cloud Node, o Flask e o Python 3.
O app ainda registra "visitas" do usuário final. e exibe os dez mais recentes, mas o codelab anterior (módulo 15) adicionou novas funcionalidades para acomodar o uso do Blobstore: o app solicita que os usuários finais façam upload de um artefato (um arquivo) correspondente à "visita". Os usuários podem fazer isso ou selecionar "pular" para desativar. Independentemente da decisão do usuário, a próxima página mostra o mesmo resultado de versões anteriores desse aplicativo, exibindo as visitas mais recentes. Outra reviravolta é que as visitas com artefatos correspondentes apresentam uma "visualização" para exibir o artefato de uma visita. Este codelab implementa as migrações mencionadas anteriormente, preservando a funcionalidade descrita.
3. Configuração/Pré-trabalho
Antes de chegarmos à parte principal do tutorial, vamos configurar nosso projeto, obter o código e, em seguida, implantar o aplicativo de referência para sabermos que começamos com o código de trabalho.
1. Configurar projeto
Se você já implantou o app do Módulo 15, recomendamos reutilizar o mesmo projeto (e código). Outra opção é criar um novo projeto ou reutilizar um projeto existente. Verifique se o projeto tem uma conta de faturamento ativa e se o App Engine está ativado.
2. Receber app de amostra do valor de referência
Um dos pré-requisitos deste codelab é ter um app de exemplo do Módulo 15 em funcionamento. Caso ainda não o tenha, consulte o módulo 15 "INICIAR" da pasta (link abaixo). Este codelab orienta você em cada etapa e termina com um código semelhante ao do Módulo 16, "FINISH". do Compute Engine.
- INÍCIO: pasta do módulo 15 (Python 2)
- FINISH: pasta do módulo 16 (Python 2)
- Repositório inteiro (para clonar ou fazer o download do arquivo ZIP)
O diretório dos arquivos de inicialização do Módulo 15 deve ser semelhante a este:
$ ls README.md app.yaml main-gcs.py main.py templates
O arquivo main-gcs.py
é uma versão alternativa de main.py
do Módulo 15 que permite a seleção de um bucket do Cloud Storage diferente do padrão do URL atribuído a um app com base no ID do projeto: PROJECT_ID
.appspot.com
. O arquivo não faz parte do codelab (módulo 16). Além disso, técnicas de migração semelhantes podem ser aplicadas a esse arquivo se você quiser.
3. (Re) Implantar aplicativo de referência
As etapas de pré-trabalho restantes para serem executadas agora:
- Conheça melhor a ferramenta de linha de comando
gcloud
- Reimplantar o aplicativo de amostra com
gcloud app deploy
- Confirmar se o aplicativo é executado no App Engine sem problemas
Depois de executar essas etapas e confirmar que o app Módulo 15 funciona. A página inicial cumprimenta os usuários com um formulário solicitando o upload de um arquivo de artefato de visita junto com uma opção, "pular" para desativar:
Quando os usuários fazem upload de um arquivo ou pulam, o aplicativo renderiza as "visitas mais recentes" conhecidas página:
As visitas que apresentem um artefato terão uma "visualização" à direita do carimbo de data/hora da visita para exibir ou fazer o download do artefato. Depois de confirmar a funcionalidade do app, você poderá migrar dos serviços legados do App Engine (webapp2, NBS, Blobstore) para alternativas contemporâneas (Flask, Cloud NBS, Cloud Storage).
4. Atualizar os arquivos de configuração
Três arquivos de configuração são usados na versão atualizada do nosso app. As tarefas necessárias são:
- Atualizar as bibliotecas integradas de terceiros necessárias no
app.yaml
e deixar as portas abertas para uma migração do Python 3 - Adicione um
requirements.txt
, que especifica todas as bibliotecas necessárias que não estão integradas. - Adicione
appengine_config.py
para que o app ofereça suporte a bibliotecas de terceiros integradas e não integradas.
app.yaml
Edite o arquivo app.yaml
atualizando a seção libraries
. Remova jinja2
e adicione grpcio
, setuptools
e ssl
. Escolha a versão mais recente disponível para as três bibliotecas. Adicione também a diretiva runtime
do Python 3, mas com comentário. Quando terminar, o código deve ficar assim (se você tiver selecionado o Python 3.9):
ANTES:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
DEPOIS:
#runtime: python39
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
- name: ssl
version: latest
As mudanças estão relacionadas principalmente às bibliotecas integradas ao Python 2 disponíveis nos servidores do App Engine para que você não precise agrupá-las por conta própria. Removemos o Jinja2 porque ele vem com o Flask, que vamos adicionar ao arquivo reqs.txt. Sempre que são usadas bibliotecas de cliente do Google Cloud, como as do Cloud NFS e do Cloud Storage, grpcio e setuptools são necessários. Por fim, o próprio Cloud Storage requer a biblioteca ssl. A diretiva de tempo de execução comentada na parte de cima é para quando você estiver pronto para transferir esse aplicativo para o Python 3. Vamos abordar esse tópico no final deste tutorial.
requirements.txt
Adicione um arquivo requirements.txt
, exigindo o framework Flask e as bibliotecas de cliente do Cloud gtag e do Cloud Storage, que não estão integradas. Crie o arquivo com este conteúdo:
flask
google-cloud-ndb
google-cloud-storage
O ambiente de execução do App Engine para Python 2 exige o autoagrupamento de bibliotecas de terceiros não integradas. Portanto, execute o seguinte comando para instalar essas bibliotecas na pasta lib:
pip install -t lib -r requirements.txt
Se você tiver o Python 2 e o 3 na sua máquina de desenvolvimento, pode ser necessário usar o comando pip2 para garantir o recebimento das versões em Python 2 dessas bibliotecas. Depois de fazer upgrade para o Python 3, não é mais necessário se agrupar.
appengine_config.py
Adicione um arquivo appengine_config.py
compatível com bibliotecas de terceiros integradas e não integradas. Crie o arquivo com este conteúdo:
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)
As etapas recém-concluídas devem ser semelhantes ou idênticas às listadas na seção Como instalar bibliotecas para aplicativos Python 2 dos documentos do App Engine e, mais especificamente, o conteúdo de appengine_config.py
precisa corresponder ao que está na Etapa 5.
O trabalho nos arquivos de configuração foi concluído, então vamos passar para o aplicativo.
5. Modificar arquivos do aplicativo
Importações
O primeiro conjunto de mudanças para main.py
inclui a troca de todos os itens que estão sendo substituídos. Veja o que vai mudar:
- O
webapp2
foi substituído pelo Flask - Em vez de usar o Jinja2 do
webapp2_extras
, use o Jinja2 do Flask - O Blobstore e o NBS do App Engine foram substituídos pelo Cloud NBS e pelo Cloud Storage
- Os gerenciadores do Blobstore em
webapp
foram substituídos por uma combinação dos utilitários do módulo de biblioteca padrãoio
, do Flask e dowerkzeug
. - Por padrão, o Blobstore grava em um bucket do Cloud Storage com o nome do URL do app (
PROJECT_ID.appspot.com
). Como estamos fazendo a portabilidade para a biblioteca de cliente do Cloud Storage,google.auth
é usado para conseguir o ID do projeto e especificar exatamente o mesmo nome de bucket. É possível mudar o nome do bucket, já que ele não está mais fixado no código.
ANTES:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Implemente as mudanças na lista acima substituindo a seção de importação atual em main.py
pelo snippet de código abaixo.
DEPOIS:
import io
from flask import (Flask, abort, redirect, render_template,
request, send_file, url_for)
from werkzeug.utils import secure_filename
import google.auth
from google.cloud import exceptions, ndb, storage
Inicialização e suporte desnecessário a Jinja2
O próximo bloco de código a ser substituído é o BaseHandler
, que especifica o uso de Jinja2 de webapp2_extras
. Isso não é necessário porque o Jinja2 vem com o Flask e é o mecanismo de modelos padrão dele. Portanto, remova-o.
No lado do módulo 16, instancie objetos que não tínhamos no app mais antigo. Isso inclui a inicialização do aplicativo Flask e a criação de clientes de API para o Cloud NBS e o Cloud Storage. Por fim, montamos o nome do bucket do Cloud Storage conforme descrito acima na seção de importações. Confira o que acontece antes e depois da implementação dessas atualizações:
ANTES:
class BaseHandler(webapp2.RequestHandler):
'Derived request handler mixing-in Jinja2 support'
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_response(self, _template, **context):
self.response.write(self.jinja2.render_template(_template, **context))
DEPOIS:
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
Atualizar o acesso ao Datastore
O Cloud NBS é compatível principalmente com o App Engine RDP. Uma diferença já abordada é a necessidade de um cliente de API. Outro é que a segunda exige que o acesso ao Datastore seja controlado pelo gerenciador de contexto Python do cliente da API. Basicamente, isso significa que todas as chamadas de acesso ao Datastore que usam a biblioteca de cliente do Cloud NBS só podem ocorrer em blocos with
do Python.
É uma mudança; o outro é que o Blobstore e seus objetos, por exemplo, BlobKey
s, não são compatíveis com o Cloud Storage. Portanto, mude o file_blob
para um ndb.StringProperty
. Confira abaixo a classe de modelo de dados e as funções store_visit()
e fetch_visits()
atualizadas que refletem essas mudanças:
ANTES:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.BlobKeyProperty()
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
DEPOIS:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.StringProperty()
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Veja uma representação pictórica das mudanças feitas até agora:
Como atualizar os gerenciadores
Gerenciador de uploads
Os gerenciadores em webapp2
são classes enquanto funcionam no Flask. Em vez de um método verbo HTTP, o Flask usa o verbo para decorar a função. O Blobstore e os gerenciadores webapp
dele foram substituídos pela funcionalidade do Cloud Storage, bem como pelo Flask e seus utilitários:
ANTES:
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
'Upload blob (POST) handler'
def post(self):
uploads = self.get_uploads()
blob_id = uploads[0].key() if uploads else None
store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
self.redirect('/', code=307)
DEPOIS:
@app.route('/upload', methods=['POST'])
def upload():
'Upload blob (POST) handler'
fname = None
upload = request.files.get('file', None)
if upload:
fname = secure_filename(upload.filename)
blob = gcs_client.bucket(BUCKET).blob(fname)
blob.upload_from_file(upload, content_type=upload.content_type)
store_visit(request.remote_addr, request.user_agent, fname)
return redirect(url_for('root'), code=307)
Algumas observações sobre essa atualização:
- Em vez de um
blob_id
, os artefatos de arquivo agora são identificados pelo nome de arquivo (fname
), se presente, eNone
(caso contrário, o usuário desativou o upload de um arquivo). - Os gerenciadores do Blobstore abstraem o processo de upload dos usuários, mas o Cloud Storage não faz isso. Por isso, é possível ver o código recém-adicionado que define o objeto blob e o local (bucket) do arquivo, bem como a chamada que realiza o upload real. (
upload_from_file()
). - O
webapp2
usa uma tabela de roteamento na parte de baixo do arquivo do aplicativo, enquanto as rotas do Flask são encontradas em cada gerenciador decorado. - Os dois gerenciadores finalizam a funcionalidade redirecionando para a página inicial (
/
), preservando a solicitaçãoPOST
com um código de retorno HTTP 307.
Gerenciador de downloads
A atualização do manipulador de download segue um padrão semelhante ao do gerenciador de uploads, porém há muito menos código para analisar. Substitua a funcionalidade do Blobstore e do webapp
pelos equivalentes do Cloud Storage e do Flask:
ANTES:
class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
'view uploaded blob (GET) handler'
def get(self, blob_key):
self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)
DEPOIS:
@app.route('/view/<path:fname>')
def view(fname):
'view uploaded blob (GET) handler'
blob = gcs_client.bucket(BUCKET).blob(fname)
try:
media = blob.download_as_bytes()
except exceptions.NotFound:
abort(404)
return send_file(io.BytesIO(media), mimetype=blob.content_type)
Observações sobre a atualização:
- Mais uma vez, o Flask decora as funções do gerenciador com a rota delas, enquanto o
webapp
faz isso em uma tabela de roteamento na parte inferior. Portanto, reconheça a sintaxe de correspondência de padrão('/view/([^/]+)?'
) e a do Flask ('/view/<path:fname>'
). - Assim como no gerenciador de upload, é necessário um pouco mais de trabalho no lado do Cloud Storage para a funcionalidade abstraída pelos gerenciadores do Blobstore, ou seja, identificar o arquivo (blob) em questão e fazer o download explícito do binário em comparação com a chamada de método
send_blob()
única do gerenciador do Blobstore. - Em ambos os casos, um erro HTTP 404 será retornado ao usuário se um artefato não for encontrado.
Gerenciador principal
As alterações finais no aplicativo principal ocorrem no gerenciador principal. Os métodos do verbo HTTP webapp2
foram substituídos por uma única função que combina a funcionalidade. Substitua a classe MainHandler
pela função root()
e remova a tabela de roteamento webapp2
, conforme mostrado abaixo:
ANTES:
class MainHandler(BaseHandler):
'main application (GET/POST) handler'
def get(self):
self.render_response('index.html',
upload_url=blobstore.create_upload_url('/upload'))
def post(self):
visits = fetch_visits(10)
self.render_response('index.html', visits=visits)
app = webapp2.WSGIApplication([
('/', MainHandler),
('/upload', UploadHandler),
('/view/([^/]+)?', ViewBlobHandler),
], debug=True)
DEPOIS:
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = fetch_visits(10)
return render_template('index.html', **context)
Em vez de separar os métodos get()
e post()
, eles são essencialmente uma instrução if-else
em root()
. Além disso, como root()
é uma função única, há apenas uma chamada para renderizar o modelo para GET
e POST
, mas isso não é possível no webapp2
.
Confira uma representação pictórica desse segundo e último conjunto de mudanças em main.py
:
(opcional) "Aprimoramento" de compatibilidade com versões anteriores
Portanto, a solução criada acima funciona perfeitamente, mas apenas se você estiver começando do zero e não tiver arquivos criados pelo Blobstore. Como atualizamos o app para identificar arquivos pelo nome de arquivo em vez de BlobKey
, o app completo do Módulo 16 não poderá visualizar arquivos do Blobstore. Em outras palavras, fizemos uma alteração incompatível com versões anteriores ao realizar essa migração. Apresentamos uma versão alternativa de main.py
, chamada main-migrate.py
(encontrada no repositório), que tenta preencher essa lacuna.
A primeira "extensão" para oferecer suporte aos arquivos criados pelo Blobstore é um modelo de dados que tem um BlobKeyProperty
(além de um StringProperty
para arquivos criados no Cloud Storage):
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
file_blob = ndb.BlobKeyProperty() # backwards-compatibility
file_gcs = ndb.StringProperty()
A propriedade file_blob
será usada para identificar arquivos criados pelo Blobstore, enquanto file_gcs
será usada para arquivos do Cloud Storage. Agora, ao criar novas visitas, armazene explicitamente um valor em file_gcs
em vez de file_blob
. Assim, store_visit será um pouco diferente:
ANTES:
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
DEPOIS:
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_gcs=upload_key).put()
Ao buscar as visitas mais recentes, "normalize" os dados antes de enviá-los ao modelo:
ANTES:
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = fetch_visits(10)
return render_template('index.html', **context)
DEPOIS:
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = etl_visits(fetch_visits(10))
return render_template('index.html', **context)
Em seguida, confirme a existência de file_blob
ou file_gcs
(ou nenhum dos dois). Se houver um arquivo disponível, escolha um atual e use esse identificador (BlobKey
para arquivos criados pelo Blobstore ou nome de arquivo para arquivos criados no Cloud Storage). Quando dizemos "arquivos criados no Cloud Storage", queremos dizer os arquivos criados com a biblioteca de cliente do Cloud Storage. O Blobstore também grava no Cloud Storage, mas, nesse caso, seriam arquivos criados pelo Blobstore.
Agora, mais importante, o que é essa função etl_visits()
que é usada para normalizar ou ETL (extrair, transformar e carregar) os dados para o usuário final? Esta é a aparência dela:
def etl_visits(visits):
return [{
'visitor': v.visitor,
'timestamp': v.timestamp,
'file_blob': v.file_gcs if hasattr(v, 'file_gcs') \
and v.file_gcs else v.file_blob
} for v in visits]
Ele provavelmente se parece com o que você esperava: o código passa por todas as visitas e, para cada visita, recebe os dados do visitante e do carimbo de data/hora na íntegra e verifica se file_gcs
ou file_blob
existem e, em caso afirmativo, escolhendo um deles (ou None
, se não existirem).
Esta é uma ilustração das diferenças entre main.py
e main-migrate.py
:
Se você estiver começando do zero sem os arquivos criados pelo Blobstore, use main.py
. No entanto, se estiver fazendo a transição e quiser oferecer suporte aos arquivos criados pelo Blobstore e pelo Cloud Storage, confira o main-migrate.py
como um exemplo de como lidar com um cenário para ajudar a planejar migrações para seus próprios apps. Ao fazer migrações complexas, é provável que surjam casos especiais. O objetivo deste exemplo é mostrar uma maior afinidade com a modernização de aplicativos reais com dados reais.
6. Resumo/limpeza
Esta seção encerra este codelab implantando o app, verificando se ele funciona conforme o esperado e em qualquer saída refletida. Após a validação do app, execute as etapas de limpeza e considere as próximas etapas.
Implante e verifique o aplicativo
Antes de reimplantar o app, execute pip install -t lib -r requirements.txt
para colocar essas bibliotecas de terceiros agrupadas na pasta lib. Se você quiser executar a solução compatível com versões anteriores, renomeie main-migrate.py
como main.py
primeiro. Agora, execute gcloud app deploy
e confirme se o app funciona de forma idêntica ao app Módulo 15. A tela do formulário vai ficar assim:
A página de visitas mais recentes tem esta aparência:
Parabéns por concluir este codelab substituindo o App Engine Blobstore pelo Cloud Storage, o App Engine MapReduce pelo Cloud NBS e o webapp2
pelo Flask. Seu código agora deve corresponder ao que está na pasta FINISH (módulo 16). O main-migrate.py
alternativo também está presente nessa pasta.
"Migração" do Python 3
Você só precisa da diretiva runtime
do Python 3 comentada na parte de cima de app.yaml
para transferir esse app para o Python 3. O código-fonte em si já é compatível com Python 3, portanto, nenhuma mudança é necessária. Para implantar como um aplicativo Python 3, execute as seguintes etapas:
- Remova a marca de comentário da diretiva
runtime
do Python 3 na parte de cima deapp.yaml
. - Exclua todas as outras linhas em
app.yaml
. - Exclua o arquivo
appengine_config.py
. (não utilizado no ambiente de execução do Python 3) - Exclua a pasta
lib
, se ela existir. (desnecessário com o ambiente de execução do Python 3)
Limpar
Geral
Se você já tiver terminado por enquanto, recomendamos que desative seu aplicativo do App Engine para evitar cobranças. No entanto, se você quiser fazer mais testes, saiba que a plataforma do App Engine tem uma cota sem custo financeiro e, desde que você não exceda esse nível de uso, não haverá cobranças. Isso é para computação, mas também pode haver cobranças por serviços relevantes do App Engine. Portanto, consulte a página de preços para mais informações. Se essa migração envolver outros serviços do Cloud, eles serão faturados separadamente. Em ambos os casos, se aplicável, consulte a seção "Específico para este codelab". seção abaixo.
Para divulgação completa, a implantação em uma plataforma de computação sem servidor do Google Cloud, como o App Engine, incorre em menores custos de criação e armazenamento. O Cloud Build tem a própria cota sem custo financeiro, assim como o Cloud Storage. O armazenamento da imagem consome parte da cota. No entanto, talvez você more em uma região que não tenha esse nível sem custo financeiro, portanto, esteja ciente do uso do armazenamento para minimizar os possíveis custos. "Pastas" específicas do Cloud Storage que você deve analisar incluem:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- Os links de armazenamento acima dependem do
PROJECT_ID
e da *LOC
*ação, por exemplo, "us
" caso seu app esteja hospedado nos EUA.
Por outro lado, se você não for continuar com este aplicativo ou outros codelabs de migração relacionados e quiser excluir tudo completamente, encerre seu projeto.
Específicos deste codelab
Os serviços listados abaixo são exclusivos deste codelab. Consulte a documentação de cada produto para mais informações:
- O serviço Blobstore do App Engine se enquadra nas Cotas e limites de dados armazenados. Analise essa questão e a página de preços de serviços em pacote legados.
- O Cloud Storage tem um nível sem custo financeiro para regiões específicas. Consulte também a página geral de preços para mais informações.
- o serviço App Engine Datastore é fornecido pelo Cloud Datastore (Cloud Firestore no modo Datastore), que também tem um nível sem custo financeiro; consulte a página de preços para mais informações."
Se você migrou do Módulo 15 para o 16, você ainda tem dados no Blobstore, por isso incluímos as informações de preços acima.
Próximas etapas
Além deste tutorial, outros módulos de migração que se concentram em abandonar os serviços em pacote legados a considerar incluem:
- Módulo 2: migrar do App Engine
ndb
para o Cloud NBS - Módulos 7 a 9: migrar de tarefas push da fila de tarefas do App Engine para o Cloud Tasks
- Módulos 12 a 13: migrar do Memcache do App Engine para o Cloud Memorystore
- Módulos 18 a 19: migrar da fila de tarefas do App Engine (tarefas pull) para o Cloud Pub/Sub
O App Engine não é mais a única plataforma sem servidor do Google Cloud. Se você tem um aplicativo pequeno do App Engine ou com funcionalidade limitada e quer transformá-lo em um microsserviço independente ou quer dividir um aplicativo monolítico em vários componentes reutilizáveis, estes são bons motivos para migrar para o Cloud Functions. Se a conteinerização se tornou parte do fluxo de trabalho de desenvolvimento de aplicativos, principalmente se consistir em um pipeline de CI/CD (integração/entrega contínua ou implantação), considere migrar para o Cloud Run. Esses cenários são abordados nos seguintes módulos:
- Migrar do App Engine para o Cloud Functions: consulte o Módulo 11
- Migrar do App Engine para o Cloud Run: consulte o Módulo 4 para conteinerizar seu app com o Docker ou o Módulo 5 para fazer isso sem contêineres, conhecimento do Docker ou
Dockerfile
s
A mudança para outra plataforma sem servidor é opcional. Recomendamos considerar as melhores opções para seus apps e casos de uso antes de fazer qualquer mudança.
Seja qual for o módulo de migração que você considerar a seguir, todo o conteúdo da estação de migração sem servidor (codelabs, vídeos, código-fonte [quando disponível]) pode ser acessado no repositório de código aberto. O README
do repositório também fornece orientações sobre quais migrações considerar e qualquer "ordem" relevante. de módulos de migração.
7. Outros recursos
Problemas/feedback do codelab
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 15 (INÍCIO) e do Módulo 16 (FINISH) podem ser encontrados na tabela abaixo. Eles também podem ser acessados no repositório de todas as migrações de codelab do App Engine. Você pode clonar ou fazer o download de um arquivo ZIP.
Codelab | Python 2 | Python 3 |
Módulo 15 | N/A | |
Módulo 16 (este codelab) | (igual ao Python 2) |
Recursos on-line
Veja abaixo recursos on-line que podem ser relevantes para este tutorial:
App Engine Blobstore e Cloud Storage
- Serviço Blobstore do App Engine
- Como migrar para a biblioteca de cliente do Cloud Storage
- Página inicial do Cloud Storage
- Documentação do Cloud Storage
Plataforma do App Engine
- Documentação do App Engine
- Ambiente de execução do App Engine para Python 2 (ambiente padrão)
- Como usar as bibliotecas integradas do App Engine no App Engine para Python 2
- Ambiente de execução do App Engine para Python 3 (ambiente padrão)
- Diferenças entre o Python 2 e o Três ambientes de execução do App Engine (ambiente padrão)
- Guia de migração do App Engine (ambiente padrão) Python 2 para 3
- Informações de preços e cotas do App Engine
- Lançamento da plataforma App Engine de segunda geração (2018)
- Comparação entre a primeira e plataformas de segunda geração
- Suporte de longo prazo para ambientes de execução legados
- Repositório de exemplos de migração da documentação (em inglês)
- Repositório de amostras de migração com contribuição da comunidade
Outras informações sobre a nuvem
- Python no Google Cloud Platform
- Bibliotecas de cliente do Python para Google Cloud
- "Sempre sem custo financeiro" do Google Cloud nível
- SDK Google Cloud (ferramenta de linha de comando
gcloud
) - Toda a documentação do Google Cloud
Python
- Sistemas de modelos Django e Jinja2
- Framework da Web
webapp2
- Documentação do
webapp2
(link em inglês) - Links
webapp2_extras
webapp2_extras
Documentação do Jinja2- Framework da Web Flask
Vídeos
- Estação de migração sem servidor
- Expedições sem servidor
- Inscreva-se no Google Cloud Tech
- Inscreva-se no Google Developers
Licença
Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.