1. Descripción general
La serie de codelabs Serverless Migration Station (instructivos prácticos y autoaprendizaje) y los videos relacionados tienen como objetivo ayudar a los desarrolladores de Google Cloud sin servidores a modernizar sus apps guiándolos a través de una o más migraciones, en especial al alejarse de los servicios heredados. De esta manera, tus apps serán más portátiles, y tendrás más opciones y flexibilidad, lo que te permitirá integrarlas con una variedad más amplia de productos de Cloud y acceder a ella, y actualizar con mayor facilidad a versiones de idiomas más recientes. Aunque inicialmente se enfoca en los primeros usuarios de Cloud, principalmente los desarrolladores de App Engine (entorno estándar), esta serie es lo suficientemente amplia como para incluir otras plataformas sin servidores como Cloud Functions y Cloud Run, o cualquier otra, si corresponde.
En este codelab, aprenderás a migrar desde Blobstore de App Engine a Cloud Storage. También hay migraciones implícitas desde:
- Framework web de
webapp2
a Flask (cubierto en el Módulo 1) - App Engine NDB a Cloud NDB para el acceso a Datastore (cubierto por el Módulo 2)
- Python 2 a 3 (la app migrada es compatible con Python 2 y 3)
Consulta los módulos de migración relacionados para obtener más información paso a paso.
En un próximo lab,
- Agrega el uso de la API o la biblioteca de Blobstore de App Engine
- Almacena las cargas de los usuarios al servicio de Blobstore
- Prepárate para el próximo paso de la migración a Cloud Storage
Requisitos
- Un proyecto de Google Cloud Platform con una cuenta de facturación de GCP activa
- Habilidades básicas de Python
- Conocimiento práctico de los comandos comunes de Linux
- Conocimientos básicos sobre el desarrollo y la implementación de aplicaciones de App Engine
- Una aplicación de App Engine del módulo 15 que funcione. Completa el codelab del módulo 15 (recomendado) o copia la app del módulo 15 del repositorio.
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Información general
Este codelab comienza con la app de ejemplo del módulo 15 y demuestra cómo migrar de Blobstore (y NDB) a Cloud Storage (y Cloud NDB). El proceso de migración implica reemplazar las dependencias de los paquetes de servicios heredados de App Engine, que te permiten mover tus apps a otra plataforma sin servidores en la nube o a otra plataforma de hosting, si así lo deseas.
Esta migración requiere un poco más de esfuerzo en comparación con las otras migraciones de esta serie. Blobstore tiene dependencias en el marco de trabajo de aplicaciones web original y es el motivo por el que la aplicación de muestra usa el marco de trabajo webapp2 en lugar de Flask. En este instructivo, se presentan migraciones a Cloud Storage, Cloud NDB, Flask y Python 3.
La app sigue registrando las "visitas" del usuario final y muestra los diez más recientes, pero el codelab anterior (Módulo 15) agregó una nueva funcionalidad para adaptarse al uso de Blobstore: la app solicita a los usuarios finales que suban un artefacto (un archivo) correspondiente a su “visita”. Los usuarios pueden hacerlo o seleccionar "omitir" para inhabilitarla. Independientemente de la decisión del usuario, la página siguiente procesa el mismo resultado que las versiones anteriores de esta app y muestra las visitas más recientes. Un giro adicional es que las visitas con los artefactos correspondientes incluyen una "vista". para mostrar el artefacto de una visita. En este codelab, se implementan las migraciones mencionadas anteriormente y se conserva la funcionalidad descrita.
3. Configurar/trabajo previo
Antes de llegar a la parte principal del instructivo, configuremos el proyecto, obtengamos el código y, luego, implementemos la app de referencia para que sepamos que comenzamos a trabajar con el código.
1. Configura el proyecto
Si ya implementaste la app del módulo 15, te recomendamos que vuelvas a usar ese mismo proyecto (y código). Como alternativa, puedes crear un proyecto completamente nuevo o reutilizar otro proyecto existente. Asegúrate de que el proyecto tenga una cuenta de facturación activa y App Engine esté habilitado.
2. Obtén app de ejemplo del modelo de referencia
Uno de los requisitos previos de este codelab es tener una app de ejemplo del módulo 15 que funcione. Si no la tienes, puedes obtenerla en el Módulo 15, "COMENZAR" (vínculo más abajo). En este codelab, se explica cada paso y se concluye con un código similar al que se muestra en el módulo 16, "FINALIZAR" carpeta.
- INICIO: Carpeta del módulo 15 (Python 2)
- FIN: Carpeta del módulo 16 (Python 2)
- Repositorio completo (para clonar o descargar un archivo ZIP)
El directorio de los archivos STARTing del módulo 15 debería verse de la siguiente manera:
$ ls README.md app.yaml main-gcs.py main.py templates
El archivo main-gcs.py
es una versión alternativa de main.py
del módulo 15 que permite seleccionar un bucket de Cloud Storage diferente del predeterminado de la URL asignada a una app según el ID del proyecto: PROJECT_ID
.appspot.com
. Este archivo no participa en este codelab (Módulo 16). Solo se pueden aplicar técnicas de migración similares a ese archivo si lo deseas.
3. (vuelve a) implementa la aplicación de modelo de referencia
Los pasos del trabajo previo restantes para ejecutar ahora sin estos:
- Familiarízate con la herramienta de línea de comandos de
gcloud
- Vuelve a implementar la app de muestra con
gcloud app deploy
- Confirma que la app se ejecuta en App Engine sin problemas
Una vez que hayas ejecutado correctamente esos pasos y confirmes que la app del Módulo 15 funciona. La página inicial recibe a los usuarios con un formulario que les solicita que suba un archivo de artefacto de visitas junto con una opción: "omitir" para inhabilitarlo:
Una vez que los usuarios suben un archivo o lo omiten, la app renderiza las "visitas más recientes" que ya conocen. página:
Las visitas que incluyan un artefacto tendrán una "vista" a la derecha de la marca de tiempo de la visita para mostrar (o descargar) el artefacto. Una vez que confirmes la funcionalidad de la app, estará todo listo para migrar de los servicios heredados de App Engine (webapp2, NBS, Blobstore) a alternativas contemporáneas (Flask, Cloud NDB y Cloud Storage).
4. Actualiza archivos de configuración
Tres archivos de configuración entran en juego para la versión actualizada de nuestra app. Las tareas requeridas son las siguientes:
- Actualiza las bibliotecas de terceros integradas necesarias en
app.yaml
y deja la puerta abierta para una migración a Python 3. - Agrega un
requirements.txt
, que especifica todas las bibliotecas necesarias que no están integradas. - Se agregó
appengine_config.py
para que la app admita bibliotecas de terceros integradas y no integradas.
app.yaml
Actualiza la sección libraries
para editar tu archivo app.yaml
. Se quitó jinja2
y se agregaron grpcio
, setuptools
y ssl
. Elige la versión más reciente disponible para las tres bibliotecas. También agrega la directiva runtime
de Python 3, pero se marcó como comentario. Cuando termines, debería verse de la siguiente manera (si seleccionaste Python 3.9):
ANTES:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
DESPUÉS:
#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
Los cambios se relacionan principalmente con las bibliotecas integradas de Python 2 disponibles en los servidores de App Engine (por lo que no tienes que agruparlas por tu cuenta). Quitamos Jinja2 porque viene con Flask, que agregaremos a reqs.txt. Cada vez que se usan las bibliotecas cliente de Google Cloud, como las de Cloud NDB y Cloud Storage, se necesitan grpcio y setuptools. Por último, Cloud Storage requiere la biblioteca SSL. La directiva de entorno de ejecución comentada que aparece en la parte superior sirve para cuando tengas todo listo para transferir esta app a Python 3. Abordaremos este tema al final de este instructivo.
requirements.txt
Agrega un archivo requirements.txt
, que requiere el framework de Flask y las bibliotecas cliente de Cloud NDB y Cloud Storage, ninguna de las cuales está integrada. Crea el archivo con este contenido:
flask
google-cloud-ndb
google-cloud-storage
El entorno de ejecución de App Engine para Python 2 requiere la agrupación automática de bibliotecas de terceros no integradas. Por lo tanto, ejecuta el siguiente comando para instalar estas bibliotecas en la carpeta lib:
pip install -t lib -r requirements.txt
Si tienes Python 2 y 3 en tu máquina de desarrollo, es posible que debas usar el comando de pip2 para asegurarte de obtener las versiones Python 2 de estas bibliotecas. Una vez que actualices a Python 3, ya no necesitarás empaquetar tú mismo.
appengine_config.py
Agrega un archivo appengine_config.py
que admita bibliotecas de terceros integradas y no integradas. Crea el archivo con este contenido:
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)
Los pasos que acabas de completar deben ser similares o idénticos a los que se indican en la sección Instala bibliotecas para apps de Python 2 de los documentos de App Engine y, más específicamente, el contenido de appengine_config.py
debe coincidir con el que aparece en el Paso 5.
Ya se completó el trabajo en los archivos de configuración, así que pasemos a la aplicación.
5. Modifica archivos de la aplicación
Importaciones
El primer conjunto de cambios para main.py
incluye el intercambio de todos los elementos que se reemplazarán. Esto es lo que cambiará:
- Se reemplazó
webapp2
por Flask. - En lugar de usar Jinja2 de
webapp2_extras
, usa el Jinja2 que viene con Flask. - Cloud NDB y Cloud Storage reemplazaron App Engine Blobstore y NDB
- Los controladores de Blobstore en
webapp
se reemplazaron por una combinación de las utilidades del módulo de biblioteca estándario
, Flask ywerkzeug
- De forma predeterminada, Blobstore escribe en un bucket de Cloud Storage con el nombre de la URL de tu app (
PROJECT_ID.appspot.com
). Debido a que estamos realizando la portabilidad a la biblioteca cliente de Cloud Storage, se usagoogle.auth
para obtener el ID del proyecto y especificar exactamente el mismo nombre de bucket. Puedes cambiar el nombre del bucket, ya que ya no está codificado.
ANTES:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Para implementar los cambios de la lista anterior, reemplaza la sección de importación actual en main.py
con el siguiente fragmento de código.
DESPUÉS:
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
Inicialización y compatibilidad innecesaria con Jinja2
El siguiente bloque de código que se debe reemplazar es el BaseHandler
que especifica el uso de Jinja2 de webapp2_extras
. Esto no es necesario porque Jinja2 viene con Flask y es su motor de plantillas predeterminado, así que quítelo.
En el módulo 16, crea instancias de objetos que no teníamos en la app anterior. Esto incluye inicializar la app de Flask y crear clientes de la API para Cloud NDB y Cloud Storage. Por último, armamos el nombre del bucket de Cloud Storage como se describió anteriormente en la sección de importaciones. Estas son las situaciones previas y posteriores a la implementación de estas actualizaciones:
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))
DESPUÉS:
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
Actualiza el acceso a Datastore
Cloud NDB es mayormente compatible con App Engine NDB. Una diferencia que ya se aborda es la necesidad de un cliente de API. Otro es el último requiere que el administrador de contexto de Python del cliente de la API controle el acceso a Datastore. En esencia, esto significa que todas las llamadas de acceso a Datastore con la biblioteca cliente de Cloud NDB solo pueden ocurrir dentro de los bloques with
de Python.
Es un cambio. y la otra es que Blobstore y sus objetos, p.ej., Los objetos BlobKey
no son compatibles con Cloud Storage, por lo que debes cambiar file_blob
para que sea ndb.StringProperty
en su lugar. A continuación, se muestran la clase de modelo de datos y las funciones store_visit()
y fetch_visits()
actualizadas que reflejan estos cambios:
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)
DESPUÉS:
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)
Esta es una representación ilustrativa de los cambios que se realizaron hasta el momento:
Actualiza los controladores
Subir controlador
Los controladores en webapp2
son clases mientras son funciones en Flask. En lugar de un método de verbo HTTP, Flask usa el verbo para decorar la función. Blobstore y sus controladores webapp
se reemplazaron por la funcionalidad de Cloud Storage, así como de Flask y sus utilidades:
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)
DESPUÉS:
@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)
Notas sobre esta actualización:
- En lugar de
blob_id
, los artefactos de archivo ahora se identifican por nombre de archivo (fname
) si está presente yNone
en caso contrario (el usuario inhabilitó la carga de un archivo). - Los controladores de Blobstore abstraen el proceso de carga de sus usuarios, pero Cloud Storage no lo hace, de modo que puedes ver el código recién agregado que establece el objeto BLOB y la ubicación (bucket) del archivo, así como la llamada que realiza la carga real. (
upload_from_file()
). webapp2
usa una tabla de enrutamiento en la parte inferior del archivo de la aplicación, mientras que las rutas de Flask se encuentran en cada controlador decorado.- Para completar su funcionalidad, ambos controladores redireccionan a la página principal (
/
) y conservan la solicitudPOST
con un código de retorno HTTP 307.
Descargar controlador
La actualización del controlador de descarga sigue un patrón similar al de carga, solo que hay mucho menos código que analizar. Reemplaza la funcionalidad de Blobstore y webapp
por los equivalentes de Cloud Storage y 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)
DESPUÉS:
@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)
Notas sobre esta actualización:
- Nuevamente, Flask decora las funciones de controlador con su ruta, mientras que
webapp
lo hace en una tabla de enrutamiento en la parte inferior, por lo que debes reconocer la sintaxis de coincidencia de patrones de este último,('/view/([^/]+)?'
) en comparación con la de Flask ('/view/<path:fname>'
). - Al igual que con el controlador de carga, se requiere un poco más de trabajo en Cloud Storage para la funcionalidad abstracta de los controladores de Blobstore, es decir, identificar el archivo (BLOB) en cuestión y descargar explícitamente el objeto binario en comparación con la única llamada al método
send_blob()
del controlador de Blobstore. - En ambos casos, se muestra un error HTTP 404 al usuario si no se encuentra un artefacto.
Controlador principal
Los cambios finales en la aplicación principal se realizan en el controlador principal. Los métodos del verbo HTTP webapp2
se reemplazan por una sola función que combina su funcionalidad. Reemplaza la clase MainHandler
por la función root()
y quita la tabla de enrutamiento webapp2
como se muestra a continuación:
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)
DESPUÉS:
@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)
En lugar de separar los métodos get()
y post()
, son, en esencia, una sentencia if-else
en root()
. Además, debido a que root()
es una única función, solo hay una llamada con el objetivo de renderizar la plantilla tanto para GET
como para POST
, pero no es posible en webapp2
.
A continuación, se incluye una representación visual del segundo y último conjunto de cambios de main.py
:
"Mejora" de la retrocompatibilidad (opcional)
Entonces, la solución creada anteriormente funciona a la perfección, pero solo si comienzas desde cero y no tienes archivos creados por Blobstore. Debido a que actualizamos la app para identificar archivos por nombre de archivo en lugar de BlobKey
, la app del Módulo 16 completada sin modificaciones no podrá ver los archivos de Blobstore. En otras palabras, realizamos un cambio incompatible con las versiones anteriores cuando realizamos esta migración. Ahora presentamos una versión alternativa de main.py
llamada main-migrate.py
(que se encuentra en el repositorio) que intenta reducir esta brecha.
La primera "extensión" Para admitir archivos creados en Blobstore, hay un modelo de datos que tiene un BlobKeyProperty
(además de un StringProperty
para los archivos creados en 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()
La propiedad file_blob
se usará para identificar los archivos creados en Blobstore, mientras que file_gcs
es para archivos de Cloud Storage. Ahora, cuando crees visitas nuevas, almacena explícitamente un valor en file_gcs
en lugar de file_blob
, de modo que store_visit se ve un poco 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()
DESPUÉS:
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()
Cuando recupere las visitas más recientes, "normalice" los datos antes de enviarlos a la plantilla:
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)
DESPUÉS:
@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)
A continuación, confirma la existencia de file_blob
o file_gcs
(o ninguno). Si hay un archivo disponible, elige el que exista y usa ese identificador (BlobKey
para archivos creados en Blobstore o nombre de archivo para archivos creados en Cloud Storage). Cuando decimos “Archivos creados en Cloud Storage”, nos referimos a archivos que se crean
con la biblioteca cliente de Cloud Storage. Blobstore también escribe en Cloud Storage, pero, en este caso, esos serían archivos creados por Blobstore.
Ahora más importante, ¿cuál es la función etl_visits()
que se usa para normalizar o ETL (extraer, transformar y cargar) los datos para el usuario final? El aspecto resultante será el siguiente:
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]
Probablemente se ve como lo que esperabas: el código repite todas las visitas y, para cada visita, toma los datos del visitante y de la marca de tiempo de forma literal. Luego, comprueba si existen file_gcs
o file_blob
y, de ser así, selecciona una de ellas (o None
si no existe ninguna).
A continuación, se muestra una ilustración de las diferencias entre main.py
y main-migrate.py
:
Si comienzas desde cero sin archivos creados por Blobstore, usa main.py
, pero si quieres realizar una transición y deseas archivos complementarios creados por Blobstore y Cloud Storage, consulta main-migrate.py
como ejemplo de cómo abordar situaciones como para ayudarte a planificar migraciones para tus propias apps. Cuando se realizan migraciones complejas, es probable que surjan casos especiales, por lo que este ejemplo pretende mostrar una mayor afinidad por la modernización de apps reales con datos reales.
6. Resumen/limpieza
En esta sección, se finaliza este codelab implementando la app y verificando que funcione según lo previsto y en cualquier resultado reflejado. Después de validar la app, realiza los pasos de limpieza y considera los siguientes.
Implementa y verifica la aplicación
Antes de volver a implementar tu app, asegúrate de ejecutar pip install -t lib -r requirements.txt
para obtener esas bibliotecas de terceros empaquetadas automáticamente en la carpeta lib. Si deseas ejecutar la solución retrocompatible, primero cambia el nombre de main-migrate.py
a main.py
. Ahora, ejecuta gcloud app deploy
y confirma que la app funcione de manera idéntica a la del Módulo 15. La pantalla del formulario se ve de la siguiente manera:
La página de visitas más recientes se ve así:
Felicitaciones por completar este codelab para reemplazar App Engine Blobstore por Cloud Storage, App Engine NDB por Cloud NDB y webapp2
por Flask. Tu código ahora debería coincidir con el que está en la carpeta FINISH (Módulo 16). El main-migrate.py
alternativo también está presente en esa carpeta.
“Migración” de Python 3
La directiva runtime
de Python 3 comentada en la parte superior de app.yaml
es todo lo que se necesita para transferir esta app a Python 3. El código fuente en sí ya es compatible con Python 3, de modo que no se necesitan cambios allí. Para implementar esto como una aplicación de Python 3, ejecuta los siguientes pasos:
- Quita el comentario de la directiva
runtime
de Python 3 en la parte superior deapp.yaml
. - Borra todas las demás líneas de
app.yaml
. - Borra el archivo
appengine_config.py
. (no se usa en el entorno de ejecución de Python 3) - Borra la carpeta
lib
si existe. (no es necesario con el entorno de ejecución de Python 3)
Limpia
General
Si ya terminaste, te recomendamos que inhabilites la aplicación de App Engine para evitar que se te facture. Sin embargo, si deseas probar o experimentar un poco más, la plataforma de App Engine tiene una cuota gratuita y, siempre y cuando no superes ese nivel de uso, no se te debería cobrar. Eso es para procesamiento, pero es posible que también se apliquen cargos por servicios relevantes de App Engine, así que consulta la página de precios para obtener más información. Si esta migración implica otros servicios de Cloud, estos se facturan por separado. En ambos casos, si corresponde, consulta la sección "Específico de este codelab" a continuación.
Para una divulgación completa, la implementación en una plataforma de procesamiento sin servidores de Google Cloud, como App Engine, genera costos menores de compilación y almacenamiento. Cloud Build tiene su propia cuota gratuita, al igual que Cloud Storage. El almacenamiento de esa imagen ocupa parte de esa cuota. Sin embargo, es posible que vivas en una región que no cuenta con ese nivel gratuito, así que ten en cuenta el uso que haces del almacenamiento para minimizar posibles costos. “Carpetas” específicas de Cloud Storage que debes revisar incluyen
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
- Los vínculos de almacenamiento anteriores dependen de tu
PROJECT_ID
y *LOC
*; por ejemplo, "us
" si tu app está alojada en EE.UU.
Por otro lado, si no vas a continuar con esta aplicación o algún otro codelab de migración relacionado y quieres borrar todo por completo, cierra tu proyecto.
Información específica de este codelab
Los servicios que se indican a continuación son exclusivos de este codelab. Consulta la documentación de cada producto para obtener más información:
- El servicio de Blobstore de App Engine está incluido en las cuotas y los límites de datos almacenados, así que revísalos, así como la página de precios de los servicios en paquete heredados.
- Cloud Storage tiene un nivel gratuito para regiones específicas. también puedes consultar su página de precios general para obtener más información.
- El servicio de App Engine Datastore lo proporciona Cloud Datastore (Cloud Firestore en modo Datastore), que también tiene un nivel gratuito. consulta su página de precios para obtener más información".
Ten en cuenta que, si migraste del módulo 15 al 16, seguirás teniendo datos en Blobstore, por lo que incluimos la información de precios más arriba.
Próximos pasos
Más allá de este instructivo, otros módulos de migración que se enfocan en alejarse de los servicios en paquetes heredados que se deben considerar incluyen los siguientes:
- Módulo 2: migrar de
ndb
de App Engine a Cloud NDB - Módulos del 7 al 9: Migra de las tareas push de la lista de tareas en cola de App Engine a Cloud Tasks
- Módulos del 12 al 13: Migra de Memcache de App Engine a Cloud Memorystore
- Módulos del 18 al 19: Migra de la lista de tareas en cola de App Engine (tareas de extracción) a Cloud Pub/Sub.
App Engine ya no es la única plataforma sin servidores en Google Cloud. Si tienes una aplicación pequeña de App Engine o una con funcionalidad limitada y deseas convertirla en un microservicio independiente, o si deseas dividir una aplicación monolítica en varios componentes reutilizables, estas son buenas razones para considerar cambiar a Cloud Functions. Si la creación de contenedores se volvió parte del flujo de trabajo de desarrollo de tu aplicación, en especial si consta de una canalización de CI/CD (integración continua/entrega o implementación continuas), considera migrar a Cloud Run. Estas situaciones se abordan en los siguientes módulos:
- Migra de App Engine a Cloud Functions: consulta el Módulo 11.
- Migra de App Engine a Cloud Run. Consulta el Módulo 4 para alojar tu app en contenedores con Docker, o el Módulo 5 para hacerlo sin contenedores, conocimiento sobre Docker ni
Dockerfile
.
Cambiar a otra plataforma sin servidores es opcional, y te recomendamos que consideres las mejores opciones para tus apps y casos de uso antes de realizar cualquier cambio.
Independientemente del módulo de migración que consideres a continuación, puedes acceder a todo el contenido de Serverless Migration Station (codelabs, videos, código fuente [si está disponible]) a través de su repositorio de código abierto. El README
del repositorio también proporciona orientación sobre qué migraciones considerar y cualquier "orden" relevante. de los módulos de migración.
7. Recursos adicionales
Problemas o comentarios sobre el codelab
Si encuentras algún problema con este Codelab, primero busca el problema antes de enviarlo. Vínculos para buscar y crear problemas nuevos:
Recursos de migración
En la siguiente tabla, encontrarás los vínculos a las carpetas del repositorio del módulo 15 (START) y el módulo 16 (FINISH). También puedes acceder a ellos desde el repositorio para todas las migraciones del codelab de App Engine. Puedes clonar o descargar un archivo ZIP.
Codelab | Python 2 | Python 3 |
Módulo 15 | N/A | |
Módulo 16 (este codelab) | (igual que Python 2) |
Recursos en línea
A continuación, hay recursos en línea que pueden ser relevantes para este tutorial:
Blobstore de App Engine y Cloud Storage
- Servicio de Blobstore de App Engine
- Migra a la biblioteca cliente de Cloud Storage
- Página principal de Cloud Storage
- Documentación de Cloud Storage
Plataforma de App Engine
- Documentación de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 2
- Usa las bibliotecas integradas de App Engine en Python 2 de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 3
- Diferencias entre Python 2 y 3 entornos de ejecución de App Engine (entorno estándar)
- Guía de migración de Python 2 a 3 de App Engine (entorno estándar)
- Información de precios y cuotas de App Engine
- Lanzamiento de la plataforma de App Engine de segunda generación (2018)
- Comparación primero y plataformas de segunda generación
- Asistencia a largo plazo para entornos de ejecución heredados
- Repositorio de muestras de migración de documentación
- Repositorio de muestras de migración aportadas por la comunidad
Otra información de Cloud
- Python en Google Cloud Platform
- Bibliotecas cliente de Python de Google Cloud
- Google Cloud “Siempre gratuito” nivel
- SDK de Google Cloud (herramienta de línea de comandos de
gcloud
) - Toda la documentación de Google Cloud
Python
- Sistemas de plantillas de Django y Jinja2
- Framework web de
webapp2
- Documentación de
webapp2
- Vínculos de
webapp2_extras
- Documentación de
webapp2_extras
de Jinja2 - Framework web de Flask
Videos
- Estación de migración sin servidores
- Expediciones sin servidores
- Suscríbete a Google Cloud Tech
- Suscríbete a Google Developers.
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.