Questa pagina descrive come installare e utilizzare i servizi in bundle legacy con il runtime Python 3 per l'ambiente standard. La tua app deve accedere ai servizi in bundle tramite l'SDK dei servizi App Engine per Python 3.
Prima di iniziare
- Consulta l'elenco delle API dei servizi in bundle legacy che puoi chiamare nel runtime Python 3.
- Prima di avviare un progetto di migrazione a Python 3, consulta la panoramica della migrazione in fase di runtime e le considerazioni sulla migrazione quando utilizzi servizi in bundle legacy.
Installazione dell'SDK dei servizi App Engine
Per installare l'SDK dei servizi App Engine, segui questi passaggi:
Includi l'SDK con la tua app aggiungendo la seguente riga al tuo file
requirements.txt
:appengine-python-standard>=1.0.0
Puoi trovare l'SDK su GitHub nel repository
appengine-python-standard
e su PyPI.Aggiungi il seguente codice nello script Python principale. Questo codice crea un middleware WSGI che imposta le variabili necessarie per abilitare le chiamate API.
Flask
from flask import Flask from google.appengine.api import wrap_wsgi_app app = Flask(__name__) app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
Django
from DJANGO_PROJECT_NAME.wsgi import application from google.appengine.api import wrap_wsgi_app app = wrap_wsgi_app(application)
Piramide
from pyramid.config import Configurator from google.appengine.api import wrap_wsgi_app config = Configurator() # make configuration settings app = config.make_wsgi_app() app = wrap_wsgi_app(app)
WSGI
import google.appengine.api def app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield b'Hello world!\n' app = google.appengine.api.wrap_wsgi_app(app)
Aggiungi la seguente riga al tuo file
app.yaml
prima di eseguire il deployment dell'app:app_engine_apis: true
Per eseguire il deployment della tua app, utilizza il comando
gcloud app deploy
.
Considerazioni sulla migrazione
Devi tenere presente le seguenti considerazioni se esegui la migrazione al runtime Python 3 e la tua app utilizza i servizi in bundle legacy.
Test
Per testare localmente la funzionalità dei servizi in bundle legacy nella tua app Python 3, utilizza il server di sviluppo locale.
Quando esegui il comando dev_appserver.py
, devi impostare l'argomento --runtime_python_path
per includere un percorso per l'interprete Python 3.
Ad esempio:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path=/usr/bin/python3
Puoi anche impostare l'argomento su un elenco separato da virgole di
coppie [RUNTIME_ID]=[PYTHON_INTERPRETER_PATH]
. Ad esempio:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path="python27=/user/bin/python2.7,python3=/usr/bin/python3"
Compatibilità con Pickle
I servizi condivisi, tra cui Memcache, Cloud NDB e rinviati, utilizzano il modulo pickle per serializzare e condividere gli oggetti Python. Se il tuo ambiente App Engine utilizza sia Python 2 sia Python 3, cosa comune durante la migrazione, devi assicurarti che gli oggetti serializzati condivisi scritti da una versione di Python possano essere ricostituiti dall'altra. Puoi trovare indicazioni sull'implementazione della compatibilità Pickle tra più versioni nella guida.
Per impostazione predefinita, Python 3 utilizza protocolli di pickling non supportati in Python 2.
Ciò può causare errori quando la tua app tenta di ricostituire un oggetto Python in un ambiente Python 2 scritto in un ambiente Python 3.
Per evitare questo problema, imposta le seguenti
variabili di ambiente
nel file app.yaml
per l'app Python 3 in base alle tue esigenze:
- Per le app che utilizzano Memcache, incluse quelle che utilizzano NDB, imposta:
MEMCACHE_USE_CROSS_COMPATIBLE_PROTOCOL: 'True'
- Per le app che utilizzano NDB per la connessione a Datastore, imposta:
NDB_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
- Per le app che utilizzano l'impostazione differita, imposta:
DEFERRED_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
In Python 2, gli oggetti string
contengono una sequenza di valori di byte a 8 bit. In Python 3, gli oggetti string
contengono una sequenza di caratteri Unicode. Per impostazione predefinita, Python 3
traduce un codice Python 2 string
in unicode interpretando Python 3
string
come ASCII. Questo può causare errori per i valori al di fuori dell'intervallo di caratteri ASCII compreso tra 0 e 127. Memcache supporta l'override di questo mapping predefinito.
from google.appengine.api import memcache
import six.moves.cPickle as pickle
def _unpickle_factory(file):
return pickle.Unpickler(file, encoding='latin1')
memcache.setup_client(memcache.Client(unpickler=_unpickle_factory))
La codifica latin1
definisce una mappatura per ciascuno dei 256 possibili valori di
ogni byte in un codice Python 2 string
. In questo modo si evitano errori di decodifica. Tuttavia, se
il codice Python 2 string
contiene dati Unicode effettivi al di fuori dell'intervallo latin1
, come quelli letti da un file, cChoosele non mapperà i dati
in modo corretto. Di conseguenza, è importante aggiornare il codice Python 2 in modo da contenere i dati Unicode con oggetti unicode
e non string
per gli oggetti selezionati. La guida alla compatibilità include dettagli sugli aggiornamenti necessari.
Il metodo descritto in precedenza per aggiornare il codice Python 2 in modo da produrre serializzazioni compatibili con Python 3, sia per gli indirizzi di serializzazioni a breve durata, come quelle archiviate in memcache. Potresti dover aggiornare o riscrivere le serializzazioni Python 2 di lunga durata, come quelle archiviate in Datastore nell'ambito della migrazione. Ad esempio, la serializzazione scritta utilizzando google.appengine.ext.ndb.model.PickleProperty
potrebbe richiedere un upgrade.
Consulta la guida alla compatibilità per scoprire di più sulle limitazioni e sui problemi meno comuni.
framework web
webapp2
non è in bundle o supportato in Python 3, quindi le applicazioni devono essere riscritte per utilizzare qualsiasi framework compatibile con WSGI (ad esempio Flask).
Una strategia di migrazione consigliata è quella di sostituire prima l'utilizzo di webapp2
nell'app Python 2.7 con Flask (o un framework web alternativo come Django, Pyramid, Bottle o web.py), continuando a usare Python 2.7.
Poi, quando l'app aggiornata è stabile, esegui la migrazione del codice in Python 3 ed esegui il deployment e il test utilizzando App Engine per Python 3.
Per esempi su come convertire le app Python 2.7 che usano webapp2
per usare il framework Flask, puoi fare riferimento a queste risorse aggiuntive.
Utilizzo dei gestori
Un'app Python 3 può avere un solo script associato, quindi se app.yaml
ha più gestori script
che mappano URL a script diversi, dovrai combinare questi script in uno che gestisca il routing degli URL.
L'esempio seguente mostra le differenze di gestore nel file app.yaml
per i rispettivi runtime.
Python 2
runtime: python27 api_version: 1 threadsafe: true handlers: - url: / script: home.app - url: /index\.html script: home.app - url: /stylesheets static_dir: stylesheets - url: /(.*\.(gif|png|jpg))$ static_files: static/\1 upload: static/.*\.(gif|png|jpg)$ - url: /admin/.* script: admin.app login: admin - url: /.* script: not_found.app
Python 3
runtime: python312
app_engine_apis: true
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /(.*\.(gif|png|jpg))$
static_files: static/\1
upload: static/.*\.(gif|png|jpg)$
- url: /admin/.*
script: auto
login: admin
L'app Python 3 deve gestire il routing degli URL (ad esempio con i decoratori Flask).
Se vuoi utilizzare più gestori script
con pattern URL diversi o
se vuoi utilizzare altri attributi nei tuoi gestori, ogni gestore deve
specificare script: auto
.
Puoi anche ignorare il comportamento predefinito all'avvio specificando un campo entrypoint
nel file app.yaml
.
Consulta le panoramiche Blobstore, Rinviato e Posta per ulteriori informazioni su come utilizzare gestori specifici.
Sicurezza dei thread
Si presume che le app siano sicure in thread. Le chiamate API devono essere effettuate nel thread di richiesta. Se utilizzi un'API dei servizi in bundle legacy all'avvio dell'app, potrebbero verificarsi errori di sicurezza.
Per scoprire di più, consulta Errori di sicurezza quando si utilizzano servizi in bundle legacy per Python.
Utilizzo del recupero degli URL
Per utilizzare il recupero URL per Python 3, devi chiamare esplicitamente la libreria di recupero URL.
Se la tua app Python 3 utilizza l'API URL Fetch, l'intestazione della richiesta X-Appengine-Inbound-Appid
viene aggiunta quando l'app invia una richiesta a un'altra app App Engine. In questo modo l'app ricevente può verificare l'identità dell'app chiamante. Per scoprire di più, consulta Migrazione delle richieste in uscita.
Esempio (App Engine ndb
)
Di seguito è riportata un'app Python 2 di base che registra le visite alle pagine utilizzando l'elemento ndb
di App Engine per accedere a Datastore. La sua companion è un'app equivalente a Python 3 in cui l'utilizzo di webapp2
è stato sostituito da Flask e le modifiche necessarie descritte in precedenza per accedere ai servizi in bundle in Python 3 sono state implementate.
Python 2 (webapp2
)
Python 3 (Flask)
Entrambe queste app sono disponibili nel repository
open source per i contenuti di migrazione
di Python App Engine (esempi di codice,
video,
codelab), in particolare nelle cartelle mod0
e mod1b
, rispettivamente.