Regions-ID
REGION_ID
ist ein abgekürzter Code, den Google anhand der Region zuweist, die Sie beim Erstellen Ihrer Anwendung ausgewählt haben. Der Code bezieht sich nicht auf ein Land oder eine Provinz, auch wenn einige Regions-IDs häufig verwendeten Länder- und Provinzcodes ähneln können. Bei Anwendungen, die nach Februar 2020 erstellt wurden, ist REGION_ID.r
in den App Engine-URLs enthalten. Bei Anwendungen, die vor diesem Datum erstellt wurden, ist die Regions-ID in der URL optional.
Die Remote API-Bibliothek ermöglicht jedem Python-Client den Zugriff auf Dienste, die für App Engine-Anwendungen verfügbar sind.
Wenn Ihre App Engine-Anwendung beispielsweise Datastore oder Google Cloud Storage verwendet, kann ein Python-Client mithilfe der Remote API auf diese Speicherressourcen zugreifen.
Sie können die Remote API verwenden, um über eine Anwendung, die auf Ihrem lokalen Computer ausgeführt wird, oder über eine lokale interaktive Remote API-Shell auf den Datenspeicher Ihrer Anwendung zuzugreifen. Die Remote API interagiert mit tatsächlichen Diensten, daher verbraucht dieser Zugriff Teile Ihres Kontingents und nutzt kostenpflichtige Ressourcen.
Remote API-Zugriff in einer Anwendung aktivieren
Am einfachsten aktivieren Sie die Remote API über die Anweisung builtins
in der Datei app.yaml
Ihrer Anwendung. In dieser Datei ist die Standard-URL /_ah/remote_api/
angegeben. Sie können in derselben Datei aber auch die Anweisung url
verwenden, um eine andere URL anzugeben.
builtin
Die Anweisung builtins
in der Datei app.yaml
stellt die Remote API unter der Standard-URL /_ah/remote_api
bereit:
URL
Mit der Anweisung url
in app.yaml
können Sie eine andere URL für die Verwendung mit der Remote API angeben:
- url: /some-URL/*
script: google.appengine.ext.remote_api.handler.application
Stellen Sie Ihre Anwendung in App Engine bereit, nachdem Sie diese Änderung vorgenommen haben.
Remote API-Shell verwenden
Das Python SDK enthält eine Remote API-Shell, mit der Sie Python-Befehle in App Engine-Diensten aufrufen können, die von Ihrer Anwendung verwendet werden. Sie müssen keine zusätzliche Authentifizierung bereitstellen, da automatisch dieselben Anmeldedaten verwendet werden, die Sie zum Hochladen der Anwendung in App Engine verwendet haben.
So starten Sie die Remote API-Shell:
Rufen Sie den folgenden Befehl in einem Terminalfenster auf Ihrem lokalen Computer auf:
SDK-INSTALL-DIRECTORY/remote_api_shell.py -s YOUR-PROJECT-ID.
REGION_ID.r.appspot.com
Ersetzen Sie
[SDK-INSTALL-DIRECTORY]
durch den Pfad zum App Engine SDK für Python und[YOUR-PROJECT-ID]
durch Ihre Projekt-ID.Rufen Sie in der angezeigten interaktiven Shell die Python-Befehle auf, die Sie ausführen möchten. Wenn Ihre Anwendung beispielsweise Datastore verwendet, können Sie die folgende ndb-Abfrage aufrufen, um 10 Datensätze abzurufen:
>>> from google.appengine.ext import ndb >>> >>> # Fetch 10 keys from the datastore >>> ndb.Query().fetch(10, keys_only=True)
Remote API in einem lokalen Client verwenden
Sie können die Remote API auch in lokalen Anwendungen verwenden, um auf Dienste zuzugreifen, die von Ihrer Anwendung in App Engine verwendet werden.
So verwenden Sie die Remote API in einer lokalen Anwendung:
Exportieren Sie die Umgebungsvariable
PYTHONPATH
für Ihr Python-Verzeichnis. Beispiel:export PYTHONPATH=/usr/somedir/v3/bin/python2.7
Ersetzen Sie diesen Pfad durch die tatsächlichen Werte für Ihren Python-Speicherort.
Fügen Sie das App Engine SDK für den Python-Speicherort zu
PYTHONPATH
hinzu:export GAE_SDK_ROOT="/usr/local/home/mydir/google_appengine" export PYTHONPATH=${GAE_SDK_ROOT}:${PYTHONPATH}
Ersetzen Sie den oben angezeigten SDK-Pfad durch den tatsächlichen Pfad zum App Engine SDK.
Importieren Sie
dev_appserver
in Ihren Clientcode und rufen Siedev_appserver.fix_sys_path()
auf, um dafür zu sorgen, dass alle SDK-Module für App Engine ordnungsgemäß importiert werden:Fügen Sie Ihrer Anwendung den folgenden
remote_api_stub
-Code hinzu. Achten Sie dabei darauf, dass Sie Ihre Projekt-ID in Ihrem Code übergeben:Wenn Sie für die Remote API nicht die Standard-URL
/_ah/remote_api
verwenden, müssen Sie den obigen Code so ändern, dass er der von Ihnen verwendeten URL entspricht. Die Definition und Dokumentation zuremote_api_stub.ConfigureRemoteApiForOAuth
finden Sie in der SDK-Datei[SDK-INSTALL-DIRECTORY]/google/appengine/ext/remote_api/remote_api_stub.py
.Fügen Sie alle erforderlichen App Engine-Importe und den Python-Code hinzu, um auf die gewünschten App Engine-Dienste zuzugreifen. Der folgende Beispielcode greift auf den Datenspeicher des Projekts zu:
Wenn Ihre Anwendung in App Engine bereitgestellt wurde, starten Sie Ihren Remote API-Client:
python your-client.py YOUR-PROJECT-ID
Ersetzen Sie
your-client.py
durch Ihr Client-Modul undYOUR-PROJECT-ID
durch Ihre Projekt-ID. Dies setzt voraus, dass Ihr Client entsprechend dem Beispielcodeclient.py
die Projekt-ID als Eingabe für die Befehlszeile akzeptiert.
Beschränkungen und Best Practices
Bei dem Modul „remote_api“ wurde großer Wert darauf gelegt, dass es sich nach Möglichkeit genau so wie der native App Engine-Datenspeicher verhält. In einigen Fällen führt dies allerdings zu einer geringeren Effizienz. Bei der Verwendung von remote_api müssen einige Punkte berücksichtigt werden:
Umlauf bei jeder Datenspeicher-Anforderung
Da Sie über HTTP auf den Datenspeicher zugreifen, sind der Aufwand und die Latenz etwas höher als beim lokalen Zugriff. Zur Erhöhung der Geschwindigkeit und zur Verringerung der Last sollten Sie versuchen, die Anzahl der durchgeführten Umläufe zu begrenzen, indem Sie „get“- und „put“-Anforderungen als Stapelvorgänge ausführen und Entitäten stapelweise aus den Abfragen abrufen. Dies hilft nicht nur bei der Verwendung von remote_api, sondern auch bei der Verwendung des Datenspeichers im Allgemeinen, da ein Batchvorgang nur als einzelner Datenspeichervorgang betrachtet wird. Beispielsweise können Sie anstatt
for key in keys:
rec = key.get()
rec.foo = bar
rec.put()
Folgendes verwenden:
records = ndb.get_multi(keys)
for rec in records:
rec.foo = bar
ndb.put_multi(records)
Beide Beispiele haben dieselbe Wirkung, bei letzterem sind jedoch nur insgesamt zwei Round-Trips erforderlich, während beim ersteren zwei Round-Trips für jede Entität benötigt werden.
Quotenverbrauch für "remote_api"-Anfragen
Da remote_api über HTTP ausgeführt wird, führt jeder ausgeführte Datenspeicheraufruf neben der Verwendung des erwarteten Datenspeicher-Kontingents zu einer Kontingentverwendung eingehender und ausgehender Byte für HTTP-Anforderungen. Beachten Sie dies, wenn Sie remote_api für Bulk-Updates verwenden.
1-MB-Obergrenze für API
Wie bei der nativen Ausführung gilt auch hier die 1-MB-Obergrenze für API-Anforderungen und -Antworten. Bei besonders großen Entitäten müssen Sie möglicherweise die jeweils abgerufenen oder abgelegten Daten begrenzen, um unter dieser Obergrenze zu bleiben. Diese Vorgabe steht leider im Widerspruch zu der Reduzierung der Umläufe. Daher sollten die Batches jeweils so groß gewählt werden, wie es möglich ist, ohne die Größenbeschränkungen für Anforderung oder Antwort zu überschreiten. Bei den meisten Entitäten ist dies jedoch vermutlich kein Problem.
Iteration über Abfragen vermeiden
Ein häufiges Muster beim Datenspeicherzugriff sieht so aus:
q = MyModel.query()
for entity in q:
# Do something with entity
Dabei ruft das SDK Entitäten aus dem Datenspeicher in Stapeln zu je 20 ab. Es wird jeweils ein neuer Stapel abgerufen, wenn die bestehenden verbraucht wurden. Da jeder Stapel von remote_api in einer separaten Anforderung abgerufen werden muss, kann hierbei nicht dieselbe Effizienz erreicht werden. Stattdessen führt remote_api für jeden Stapel eine völlig neue Abfrage aus und verwendet dabei die Offset-Funktion, um zu weiteren Ergebnissen vorzudringen.
Wenn Sie wissen, wie viele Entitäten Sie benötigen, können Sie den gesamten Abruf in einer einzigen Anforderung durchführen, indem Sie die benötigte Anzahl anfordern:
entities = MyModel.query().fetch(100)
for entity in entities:
# Do something with entity
Wenn Sie nicht wissen, wie viele Entitäten Sie benötigen, können Sie Cursors verwenden, um große Ergebnismengen effizient zu iterieren. Dadurch können Sie gleichzeitig die Obergrenze von 1.000 Entitäten umgehen, die für normale Datenspeicherabfragen gilt.
Geringere Effizienz bei Transaktionen
Zum Implementieren von Transaktionen über remote_api werden Informationen zu den in der Transaktion abgerufenen Entitäten sowie Kopien der Entitäten, die in der Transaktion abgelegt oder gelöscht wurden, angesammelt. Wenn die Transaktion in einem Commit-Vorgang übergeben wird, werden alle diese Informationen an den App Engine-Server gesendet. Dort müssen erneut alle Entitäten, die in der Transaktion verwendet wurden, abgerufen werden, es muss überprüft werden, dass sie nicht geändert wurden, und dann müssen alle Änderungen, die in der Transaktion vorgenommen wurden, abgelegt und gelöscht werden und schließlich muss ein Commit-Vorgang durchgeführt werden. Bei einem Konflikt macht der Server die Transaktion rückgängig und benachrichtigt die Client-Seite, die dann den Vorgang noch einmal von vorne beginnen muss.
Diese Vorgehensweise funktioniert und dupliziert die von den Transaktionen bereitgestellten Funktionen exakt im lokalen Datenspeicher, ist jedoch ziemlich ineffizient. Wenn nötig, sollten Sie unbedingt Transaktionen verwenden. Versuchen Sie jedoch zugunsten der Effizienz die Anzahl und Komplexität der ausgeführten Transaktionen möglichst gering zu halten.