Auf dieser Seite wird beschrieben, wie gebündelte Legacy-Dienste mit der Python 3-Laufzeit für die Standardumgebung installiert und verwendet werden. Ihre Anwendung muss über das App Engine Services SDK für Python 3 auf die gebündelten Dienste zugreifen.
Hinweise
- Weitere Informationen finden Sie in der Liste der gebündelten Legacy-Dienst-APIs, die Sie in der Python-Laufzeit aufrufen können.
- Lesen Sie vor dem Starten eines Migrationsprojekts zu Python 3 die Übersicht über die Laufzeitmigration und die Überlegungen zur Migration bei der Verwendung von gebündelten Legacy-Diensten.
App Engine Services SDK installieren
So installieren Sie das App Engine Services SDK:
Fügen Sie Ihrer App das SDK hinzu, indem Sie der Datei
requirements.txt
Folgendes hinzufügen:appengine-python-standard>=1.0.0
Sie finden das SDK auf GitHub im Repository
appengine-python-standard
und unter PyPI.Fügen Sie Ihrem Haupt-Python-Skript den folgenden Code hinzu. Dieser Code erstellt WSGI-Middleware, mit der die für die Aktivierung Ihrer API-Aufrufe erforderlichen Variablen festgelegt werden.
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)
Pyramide
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)
Fügen Sie die folgende Zeile Ihrer
app.yaml
hinzu, bevor Sie die Anwendung bereitstellen:app_engine_apis: true
Verwenden Sie zum Bereitstellen der Anwendung den Befehl
gcloud app deploy
.
Hinweise zur Migration
Beachten Sie die folgenden Überlegungen, wenn Sie zur Python 3-Laufzeit migrieren und Ihre Anwendung gebündelte Legacy-Dienste verwendet.
Test
Verwenden Sie den lokalen Entwicklungsserver, um die Legacy-Funktionen für gebündelte Dienste lokal in Ihrer Python 3-Anwendung zu testen.
Wenn Sie den Befehl dev_appserver.py
ausführen, müssen Sie das Argument --runtime_python_path
so festlegen, dass ein Pfad zum Python 3-Interpreter enthalten ist.
Beispiel:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path=/usr/bin/python3
Sie können das Argument auch auf eine durch Kommas getrennte Liste an [RUNTIME_ID]=[PYTHON_INTERPRETER_PATH]
-Paaren festlegen. Beispiel:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path="python27=/user/bin/python2.7,python3=/usr/bin/python3"
Pickle-Kompatibilität
Freigegebene Dienste, einschließlich Memcache, Cloud NDB und Deffered, verwenden das Modul Pickle, um Python-Objekte zu serialisieren und freizugeben. Wenn Ihre App Engine-Umgebung sowohl Python 2 als auch Python 3 verwendet, was während einer Migration üblich ist, müssen Sie dafür sorgen, dass freigegebene serialisierte Objekte, die von einer Version von Python geschrieben wurden, von der anderen rekonstruiert werden können. Weitere Informationen zur Implementierung der Kompatibilität mit verschiedenen Pickle-Versionen finden Sie in der Anleitung.
Standardmäßig verwendet Python 3 Pickling-Protokolle, die in Python 2 nicht unterstützt werden.
Dies kann zu Fehlern führen, wenn Ihre Anwendung versucht, ein Python-Objekt in einer Python 2-Umgebung zu rekonstruieren, die in einer Python 3-Umgebung geschrieben wurde.
Um dieses Problem zu vermeiden, legen Sie in der app.yaml
-Datei folgende Umgebungsvariablen für Ihre Python 3-Anwendung nach Bedarf fest:
- Legen Sie für Anwendungen, die Memcache verwenden, einschließlich Anwendungen, die NDB verwenden, Folgendes fest:
MEMCACHE_USE_CROSS_COMPATIBLE_PROTOCOL: 'True'
- Legen Sie für Anwendungen, die NDB für die Verbindung zu Datastore verwenden, Folgendes fest:
NDB_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
- Legen Sie für Anwendungen, die Deferred verwenden, Folgendes fest:
DEFERRED_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
In Python 2 enthalten string
-Objekte eine Sequenz von 8-Bit-Bytewerten. In Python 3 enthalten string
-Objekte eine Sequenz an Unicode-Zeichen. Standardmäßig Pickle-übersetzt Python 3 ein Python 2-string
in Unicode, wobei Python 3 string
als ASCII interpretiert wird. Dies kann zu Fehlern bei Werten außerhalb des ASCII-Zeichenbereichs von 0 bis 127 führen. Memcache unterstützt das Überschreiben dieser Standardzuordnung.
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))
Die latin1
-Codierung definiert eine Zuordnung für jeden der 256 möglichen Werte jedes Byte in einem Python 2-string
. Dadurch werden Decodierungsfehler verhindert. Wenn Ihr Python 2-string
jedoch tatsächliche Unicode-Daten außerhalb des latin1
-Bereichs enthält, z. B. Daten, die aus einer Datei gelesen werden, ordnet cPickle die Daten nicht korrekt zu. Daher ist es wichtig, dass Sie Ihren Python 2-Code aktualisieren, um Unicode-Daten mit unicode
-Objekten und nicht mit string
-Objekten für von Ihnen ausgewählte Objekte zu speichern. Der Kompatibilitätsleitfaden enthält Details zu den erforderlichen Updates.
Die zuvor beschriebene Methode zum Aktualisieren des Python 2-Codes zum Erstellen von Python 3-kompatiblen Serialisierungen bezieht sich auf kurzlebige Serialisierungen, z. B. die in Memcache gespeicherten. Möglicherweise müssen Sie langlebige Python 2-Serialisierungen aktualisieren oder neu schreiben, z. B. diejenigen, die im Rahmen Ihrer Migration in Datastore gespeichert sind. Beispiel: Serialisierungen, die mit google.appengine.ext.ndb.model.PickleProperty
geschrieben wurden, erfordern möglicherweise ein Upgrade.
Weitere Informationen zu Einschränkungen und weniger häufigen Problemen finden Sie im Leitfaden zur Kompatibilität.
Web-Frameworks
webapp2
ist in Python 3 nicht gebündelt oder wird nicht unterstützt. Daher muss jede Anwendung neu geschrieben werden, um ein WSGI-kompatibles Framework wie Flask zu nutzen.
Es wird empfohlen, zuerst die Verwendung vonwebapp2
in Ihrer Python 2.7-Anwendung mit Flask (oder einem anderen Web-Framework wieDjango, Pyramid, Bottle oderweb.py) zu ersetzen, während Sie noch Python 2.7 verwenden.
Wenn die aktualisierte Anwendung stabil ist, migrieren Sie den Code zu Python 3 und stellen Sie die Anwendung mit App Engine für Python 3 bereit.
Beispiele für die Konvertierung von Python 2.7-Anwendungen, die webapp2
für die Verwendung des Flask-Frameworks verwenden, finden Sie in diesen zusätzlichen Ressourcen.
Handler verwenden
Einer Python 3-Anwendung kann nur ein Skript zugeordnet sein. Wenn Ihre app.yaml
also mehrere script
-Handler enthält, die URLs verschiedenen Skripts zuordnen, müssen Sie diese Skripts in einem Skript zusammenfassen, das URL-Routing verwendet.
Im folgenden Beispiel werden die Handler-Unterschiede in der Datei app.yaml
für die entsprechenden Laufzeiten dargestellt.
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
Ihre Python 3-Anwendung muss URL-Routing verarbeiten (beispielsweise mit Flask-Decorators).
Wenn Sie mehrere script
-Handler mit unterschiedlichen URL-Mustern oder andere Attribute in Ihren Handlern verwenden möchten, muss jeder Handler script: auto
angeben.
Sie können das Standardstartverhalten auch überschreiben. Geben Sie dazu in der Datei app.yaml
das Feld entrypoint
an.
Weitere Informationen zur Verwendung bestimmter Handler finden Sie in den Übersichten Blobstore, Deferred und Mail.
Threadsicherheit
Es wird davon ausgegangen, dass Apps threadsicher sind. API-Aufrufe müssen im Anfrage-Thread erfolgen. Wenn Sie beim Start der Anwendung eine Legacy-Bundle-Dienst-API verwenden, kann dies zu Sicherheitsfehlern führen.
Weitere Informationen finden Sie unter Sicherheitsfehler bei der Verwendung von gebündelten Legacy-Diensten für Python.
URL Fetch verwenden
Wenn Sie URL Fetch für Python verwenden möchten, müssen Sie die URL-Abrufbibliothek explizit aufrufen.
Wenn Ihre Python 3-Anwendung die URL Fetch API verwendet, wird der Anfrageheader X-Appengine-Inbound-Appid
hinzugefügt, wenn Ihre App eine Anfrage an eine andere App Engine-Anwendung sendet. Dies ermöglicht der empfangenden Anwendung, die Identität der aufrufenden Anwendung zu überprüfen. Weitere Informationen finden Sie unter Ausgehende Anfragen migrieren.
Beispiel (App Engine ndb
)
Nachfolgend sehen Sie eine einfache Python 2-App, die Seitenbesuche mit App Engine ndb
für den Zugriff auf Datastore registriert. Ihr Gegenstück ist eine Python 3 äquivalente Anwendung, bei der die Verwendung von webapp2
durch Flask ersetzt wurde und die oben beschriebenen notwendigen Änderungen für den Zugriff auf gebündelte Dienste in Python 3 implementiert wurden.
Python 2 (webapp2
)
Python 3 (Flask)
Beide Anwendungen finden Sie im Open-Source-Repository für den Python App Engine-Migrationsinhalt (Codebeispiele, Videos, codelabs), insbesondere in den Ordnern mod0
bzw. mod1b
.