In questa pagina viene descritto come installare e utilizzare i servizi in bundle legacy con il runtime Python 3 per dell'ambiente standard. L'app deve accedere ai servizi in bundle tramite l'SDK dei servizi App Engine per Python 3.
Prima di iniziare
- Consulta l'elenco di API dei servizi in bundle legacy puoi chiamare il runtime Python.
- Prima di iniziare un progetto di migrazione a Python 3, consulta la panoramica della migrazione del runtime e le considerazioni sulla migrazione quando utilizzi i servizi in bundle precedenti.
Installazione dell'SDK dei servizi App Engine
Per installare l'SDK dei servizi App Engine, segui questi passaggi:
Includi l'SDK nella tua app aggiungendo la seguente riga al file
requirements.txt
:appengine-python-standard>=1.0.0
Puoi trovare l'SDK su GitHub nella
appengine-python-standard
repository e su PyPI.Aggiungi il seguente codice nello script Python principale. Questo codice crea WSGI middleware 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 a
app.yaml
prima di eseguire il deployment dell'app:app_engine_apis: true
Per eseguire il deployment della tua app, utilizza
gcloud app deploy
.
Considerazioni sulla migrazione
Se esegui la migrazione a un'istanza, tieni presente quanto segue il runtime Python 3 e la tua app utilizza in bundle legacy.
Test
Per testare localmente la funzionalità dei servizi in bundle legacy nel tuo
nell'app Python 3, utilizza
server di sviluppo locale.
Quando esegui il comando dev_appserver.py
, devi impostare l'argomento --runtime_python_path
in modo da 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
[RUNTIME_ID]=[PYTHON_INTERPRETER_PATH]
coppie. Ad esempio:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path="python27=/user/bin/python2.7,python3=/usr/bin/python3"
Compatibilità con i file pickle
I servizi condivisi, tra cui Memcache, Cloud NDB e deferred utilizzano il modulo pickle per serializzare e condividere oggetti Python. Se il tuo ambiente App Engine utilizza sia Python 2 che Python 3, comune durante una migrazione, devi assicurarti che gli oggetti serializzati condivisi scritti da una versione di Python possono essere ricostituito dall'altro. Puoi trovare indicazioni sull'implementazione di più versioni compatibilità con sottaceti .
Per impostazione predefinita, Python 3 utilizza protocolli di pickling che non sono supportati in Python 2.
Ciò può causare errori quando l'app tenta di ricostituire un oggetto Python
in un ambiente Python 2 scritto in un ambiente Python 3.
Per evitare questo problema, imposta quanto segue
variabili di ambiente
nel file app.yaml
dell'app Python 3 in base alle 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 connettersi a Datastore, imposta:
NDB_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
- Per le app che utilizzano la modalità differita, imposta:
DEFERRED_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
In Python 2, gli oggetti string
contengono una sequenza di valori byte a 8 bit. In Python
3, string
oggetti contengono una sequenza di caratteri Unicode. Per impostazione predefinita, Python 3
pickle traduce un string
di Python 2 in Unicode mediante l'interpretazione di Python 3
string
in formato ASCII. Questo può causare errori per i valori al di fuori del campo ASCII
un intervallo di caratteri compreso tra 0 e 127. Memcache supporta l'override di questa mappatura predefinita.
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 valori possibili di
ogni byte in un string
Python 2. In questo modo si evitano errori di decodifica. Tuttavia, se
il tuo string
Python 2 contiene dati Unicode effettivi al di fuori di latin1
ad esempio i dati letti da un file, cPickle non mapperà i dati
in modo corretto. Pertanto, è importante aggiornare il codice Python 2 in modo che
dati Unicode con unicode
oggetti e non string
oggetti, per gli oggetti
Sottaceto. La compatibilità
guide include dettagli su
gli aggiornamenti necessari.
Il metodo descritto in precedenza per aggiornare il codice Python 2 in modo da produrre serializzazioni compatibili con Python 3 si occupa delle serializzazioni di breve durata, come quelle memorizzate in Memcache. Potresti dover aggiornare o riscrivere il codice Python 2 di lunga durata.
serializzazioni, come quelle archiviate in Datastore come parte
migrazione. Ad esempio, 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 qualsiasi applicazione deve
essere riscritte per utilizzare qualsiasi framework compatibile con WSGI (come
Flask).
Una strategia di migrazione consigliata è quella di sostituire prima l'utilizzo di webapp2
in
l'app Python 2.7 con Flask (o un framework web alternativo come
Django
Pyramid
Bottiglia oppure
web.py), rimanendo su Python 2.7.
Quindi, quando l'app aggiornata è stabile, esegui la migrazione del codice a Python 3 e
eseguire il deployment e testare utilizzando App Engine per Python 3.
Per esempi di come convertire app Python 2.7 che utilizzano webapp2
per utilizzare il framework Flask, puoi fare riferimento
queste risorse aggiuntive.
Utilizzare i gestori
Un'app Python 3 può avere un solo script associato, quindi se il tuo
app.yaml
ha più gestori script
che mappano gli URL a script diversi,
dovrai combinare questi script in un unico script che gestisca il routing degli URL.
L'esempio seguente mostra le differenze relative ai gestori 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 Decoratori di Flask).
Se vuoi utilizzare più gestori script
con pattern URL diversi, oppure
se vuoi utilizzare altri attributi nei tuoi gestori, ogni gestore deve
specificare script: auto
.
Puoi anche ignorare il comportamento di avvio predefinito specificando un campo entrypoint
nel file app.yaml
.
Visita il Blobstore. Rinviato e Posta per ulteriori informazioni sull'utilizzo di gestori specifici.
Coerenza di thread
Si presume che le app siano sicure per i thread. Le chiamate API devono essere effettuate nella richiesta . Se utilizzi un'API dei servizi in bundle legacy quando l'app viene questo può causare errori di sicurezza.
Per saperne di più, consulta Errori di sicurezza quando si utilizzano servizi in bundle legacy per Python.
Utilizzo del recupero URL
Per utilizzare il metodo di recupero URL per Python, devi chiamare in modo esplicito il metodo nella 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 di destinazione può verificare l'identità dell'app chiamante. Per saperne di più, vedi
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 App Engine ndb
per
accedere a Datastore. L'altra app complementare è un'app equivalente Python 3 in cui webapp2
è stato sostituito da Flask e le modifiche richieste descritte sopra per
l'accesso ai servizi in bundle in Python 3 è stato implementato.
Python 2 (webapp2
)
Python 3 (Flask)
Entrambe queste app sono disponibili nell'open source
repo di comando
Contenuti sulla migrazione di App Engine (esempi di codice,
video,
codelabs), in particolare nella sezione mod0
e mod1b
cartelle.