1. Panoramica
Questa serie di codelab (tutorial pratici e autonomi) ha lo scopo di aiutare gli sviluppatori di Google App Engine (ambiente standard) a modernizzare le loro app guidandoli attraverso una serie di migrazioni. Il passaggio più significativo è l'abbandono dei servizi di runtime originali in bundle, perché i runtime di nuova generazione sono più flessibili e offrono agli utenti una maggiore varietà di opzioni di servizio. Il passaggio al runtime di nuova generazione consente di integrarsi più facilmente con i prodotti Google Cloud, utilizzare una gamma più ampia di servizi supportati e supportare le versioni attuali dei linguaggi.
Questo tutorial facoltativo mostra agli sviluppatori come eseguire la migrazione da Cloud NDB a Cloud Datastore come libreria client per comunicare con il servizio Datastore. Gli sviluppatori che preferiscono NDB possono continuare a utilizzarlo perché è compatibile con Python 3, quindi la migrazione è facoltativa. Questa migrazione è destinata solo a chi vuole creare un codebase coerente e librerie condivise con altre app che utilizzano già Cloud Datastore. Questo è spiegato nella sezione "Contesto".
Imparerai come
- Utilizza Cloud NDB (se non lo conosci)
- Migrazione da Cloud NDB a Cloud Datastore
- Esegui la migrazione della tua app a Python 3
Che cosa ti serve
- Un progetto Google Cloud Platform con un account di fatturazione GCP attivo
- Competenze di base di Python
- Conoscenza pratica dei comandi Linux di base
- Conoscenza di base dello sviluppo e del deployment di app App Engine
- Un'app App Engine 2.x o 3.x del modulo 2 funzionante.
Sondaggio
Come utilizzerai questo codelab?
2. Sfondo
Sebbene Cloud NDB sia un'ottima soluzione Datastore per gli sviluppatori App Engine di lunga data e aiuti a passare a Python 3, non è l'unico modo in cui gli sviluppatori App Engine possono accedere a Datastore. Quando Datastore di App Engine è diventato un prodotto autonomo nel 2013, è stata creata una nuova libreria client, Cloud Datastore, in modo che tutti gli utenti potessero utilizzare Datastore.
Gli sviluppatori di App Engine e non-App Engine Python 3 sono invitati a utilizzare Cloud Datastore (non Cloud NDB). Gli sviluppatori di App Engine Python 2 sono invitati a eseguire la migrazione da ndb a Cloud NDB e il porting a Python 3, ma possono anche scegliere di eseguire la migrazione a Cloud Datastore. Si tratta di una decisione logica, soprattutto per gli sviluppatori che hanno già codice che utilizza Cloud Datastore, come quelli appena menzionati, e vogliono creare librerie condivise in tutte le loro applicazioni. Il riutilizzo del codice è una best practice, così come la coerenza del codice, ed entrambi contribuiscono a ridurre il costo complessivo della manutenzione, come riassunto di seguito:
Migrazione da Cloud NDB a Cloud Datastore
- Consente agli sviluppatori di concentrarsi su un unico codebase per l'accesso a Datastore
- Evita di gestire parte del codice utilizzando Cloud NDB e parte utilizzando Cloud Datastore
- Offre maggiore coerenza nel codebase e una migliore riutilizzabilità del codice
- Consente l'utilizzo di librerie comuni/condivise, il che contribuisce a ridurre il costo di manutenzione complessivo
Questa migrazione prevede i seguenti passaggi principali:
- Configurazione/preparazione
- Sostituisci Cloud NDB con le librerie client di Cloud Datastore
- Aggiorna applicazione
3. Configurazione/preparazione
Prima di iniziare la parte principale del tutorial, configuriamo il progetto, recuperiamo il codice e poi implementiamo l'app di base per assicurarci di iniziare con un codice funzionante.
1. Configura il progetto
Se hai completato il codelab del modulo 2, ti consigliamo di riutilizzare lo stesso progetto (e codice). In alternativa, puoi creare un nuovo progetto o riutilizzarne uno esistente. Assicurati che il progetto abbia un account di fatturazione attivo e che App Engine (app) sia abilitato.
2. Ottieni l'app di esempio di base
Uno dei prerequisiti è avere un'app di esempio del modulo 2 funzionante. Utilizza la tua soluzione se hai completato il tutorial. Puoi completarlo ora (link sopra) oppure, se vuoi saltarlo, copia il repository del modulo 2 (link sotto).
Che tu utilizzi il tuo o il nostro, il codice del modulo 2 è il punto di partenza. Questo codelab del modulo 3 ti guida in ogni passaggio e, al termine, dovrebbe assomigliare al codice nel punto FINISH. Esistono le versioni Python 2 e 3 di questo tutorial, quindi prendi il repository di codice corretto di seguito.
Python 2
- INIZIO: Codice del modulo 2
- FINE: Codice del Modulo 3
- Intero repository (per clonare o scaricare il file ZIP)
La directory dei file START di Python 2 Module 2 (tuoi o nostri) dovrebbe avere il seguente aspetto:
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
Se hai completato il tutorial del modulo 2, avrai anche una cartella lib con Flask e le relative dipendenze. Se non hai una cartella lib, creala con il comando pip install -t lib -r requirements.txt in modo da poter eseguire il deployment di questa app di base nel passaggio successivo. Se hai installato sia Python 2 che Python 3, ti consigliamo di utilizzare pip2 anziché pip per evitare confusione con Python 3.
Python 3
- INIZIO: Repository del modulo 2
- FINISH: Module 3 repo
- Intero repository (per clonare o scaricare il file ZIP)
La directory dei file di avvio del Modulo 2 di Python 3 (tuoi o nostri) dovrebbe avere il seguente aspetto:
$ ls
README.md main.py templates
app.yaml requirements.txt
Né lib né appengine_config.py vengono utilizzati per Python 3.
3. (Esegui di nuovo il deployment dell'app del modulo 2
I passaggi preliminari rimanenti da eseguire ora:
- Acquisisci di nuovo familiarità con lo strumento a riga di comando
gcloud(se necessario). - (Esegui di nuovo il deployment del codice del modulo 1 in App Engine (se necessario))
Una volta eseguiti correttamente questi passaggi e verificato che sia operativo, andremo avanti in questo tutorial, a partire dai file di configurazione.
4. Sostituisci Cloud NDB con le librerie client di Cloud Datastore
L'unica modifica alla configurazione è una piccola sostituzione del pacchetto nel file requirements.txt.
1. Aggiorna requirements.txt
Al termine del modulo 2, il file requirements.txt aveva questo aspetto:
- PRIMA (Python 2 e 3):
Flask==1.1.2
google-cloud-ndb==1.7.1
Aggiorna requirements.txt sostituendo la libreria Cloud NDB (google-cloud-ndb) con l'ultima versione della libreria Cloud Datastore (google-cloud-datastore), lasciando intatta la voce per Flask, tenendo presente che l'ultima versione di Cloud Datastore compatibile con Python 2 è la 1.15.3:
- AFTER (Python 2):
Flask==1.1.2
google-cloud-datastore==1.15.3
- DOPO (Python 3):
Flask==1.1.2
google-cloud-datastore==2.1.0
Tieni presente che il repository viene aggiornato più regolarmente di questo tutorial, quindi è possibile che il file requirements.txt rifletta versioni più recenti. Ti consigliamo di utilizzare le versioni più recenti di ogni libreria, ma se non funzionano, puoi eseguire il rollback a una release precedente. I numeri di versione riportati sopra sono gli ultimi disponibili al momento dell'ultimo aggiornamento di questo codelab.
2. Altri file di configurazione
Gli altri file di configurazione, app.yaml e appengine_config.py, devono rimanere invariati rispetto al passaggio di migrazione precedente:
app.yamldeve (ancora) fare riferimento ai pacchetti in bundle di terze partigrpcioesetuptools.appengine_config.pydeve (ancora) puntarepkg_resourcesegoogle.appengine.ext.vendoralle risorse di terze parti inlib.
Ora passiamo ai file dell'applicazione.
5. Aggiorna i file dell'applicazione
Non sono state apportate modifiche a template/index.html, ma sono disponibili alcuni aggiornamenti per main.py.
1. Importazioni
Il codice iniziale per la sezione di importazione dovrebbe essere il seguente:
- PRIMA:
from flask import Flask, render_template, request
from google.cloud import ndb
Sostituisci l'importazione google.cloud.ndb con una per Cloud Datastore: google.cloud.datastore. Poiché la libreria client Datastore non supporta la creazione automatica di un campo timestamp in un'entità, importa anche il modulo della libreria standard datetime per crearne uno manualmente. Per convenzione, le importazioni di librerie standard precedono quelle di pacchetti di terze parti. Al termine delle modifiche, il codice dovrebbe avere il seguente aspetto:
- DOPO:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore
2. Inizializzazione e modello di dati
Dopo aver inizializzato Flask, l'app di esempio del modulo 2 che crea una classe di modello di dati NDB e i relativi campi ha il seguente aspetto:
- PRIMA:
app = Flask(__name__)
ds_client = ndb.Client()
class Visit(ndb.Model):
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
La libreria Cloud Datastore non ha una classe di questo tipo, quindi elimina la dichiarazione della classe Visit. Hai comunque bisogno di un client per comunicare con Datastore, quindi modifica ndb.Client() in datastore.Client(). La libreria Datastore è più "flessibile" e ti consente di creare entità senza "dichiararne in anticipo" la struttura come NDB. Dopo questo aggiornamento, questa parte di main.py dovrebbe avere il seguente aspetto:
- DOPO:
app = Flask(__name__)
ds_client = datastore.Client()
3. Accesso a Datastore
La migrazione a Cloud Datastore richiede la modifica del modo in cui vengono create, archiviate ed eseguite query sulle entità Datastore (a livello utente). Per le tue applicazioni, la difficoltà di questa migrazione dipende dalla complessità del codice Datastore. Nella nostra app di esempio, abbiamo cercato di rendere l'aggiornamento il più semplice possibile. Ecco il nostro codice iniziale:
- PRIMA:
def store_visit(remote_addr, user_agent):
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
with ds_client.context():
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch_page(limit)[0])
Con Cloud Datastore, crea un'entità generica, identificando gli oggetti raggruppati nell'entità con una "chiave". Crea il record di dati con un oggetto JSON (Python dict) di coppie chiave-valore, quindi scrivilo in Datastore con il put() previsto. L'esecuzione di query è simile, ma più semplice con Datastore. Qui puoi vedere in che modo differisce il codice Datastore equivalente:
- DOPO:
def store_visit(remote_addr, user_agent):
entity = datastore.Entity(key=ds_client.key('Visit'))
entity.update({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
ds_client.put(entity)
def fetch_visits(limit):
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
return query.fetch(limit=limit)
Aggiorna i corpi delle funzioni per store_visit() e fetch_visits() come sopra, mantenendo le firme identiche alla versione precedente. Non sono state apportate modifiche al gestore principale root(). Dopo aver completato queste modifiche, la tua app è ora attrezzata per utilizzare Cloud Datastore e pronta per il test.
6. Riepilogo/Pulizia
Esegui il deployment di un'applicazione
Esegui nuovamente il deployment dell'app con gcloud app deploy e verifica che funzioni. Il codice ora dovrebbe corrispondere a quello presente nelle cartelle del repository del modulo 3:
Se hai iniziato questa serie senza aver svolto i codelab precedenti, l'app non cambia. Registra tutte le visite alla pagina web principale (/) e ha questo aspetto dopo che hai visitato il sito un numero sufficiente di volte:

Congratulazioni per aver completato questo codelab del modulo 3. Ora sai che puoi utilizzare sia le librerie client Cloud NDB che Cloud Datastore per accedere a Datastore. Se esegui la migrazione a quest'ultima, ora puoi usufruire dei vantaggi delle librerie condivise, del codice comune e del riutilizzo del codice per garantire la coerenza e ridurre i costi di manutenzione.
(Facoltativo) Pulizia
Eseguire la pulizia per evitare addebiti fino a quando non sarai pronto per passare al codelab di migrazione successivo. In qualità di sviluppatori esistenti, probabilmente siete già aggiornati sulle informazioni sui prezzi di App Engine.
(Facoltativo) Disattiva l'app
Se non sei ancora pronto per passare al tutorial successivo, disattiva l'app per evitare addebiti. Quando vuoi passare al codelab successivo, puoi riattivarlo. Mentre l'app è disattivata, non riceverà traffico per generare addebiti. Tuttavia, un altro aspetto per cui potresti ricevere una fattura è l'utilizzo di Datastore se supera la quota senza costi, quindi elimina i dati sufficienti per rientrare in questo limite.
D'altra parte, se non intendi continuare con le migrazioni e vuoi eliminare tutto completamente, puoi chiudere il progetto.
Passaggi successivi
Da qui, puoi esplorare i seguenti moduli di migrazione:
- Bonus del modulo 3:continua nella sezione bonus per scoprire come eseguire il porting a Python 3 e al runtime di nuova generazione di App Engine.
- Modulo 7: code di attività push di App Engine (obbligatorio se utilizzi le code di attività [push])
- Aggiunge le attività push di App Engine
taskqueueall'app del modulo 1 - Prepara gli utenti alla migrazione a Cloud Tasks nel modulo 8
- Aggiunge le attività push di App Engine
- Modulo 4: esegui la migrazione a Cloud Run con Docker
- Containerizzare l'app per eseguirla su Cloud Run con Docker
- Ti consente di rimanere su Python 2
- Modulo 5: esegui la migrazione a Cloud Run con Cloud Buildpacks
- Containerizzare l'app per eseguirla su Cloud Run con Cloud Buildpacks
- Non è necessario sapere nulla di Docker, container o
Dockerfiles - Richiede che tu abbia già eseguito la migrazione dell'app a Python 3
- Modulo 6: esegui la migrazione a Cloud Firestore
- Esegui la migrazione a Cloud Firestore per accedere alle funzionalità di Firebase
- Sebbene Cloud Firestore supporti Python 2, questo codelab è disponibile solo in Python 3.
7. BONUS: esegui la migrazione a Python 3
Per accedere al runtime e alle funzionalità più recenti di App Engine, ti consigliamo di eseguire la migrazione a Python 3. Nella nostra app di esempio, Datastore era l'unico servizio integrato che abbiamo utilizzato e, poiché abbiamo eseguito la migrazione da ndb a Cloud NDB, ora possiamo eseguire il porting al runtime Python 3 di App Engine.
Panoramica
Sebbene il porting a Python 3 non rientri nell'ambito di un tutorial di Google Cloud, questa parte del codelab offre agli sviluppatori un'idea di come differisce il runtime Python 3 di App Engine. Una delle caratteristiche più importanti del runtime di nuova generazione è l'accesso semplificato ai pacchetti di terze parti: non è necessario specificare i pacchetti integrati in app.yaml né copiare o caricare librerie non integrate; vengono installate implicitamente dall'elenco in requirements.txt.
Poiché il nostro campione è molto semplice e Cloud Datastore è compatibile con Python 2-3, non è necessario eseguire il porting esplicito del codice dell'applicazione alla versione 3.x: l'app viene eseguita nelle versioni 2.x e 3.x senza modifiche, il che significa che in questo caso le uniche modifiche richieste riguardano la configurazione:
- Semplifica
app.yamlper fare riferimento a Python 3 e rimuovere il riferimento alle librerie di terze parti in bundle. - Elimina
appengine_config.pye la cartellalibperché non sono più necessari.
I file dell'applicazione main.py e templates/index.html rimangono invariati.
Aggiorna requirements.txt
L'ultima versione di Cloud Datastore che supporta Python 2 è la 1.15.3. Aggiorna requirements.txt con l'ultima versione per Python 3 (potrebbe essere più recente). Al momento della stesura di questo tutorial, l'ultima versione era la 2.1.0, quindi modifica la riga in modo che sia simile a questa (o a qualsiasi altra versione più recente):
google-cloud-datastore==2.1.0
Semplifica app.yaml
PRIMA:
L'unica vera modifica per questa app di esempio è l'accorciamento significativo di app.yaml. Ecco un riepilogo di quanto avevamo in app.yaml al termine del modulo 3:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
DOPO:
In Python 3, le direttive threadsafe, api_version e libraries sono tutte deprecate; tutte le app sono considerate thread-safe e api_version non viene utilizzato in Python 3. Nei servizi App Engine non sono più preinstallati pacchetti di terze parti integrati, pertanto anche libraries è deprecato. Per ulteriori informazioni su queste modifiche, consulta la documentazione sulle modifiche apportate a app.yaml. Di conseguenza, devi eliminare tutti e tre da app.yaml e aggiornare a una versione di Python 3 supportata (vedi di seguito).
(Facoltativo) Utilizzo della direttiva handlers
Inoltre, è stata ritirata anche la direttiva handlers, che indirizza il traffico alle applicazioni App Engine. Poiché il runtime di nuova generazione prevede che i framework web gestiscano il routing delle app, tutti gli "script di gestione" devono essere modificati in "auto". Combinando le modifiche riportate sopra, si ottiene questo app.yaml:
runtime: python38
handlers:
- url: /.*
script: auto
Scopri di più su script: auto nella pagina di riferimento di app.yaml.
Rimozione dell'istruzione handlers
Poiché handlers è deprecato, puoi rimuovere anche l'intera sezione, lasciando un app.yaml su una sola riga:
runtime: python38
Per impostazione predefinita, verrà avviato il server web Gunicorn WSGI, disponibile per tutte le applicazioni. Se hai familiarità con gunicorn, questo è il comando eseguito quando viene avviato per impostazione predefinita con app.yaml:
gunicorn main:app --workers 2 -c /config/gunicorn.py
(Facoltativo) Utilizzo della direttiva entrypoint
Se, tuttavia, la tua applicazione richiede un comando di avvio specifico, questo può essere specificato con una direttiva entrypoint, che genera un app.yaml simile a questo:
runtime: python38
entrypoint: python main.py
Questo esempio richiede specificamente l'utilizzo del server di sviluppo Flask anziché gunicorn. Per l'avvio sull'interfaccia 0.0.0.0 sulla porta 8080, è necessario aggiungere all'app anche il codice che avvia il server di sviluppo, aggiungendo questa piccola sezione alla fine di main.py:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Scopri di più su entrypoint nella pagina di riferimento di app.yaml. Altri esempi e best practice sono disponibili nella documentazione sull'avvio dell'ambiente standard di App Engine e nella documentazione sull'avvio dell'ambiente flessibile di App Engine.
Elimina appengine_config.py e lib
Elimina il file appengine_config.py e la cartella lib. Durante la migrazione a Python 3, App Engine acquisisce e installa i pacchetti elencati in requirements.txt.
Il file di configurazione appengine_config.py viene utilizzato per riconoscere librerie/pacchetti di terze parti, sia che tu li abbia copiati personalmente sia che utilizzi quelli già disponibili sui server App Engine (integrati). Quando esegui la migrazione a Python 3, ecco un riepilogo delle modifiche principali:
- Nessun bundling delle librerie di terze parti copiate (elencate in
requirements.txt) - Nessun
pip installin una cartellalib, il che significa nessuna cartellalib - Nessuna libreria di terze parti integrata nella scheda in
app.yaml - Non è necessario fare riferimento all'app per le librerie di terze parti, quindi non è necessario il file
appengine_config.py
È sufficiente elencare tutte le librerie di terze parti richieste in requirements.txt.
Esegui il deployment di un'applicazione
Esegui di nuovo il deployment dell'app per assicurarti che funzioni. Puoi anche verificare quanto la tua soluzione si avvicina al codice Python 3 di esempio del modulo 3. Per visualizzare le differenze con Python 2, confronta il codice con la sua versione Python 2.
Congratulazioni per aver completato il passaggio bonus del Modulo 3. Consulta la documentazione sulla preparazione dei file di configurazione per il runtime Python 3. Infine, rivedi il riepilogo precedente per i passaggi successivi e la pulizia.
Preparazione della tua richiesta
Quando sarà il momento di eseguire la migrazione della tua applicazione, dovrai trasferire main.py e altri file dell'applicazione alla versione 3.x, pertanto una best practice è cercare di rendere la tua applicazione 2.x il più "compatibile con le versioni successive" possibile.
Esistono molte risorse online per aiutarti a raggiungere questo obiettivo, ma alcuni dei suggerimenti chiave sono:
- Assicurati che tutte le dipendenze dell'applicazione siano completamente compatibili con la versione 3.x
- Assicurati che la tua applicazione venga eseguita almeno su Python 2.6 (preferibilmente 2.7)
- Assicurati che l'applicazione superi l'intera suite di test (e una copertura minima dell'80%).
- Utilizza librerie di compatibilità come
six, Future e/o Modernize - Informati sulle principali differenze tra le versioni 2.x e 3.x non compatibili con le versioni precedenti
- Qualsiasi I/O porterà probabilmente a incompatibilità tra stringhe Unicode e stringhe di byte
L'app di esempio è stata progettata tenendo conto di tutto questo, ecco perché funziona su 2.x e 3.x fin da subito, in modo da poterci concentrare su ciò che deve essere modificato per utilizzare la piattaforma di nuova generazione.
8. Risorse aggiuntive
Problemi/feedback relativi ai codelab del modulo di migrazione di App Engine
Se riscontri problemi con questo codelab, cerca prima il tuo problema prima di presentare una segnalazione. Link per cercare e creare nuovi problemi:
Risorse per la migrazione
I link alle cartelle del repository per il modulo 2 (INIZIO) e il modulo 3 (FINE) sono disponibili nella tabella riportata di seguito. Puoi accedervi anche dal repository per tutte le migrazioni di App Engine, che puoi clonare o scaricare come file ZIP.
Codelab | Python 2 | Python 3 |
Module 3 |
Risorse App Engine
Di seguito sono riportate risorse aggiuntive relative a questa migrazione specifica:
- Riferimenti a Python Cloud NDB e Cloud Datastore
- Migrazione a Python 3 e al runtime di nuova generazione di GAE
- Generale