HTTP(S)-Anfragen senden

Auf dieser Seite wird beschrieben, wie Sie in der App Engine-Anwendung HTTP(S)-Anfragen senden.

App Engine verwendet den URL-Abrufdienst, um ausgehende HTTP(S)-Anfragen zu senden. Weitere Informationen zu Größenbeschränkungen für Anfragen und dazu, welche Header in einer URL-Abrufanfrage gesendet werden, finden Sie unter Ausgehende Anfragen.

HTTP-Request senden

Verwenden Sie die Methode urlfetch.fetch, um ausgehende HTTP-Anfragen zu senden. Für eine bessere Codeübertragbarkeit können Sie auch die Python-Standardbibliotheken urllib, urllib2 oder httplib zum Senden von HTTP-Requests verwenden. Wenn Sie diese Bibliotheken in App Engine verwenden, führen sie HTTP-Requests mithilfe des URL-Abrufdiensts von App Engine aus. Sie können auch die requests-Drittanbieterbibliothek verwenden, wenn Sie sie für die Verwendung von URLFetch konfigurieren.

urlfetch

Die folgenden Snippets veranschaulichen, wie mithilfe von urlfetch eine grundlegende HTTP-GET-Anfrage ausgeführt wird: Importieren Sie zuerst die urlfetch-Bibliothek aus dem App Engine SDK:

from google.appengine.api import urlfetch

Verwenden Sie dann urlfetch, um den GET-Request auszuführen:

url = 'http://www.google.com/humans.txt'
try:
    result = urlfetch.fetch(url)
    if result.status_code == 200:
        self.response.write(result.content)
    else:
        self.response.status_code = result.status_code
except urlfetch.Error:
    logging.exception('Caught exception fetching url')

Das folgende Snippet veranschaulicht, wie mit urlfetch eine erweiterte Anfrage durchgeführt werden kann, bei dem Daten von einem Webformular über eine HTTP-POST-Anfrage gesendet werden:

try:
    form_data = urllib.urlencode(UrlPostHandler.form_fields)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    result = urlfetch.fetch(
        url='http://localhost:8080/submit_form',
        payload=form_data,
        method=urlfetch.POST,
        headers=headers)
    self.response.write(result.content)
except urlfetch.Error:
    logging.exception('Caught exception fetching url')

urllib2

Die folgenden Snippets veranschaulichen, wie mithilfe von urllib2 eine grundlegende HTTP-GET-Anfrage ausgeführt wird: Importieren Sie zuerst die Bibliothek urllib2:

import urllib2

Verwenden Sie dann urllib2, um den GET-Request auszuführen:

url = 'http://www.google.com/humans.txt'
try:
    result = urllib2.urlopen(url)
    self.response.write(result.read())
except urllib2.URLError:
    logging.exception('Caught exception fetching url')

Anfragen

Sie müssen mithilfe der Vendoring-Anleitung sowohl requests als auch requests-toolbelt installieren, um Anfragen zu nutzen.

Nach der Installation verwenden Sie das Modul requests_toolbelt.adapters.appengine, um Anfragen zur Verwendung von URLFetch zu konfigurieren:

import requests
import requests_toolbelt.adapters.appengine

# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt.adapters.appengine.monkeypatch()

Nach der Konfiguration können Sie Requests normal verwenden:

url = 'http://www.google.com/humans.txt'
response = requests.get(url)
response.raise_for_status()
return response.text

Weitere Informationen zur Unterstützung von Anfragen für Google App Engine finden Sie in der Dokumentation zu urllib3.contrib.appengine und requests_toolbelt.appengine.

Anfragezeitüberschreitung festlegen

Sie können die Standardfrist mit der Funktion urlfetch.set_default_fetch_deadline() anpassen. Diese Funktion speichert die neue Standardfrist in einer Thread-lokalen Variablen. Daher muss sie für jeden Request festgelegt werden, z. B. in einer benutzerdefinierten Middleware.

HTTPS-Request senden

Legen Sie den Parameter validate_certificate beim Aufrufen der Methode urlfetch.fetch() auf true fest, um einen HTTPS-Request zu senden.

Asynchrone Requests senden

HTTP(S)-Requests sind standardmäßig synchron. Für asynchrone Anfragen muss Ihre Anwendung folgende Vorgänge durchlaufen:

  1. Ein neues RPC-Objekt mit urlfetch.create_rpc() erstellen. Dieses Objekt repräsentiert in nachfolgenden Methodenaufrufen asynchrone Aufrufe.
  2. urlfetch.make_fetch_call() aufrufen, um die Anfrage auszuführen. Diese Methode nutzt das RPC-Objekt und die URL des Anfrageziels als Parameter.
  3. Die Methode get_result() des RPC-Objekts aufrufen. Diese Methode gibt das Ergebnisobjekt zurück, wenn die Anfrage erfolgreich war, und löst eine Ausnahme aus, wenn bei der Anfrage ein Fehler aufgetreten ist.

Die folgenden Snippets veranschaulichen die Ausführung einer einfachen asynchronen Anfrage aus einer Python-Anwendung. Importieren Sie zuerst die urlfetch-Bibliothek aus dem App Engine SDK:

from google.appengine.api import urlfetch

Als Nächstes verwenden Sie urlfetch zum Ausführen des asynchronen Requests:

rpc = urlfetch.create_rpc()
urlfetch.make_fetch_call(rpc, 'http://www.google.com/')

# ... do other things ...
try:
    result = rpc.get_result()
    if result.status_code == 200:
        text = result.content
        self.response.write(text)
    else:
        self.response.status_int = result.status_code
        self.response.write('URL returned status code {}'.format(
            result.status_code))
except urlfetch.DownloadError:
    self.response.status_int = 500
    self.response.write('Error fetching URL')

Anfragezeitüberschreitung festlegen

Zum Festlegen einer Zeitüberschreitung für den Request legen Sie beim Erstellen des RPC-Objekts den Parameter deadline der Methode urlfetch.create_rpc() fest.

Callback-Funktion verwenden

Sie können eine Callback-Funktion für das RPC-Objekt festlegen. Die Funktion wird aufgerufen, wenn Ihre Anwendung eine Methode für das Objekt aufruft – z. B. wait(), checksuccess() oder get_result() –, die bewirkt, dass das Objekt wartet, bis der Request abgeschlossen ist.

So verwenden Sie eine Callback-Funktion zur Verarbeitung des Ergebnisses Ihres Abrufaufrufs:

  1. Erstellen Sie eine Hilfsfunktion, um den Umfang des Callbacks festzulegen.
  2. Erstellen Sie eine Handler-Funktion, um das Ergebnis des Abrufaufrufs zu verarbeiten.
  3. Legen Sie das Attribut callback des RPC-Objekts auf die Hilfsfunktion fest.

Das folgende Snippet veranschaulicht das Aufrufen einer Callback-Funktion:

def handle_result(rpc):
    result = rpc.get_result()
    self.response.write(result.content)
    logging.info('Handling RPC in callback: result {}'.format(result))

urls = ['http://www.google.com',
        'http://www.github.com',
        'http://www.travis-ci.org']
rpcs = []
for url in urls:
    rpc = urlfetch.create_rpc()
    rpc.callback = functools.partial(handle_result, rpc)
    urlfetch.make_fetch_call(rpc, url)
    rpcs.append(rpc)

# ... do other things ...

# Finish all RPCs, and let callbacks process the results.

for rpc in rpcs:
    rpc.wait()

logging.info('Done waiting for RPCs')

Requests an andere App Engine-Anwendungen senden

Wenn Sie eine Anfrage an eine andere App Engine-Anwendung senden, muss die Identität dieser Anwendung bestätigt werden. Dazu fügen Sie der Anfrage den Header X-Appengine-Inbound-Appid hinzu. Wenn Sie den URL-Abrufdienst so konfigurieren, dass er keiner Weiterleitung folgt, fügt App Engine diesen Header automatisch zu Anfragen hinzu.

Legen Sie den Parameter follow_redirects der Methode fetch auf False fest, damit der URL-Abrufdienst keinen Weiterleitungen folgt

Weitere Informationen

Unter Ausgehende Anfragen finden Sie weitere Informationen zum URL-Abrufdienst, z. B. zu den Headern, die in einer URL-Abrufanfrage gesendet werden.