PythonでHTTPリクエストを送信する5つの方法

October 12, 2021
執筆者
レビュー担当者
Mia Adjei
Twilion

PythonでHTTPリクエストを送信する5つの方法

この記事はAugust Allardこちらで公開した記事(英語)を日本語化したものです。

ソフトウェア開発では、同じ結果を得るための方法が複数あることがよくあります。これは、サードパーティーのソフトウェアパッケージを評価する際にも同じことが言えます。例えば、Pythonのエコシステムでは、HTTP リクエストの送信に関連するパッケージがいくつもあります。開発者はどれを使えばいいのでしょうか?

この実験ベースのチュートリアルでは、Pythonの最も人気のあるリクエスト関連パッケージを5つご紹介します。各パッケージの簡単なGETリクエストを作成する方法と簡単なコードスニペットを例示します。NASAのAstronomy Photo of the Day API(以降「APOD」と短縮)を使って、Webブラウザで宇宙の写真を表示させます。

本稿の目標は、各パッケージのすべての機能を細かく比較対照するのではなく、様々なPythonパッケージを使って簡単なGETリクエストを素早く構成することです。もし非同期リクエストがあなたのユースケースにより適しているなら、Twilioブログの「aiohttpとasyncioを使用したPythonの非同期HTTPリクエスト」を参照してください。

必要事項

NASAのデモ用APIキーを取得する

https://api.nasa.gov/に移動します。認証セクションに、NASAデータセットを検索するために固有のAPIキーが必要ないことが記載されています。もしAPIキーを作成したい場合は、ウェブページの指示に従って、今回使用するデモ用キーの代わりに、取得したAPIキーを使用してください。

デモ用APIキーのレート制限は、同ウェブページのDEMO_KEY Rate Limitsにあるように、1時間あたり30リクエスト、1日あたり50リクエストとなっています。本稿でご紹介する方法であれば、この制限内に十分に収まるはずです。NASAのウェブページでは、実際のAPIキー値の代わりに「DEMO_KEY」という文字列を使用できることが記載されています。本稿ではこの「DEMO_KEY」を使用します。

APOD APIのURLエンドポイントを確認する

HTTPリクエストを送信するURLはhttps://api.nasa.gov/planetary/apodです。NASA APIウェブサイトBrowse APIsセクションまでスクロールして、APODドロップダウンメニューを開くと確認できます。

apod

APODドロップダウンメニューに表示される簡単な情報を読むと、このエンドポイントはGETメソッドのみを受け付けることがわかります。このため、本稿でご紹介する5つのHTTPリクエストの送信方法では、GETリクエストのみを取り扱います。

Pythonの仮想環境を作成する

任意の場所にpython-http/ディレクトリを作成し、移動します。この例では、MacBookのデスクトップを使用し、コマンドラインからディレクトリを作成することにします。

$ cd ~/Desktop
$ mkdir python-http
$ cd python-http 

プロジェクト用に新しい仮想環境を作成し、インストールする必要のある依存関係が、あなたのコンピュータのグローバル設定に干渉しないようにします。envという新しい環境を作成するために、コマンドラインで以下のコマンドを実行します。

$ python3 -m venv env 
$ source env/bin/activate  

仮想環境を構築すると、コマンドプロンプトの入力行が環境の名前である「env」で始まっているのがわかると思います。Pythonによってpython-http/ディレクトリにenv/という新しいフォルダが作成されました。これはコマンドプロンプトでlsコマンドを実行すると確認できます。

python-http/ディレクトリに、.gitignoreファイルを作成します。Macでコマンドラインを使用してファイルを作成する場合は、以下のようなコマンドになります。

(env) $ touch .gitignore 

お好みのテキストエディタで.gitignoreファイルを開き、.gitignore ファイルにenv/フォルダを追加してください。ここで、次のセクションで作成する .env ファイル用の行も追加しておきます。

env/
.env 

Pythonが作成する仮想環境用のenv/フォルダは、APIキーや環境変数などの秘密を保存するために作成される.envファイルとは別物であることに注意しましょう。

環境変数を安全に保存する

APIキーは機密情報であり、保護されるべきものです。したがって、APIキーをアプリケーションにハードコードするのではなく、環境変数として保存することがベストプラクティスと考えられています。NASAのデモAPIキーの値(「DEMO_KEY」)は公開されていますが、このベストプラクティスに従うことにします。

これを行うには、APIキーを .envファイルに保存し、.envファイルを.gitignore ファイルに追加して(これは上記ですでに行いました)、gitがファイルを追跡しないようにすればよいのです。.envファイルは、オペレーティングシステムが利用できるようにする必要がある環境変数があるときに使用されます。

まず、.envファイルを作成します。Macのコマンドラインで実行するには、以下のコマンドを使用します。

(env) $ touch .env

次に、.envファイルをお好みのテキストエディタで開き、以下のコードを追加してください。

export NASA_API_KEY=DEMO_KEY

.envファイルをソースして、オペレーティングシステムで利用できるようにし、環境変数の値をコンソールに表示して、ソースに成功したことを確認します。

(env) $ source .env
(env) $ echo $NASA_API_KEY 

Pythonの依存関係をインストールする

Python標準ライブラリに含まれるurllibモジュールの他に、ご紹介するサードパーティ製のPythonパッケージは以下の通りです。

  • Requests - Python を使ってリクエストするための最も人気のあるパッケージです。
  • urllib3 - Python標準ライブラリの一つであるurllibと混同しないでください。
  • httplib2 - 他のライブラリではない仕様が提供されています。
  • httpx - HTTP/2と非同期リクエストを提供する、より新しいパッケージです。

Pythonプロジェクトに必要な依存関係は、通常requirements.txtと呼ばれるファイルに記載されています。python-http/プロジェクトディレクトリに requirements.txtファイルを作成します。

(env) $ touch requirements.txt

以下のPythonパッケージのリストをコピーして、お好きなテキストエディタでrequirements.txtファイルに貼り付けてください。

requests
urllib3
httplib2
httpx  

仮想環境(「env」)がまだソースされていることを確認しながら、以下のコマンドですべての依存関係をインストールします。

(env) $ pip install -r requirements.txt

Pythonファイルを作成する

コードを書いていきます。まず、これから試すモジュールやパッケージごとにPythonファイルを作成しましょう。

(env) $ touch use_requests.py
(env) $ touch use_urllib3.py
(env) $ touch use_httplib2.py
(env) $ touch use_httpx.py
(env) $ touch use_urllib.py

作成した5種類のファイルそれぞれについて、コード例を以下に示します。また、プロジェクト全体はこのGitHubリポジトリで確認できます。

コード例をもう少し堅牢で便利にするために、jsonwebbrowserという2つの組み込みPythonモジュールを使って、宇宙の写真をウェブブラウザで開けるように作業します。

PythonでHTTPリクエストを行う5つの一般的な方法を探る

Requestsライブラリ

PythonのRequestsパッケージはとても人気があり、現在100万以上のGitHubリポジトリで必要要件として指定されており、そのコードベースには何年にもわたって600人近くの貢献者がいます!このパッケージの明確で簡潔なドキュメントが普及に貢献していることは間違いありません。

以下のコードスニペットをコピーして、use_requests.pyファイルに貼り付けてください。

import json
import os
import webbrowser

import requests


nasa_api_key = os.environ.get('NASA_API_KEY')
api_url = 'https://api.nasa.gov/planetary/apod?api_key={}'.format(nasa_api_key)

def use_requests(api_url):

    response = requests.get(api_url)
    json_response = json.loads(response.text)
    photo_url = json_response['url']
    webbrowser.open_new_tab(photo_url)

    return

use_requests(api_url)

上記のサンプルコードでは、まず必要なモジュールとパッケージをすべてインポートしています。次に、.envファイルに保存したAPIキーを取得し(8行目)、GETリクエストを送信するURLに追加しています(9行目)。13行目でRequestsライブラリを使用しています。構文がいかにシンプルであるかがわかります。APIのレスポンスから写真のURLを取得した後、16行目で写真をウェブブラウザで開いています。

ファイルの一番下に関数の呼び出しが含まれているので、このファイルを実行すると、写真が自動的にウェブブラウザで開かれるはずです。コマンドラインでこのファイルを実行し、ご自身で試してみてください。

(env) $ python3 use_requests.py

urllib3

名前は似ていますが、urllib3 はサードパーティ製のパッケージで、Python標準ライブラリの一部であるurllibとは全く別のものです。GitHubの65万以上のリポジトリでurllib3が要件として挙げられており、Requestsライブラリに代わるものとして非常に人気があります。

以下のコードスニペットをコピーして、use_urllib3.pyファイルに貼り付けてください。

import json
import os
import webbrowser

import urllib3


nasa_api_key = os.environ.get('NASA_API_KEY')
api_url = 'https://api.nasa.gov/planetary/apod?api_key={}'.format(nasa_api_key)

def use_urllib3(api_url):

    http = urllib3.PoolManager()
    response = http.request('GET', api_url)
    json_response = json.loads(response.data)
    photo_url = json_response['url']
    webbrowser.open_new_tab(photo_url)

    return

use_urllib3(api_url)

上記のサンプルコードでは、まず必要なモジュールとパッケージをすべてインポートしています。次に、.envファイルに保存した APIキーを取得し(8行目)、GETリクエストを送信するURLに追加しています(9行目)。13行目と14行目では、urllib3パッケージを使用して、写真のURLを抽出し、Webブラウザに表示するための処理を行っています。

ファイルの末尾に関数の呼び出しが含まれているので、このファイルを実行して動作を確認できます。

ヒント: ファイルを実行しようとしているときに、[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificateエラーが発生したら、 こちらのStackOverflowの投稿の手順で解決してください。

(env) $ python3 use_urllib3.py

httplib2

httplib2パッケージは 86,000のGitHubリポジトリで使用されています。httplib2の使用量はRequestsやurllib3パッケージに比べて少ないですが、httplib2は他のパッケージにはない仕様を揃えています。例えば、httplib2は持続的な接続とキャッシュをサポートしています。

ここでは、あなたのプロジェクトでどのようにhttplib2を使用するかの簡単な例を示します。次のコードをコピーしてuse_httplib2.pyに貼り付けてください。

import json
import os
import webbrowser

import httplib2


nasa_api_key = os.environ.get('NASA_API_KEY')
api_url = 'https://api.nasa.gov/planetary/apod?api_key={}'.format(nasa_api_key)

def use_httplib2(api_url):

    http = httplib2.Http()

    # The response is sent as a 2-item tuple, with the content at index 1
    response = http.request(api_url)
    json_response = json.loads(response[1])
    photo_url = json_response['url']
    webbrowser.open_new_tab(photo_url)

    return

use_httplib2(api_url)

上記のサンプルコードでは、まず必要なモジュールとパッケージをすべてインポートしています。次に、.envファイルに保存したAPIキーを取得し(8行目)、それをGETリクエストを送信するURLに追加しています(9行目)。13行目と16行目では、httplib2パッケージを使用して、写真のURLを抽出し、ウェブブラウザに表示するための処理を行っています。

ファイルの末尾に関数呼び出しが含まれているので、このファイルを実行して動作を確認できます。

(env) $ python3 use_httplib2.py

httpx

httpx Pythonパッケージは、ご紹介するパッケージの中では最も新しいものです。標準的な同期型のHTTP/1プロトコルに加え、HTTP/2プロトコル非同期型リクエストをサポートしています。これは非常にRequestsに似た仕様で作られており、Requestsパッケージに存在するコードパターンの多くを反映しています。

httpxを試してみるには、以下のコードをuse_httpx.pyファイルにコピー&ペーストしてください。

import json
import os
import webbrowser

import httpx


nasa_api_key = os.environ.get('NASA_API_KEY')
api_url = 'https://api.nasa.gov/planetary/apod?api_key={}'.format(nasa_api_key)

def use_httpx(api_url):

    request = httpx.get(api_url)
    json_request = request.json()
    photo_url = json_request['url']
    webbrowser.open_new_tab(photo_url)

    return

use_httpx(api_url)

上記のサンプルコードでは、まず必要なモジュールとパッケージをすべてインポートしています。次に、.envファイルに保存したAPIキーを取得し(8行目)、それをGETリクエストを送信するURLに追加しています(9行目)。13行目でhttpxライブラリを使用していますが、いかにシンプルな構文であるかがわかると思います。APIのレスポンスから写真のURLを分離した後、16行目でWebブラウザで写真を開いています。

ファイルの一番下に関数の呼び出しが含まれているので、このファイルを実行すると、写真が自動的にウェブブラウザで開かれるはずです。CLIでこのファイルを実行し、ご自身で試してみてください。

(env) $ python3 use_httpx.py

urllib

RequestsパッケージでHTTPリクエストを構築することが簡単なのに比べて、Pythonの組み込みのurllibモジュールを使うのは少し複雑です。このチュートリアルのパッケージの1つを使用する場合、コンテキストマネージャの使用とレスポンスのデコードが必要になります。

以下のサンプルコードをコピーして、use_urllib.pyファイルに貼り付けてください。

import json
import os
import urllib.request
import webbrowser


nasa_api_key = os.environ.get('NASA_API_KEY')
api_url = 'https://api.nasa.gov/planetary/apod?api_key={}'.format(nasa_api_key)

def use_urllib(api_url):

    request = urllib.request.Request(api_url)
    with urllib.request.urlopen(request) as response:
        data = json.loads(response.read().decode("utf-8"))
        photo_url = data['url']
        webbrowser.open_new_tab(photo_url)

    return

use_urllib(api_url)

上記のサンプルコードでは、まず必要なモジュールとパッケージをすべてインポートしています。次に、.envファイルに保存したAPI キーを取得し(7行目)、GETリクエストを送信するURLに挿入しています(8行目)。12行目でurllibモジュールを使ってRequestオブジェクトを作成し、13行目でコンテキストマネージャー(with…)を使ってAPODエンドポイントにリクエストを送信してレスポンスを保存しています。14行目でレスポンスをデコードしてJSONに変換し、15行目と16行目で写真のURLを抽出してブラウザで開いています。

ファイルの末尾に関数呼び出しが含まれているので、このファイルを実行して動作を確認できます。

(env) $ python3 use_urllib.py

お疲れ様でした!

本稿では、以下の方法をご紹介しました。

  • APIキーなどのシークレットを.envファイルに安全に保存する
  • APIエンドポイントに5つの方法でGETリクエストを送信する
  • PythonスクリプトからWebブラウザで画像を開く

次のステップ

Pythonを使って5つの方法でHTTPリクエストを行う方法を学べたところで、次のステップとして以下のプロジェクトに取り掛かってみるのはいかがでしょうか?

  • PyPiに掲載されている他のHTTP関連リクエスト関連のパッケージも試してみる。
  • 本稿で使用した各パッケージの長所と短所をさらに詳しく調べて比較してみる。
  • 本稿で取り上げたパッケージの中から一つを選び、ドキュメントを参照しながらキャッシュを使用するような、より洗練されたタイプのHTTPリクエストを作成する。
  • 本稿で取り上げた方法に対応したAPIでPOST、PUT、DELETEリクエストを試してみる。

また、Twilioブログの記事から、次のプロジェクトのアイディアを探してみてください。

オーガストは、TwilioDeveloper Voicesチームのテクニカルコンテンツ担当ソフトウェアエンジニアで、Pythonを専門としています。Raspberry Piと本物のパイ、そして森の中を散歩するのが大好きです