HTTP(S) リクエストの発行

このページでは、App Engine アプリから HTTP(S) リクエストを発行する方法について説明します。

App Engine は、URL 取得サービスを使用して、送信 HTTP(S) リクエストを発行します。リクエストのサイズ上限と URL 取得リクエストで送信されるヘッダーの詳細については、送信リクエストをご覧ください。

HTTP リクエストの発行

送信 HTTP リクエストを発行するには、urlfetch.fetch メソッドを使用します。コードの移植性を向上させるため、Python 標準ライブラリ urlliburllib2 または httplib を使用して HTTP リクエストを発行します。これらのライブラリを App Engine で使用すると、App Engine の URL 取得サービスを使用して HTTP リクエストが実行されます。URLFetch を使用するように構成すると、サードパーティの requests ライブラリも使用できます。

urlfetch

以下のスニペットでは、urlfetch を使用して基本的な HTTP GET リクエストを実行します。最初に、App Engine SDK から urlfetch ライブラリをインポートします。

from google.appengine.api import urlfetch

次に、urlfetch を使用して GET リクエストを実行します。

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')

以下のスニペットでは、より高度なリクエストを実行します。urlfetch を使用して、HTTP POST リクエストでウェブフォームからデータを送信します。

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

以下のスニペットでは、urllib2 を使用して基本的な HTTP GET リクエストを実行します。まず、urllib2 ライブラリをインポートします。

import urllib2

次に、urllib2 を使用して GET リクエストを実行します。

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')

リクエスト

リクエストを使用するには、ベンダリングの手順に沿って requestsrequests-toolbelt の両方をインストールする必要があります。

インストールされたら、requests_toolbelt.adapters.appengine モジュールで URLFetch を使用するようにリクエストを構成します。

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()

構成すると、通常どおりリクエストを使用できます。

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

リクエストの Google App Engine のサポートについては、urllib3.contrib.appenginerequests_toolbelt.appengine のドキュメントをご覧ください。

リクエストのタイムアウトの設定

urlfetch.set_default_fetch_deadline() 関数を使用すると、デフォルトの期限を調整できます。この関数は、スレッド ローカルの変数に新しいデフォルトの期限を保存します。たとえば、カスタム ミドルウェアでは、この変数をリクエストごとに設定する必要があります。

HTTPS リクエストの発行

HTTPS リクエストを発行するには、urlfetch.fetch() メソッドを呼び出すときに validate_certificate パラメータを true に設定します。

非同期リクエストの発行

HTTP(S) リクエストはデフォルトで同期されます。非同期リクエストを発行するには、アプリケーションで次の処理を行う必要があります。

  1. urlfetch.create_rpc() を使用して、新しい RPC オブジェクトを作成します。このオブジェクトは、後続のメソッド呼び出しでの非同期呼び出しを表します。
  2. urlfetch.make_fetch_call() を呼び出し、リクエストを行います。このメソッドは、RPC オブジェクトとリクエストのターゲット URL をパラメータとして取得します。
  3. RPC オブジェクトの get_result() メソッドを呼び出します。リクエストに成功すると、このメソッドは結果オブジェクトを返します。リクエスト中にエラーが発生した場合には、例外が発生します。

以下のスニペットでは、Python アプリケーションから基本的な非同期リクエストを行います。最初に、App Engine SDK から urlfetch ライブラリをインポートします。

from google.appengine.api import urlfetch

次に、urlfetch を使用して非同期リクエストを行います。

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')

リクエストのタイムアウトの設定

リクエストのタイムアウトを設定するには、RPC オブジェクトを作成するときに、urlfetch.create_rpc() メソッドの deadline パラメータを設定します。

コールバック関数の使用

RPC オブジェクトにコールバック関数を定義します。アプリケーションがオブジェクトのメソッド(wait()checksuccess()get_result() など)を呼び出すと、関数が呼び出されます。このオブジェクトは、リクエストが完了するまで待機します。

フェッチ呼び出しの結果を処理するコールバック関数を使用するには:

  1. コールバックのスコープを定義するヘルパー関数を作成します。
  2. フェッチ呼び出しの結果を処理するハンドラ関数を作成します。
  3. RPC オブジェクトの callback 属性にヘルパー関数を設定します。

以下のスニペットでは、コールバック関数を呼び出します。

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')

別の App Engine アプリへのリクエストの発行

別の App Engine アプリにリクエストを発行する場合、App Engine アプリでリクエストに X-Appengine-Inbound-Appid ヘッダーを追加して、その ID を表明する必要があります。URL 取得サービスにリダイレクトに従わないように指示した場合、App Engine によって、自動的にこのヘッダーがリクエストに追加されます。

リダイレクトしないように URL 取得サービスに指示するには、fetch メソッドの follow_redirects パラメータを False に設定します。

次のステップ

送信リクエスト内の URL 取得リクエストで送信されるヘッダーなど、URL 取得サービスについて学習します。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Python の App Engine スタンダード環境