Edited at

Python Requestsモジュールについて

[参照]

Pythonプロフェッショナルプログラミング第2版


Requests:HTTP for Humans

http://docs.python-requests.org/en/latest


RESTとは

RESTはソフトウェアアーキテクチャーのひとつ。

ソフトウェアの設計原則の集合。

「REST」「REST API」という単語は、「HTTP」上で動作するSOAPやRPCではないAPI」の意味で使われることが多い。


REST APIの特徴


  • HTTP上で動作する

  • データはリソースと呼ばれる

  • REST APIで使用可能なリソースは、一意なURLを持っている。

  • GET/POST/PUT/DELETEなどのHTTPメソッドはそれぞれ、取得/保存/上書き/削除などのリソースの操作と対応している。

  • JSONやXMLなどのフォーマットでデータを送受信する

  • リクエストの成功や失敗などの処理結果はステータスコードで表す

REST APIを使用するには、HTTPクライアントを利用する。

・シェル上のコマンドやシェルスクリプトではcurlを使う。

・プログラム中から使用する場合はHTTPクライアントライブラリを使う。

https://ja.wikipedia.org/wiki/REST



以下の説明内容のまとめ

1.Requestsの導入

2.テスト用サーバーの導入(httpbinのテスト)

3.リクエスト

 •3-1 GETリクエストの送信

 •3-2 POSTリクエストの送信

 •3-3 JSON形式でPOSTリクエストを送信する

 •3-4 GET/POST以外のHTTPメソッドの使用



1.Requestsの導入

pipコマンドを使用する。


$ pip install requests


2.テスト用サーバーの導入

・Requestsモジュールの動作を試すにはWebサーバーが必要。


httpbin

※httpbinというモジュールを使用する場合


$ pip install httpbin


$ python -m httpbin.core

*Running on http://127.0.0.1:5000

※Requestsモジュールから使用する前に、テストサーバーの動作をcurlコマンドで確認してみる。

※テストサーバーを起動した状態で、次のコマンドを実行する。

※正常に動作していれば、JSON形式のレスポンスが表示される。


$ curl "http://127.0.0.1:5000/get?foo=bar" #GETリクエストをテストサーバーに送信

{
"args":{ #argsはGETパラメータ
"foo":"bar"
},
"headers":{
"Accept":"*/*",
"Content-Length:"",
"
Content-Type": "",
"
Host": "127.0.0.1:5000",
"
User-Agent": "curl/7.35.0"
},
"
origin":"127.0.0.1",
"
url": "http://127.0.0.1:5000"/get?foo=bar"
}

$ curl -x post -d foo=bar http://127.0.0.1:5000/post #postリクエストをテスト サーバーに送信
{
"args":{},
"data":"", #dataは送信データの本文
"files":{},
"form":{ #formはフォームエンコードされたパラメータ
"foo":"bar"
},
"headers":{
"Accept":"*/*,
"
Content-Length":"7",
"
Content-Type":"application/x-www-form-urlencoded",
"
Host":"127.0.0.1:5000",
"
User-Agent": "curl/7.35.0"
},
"
json":null,
"
origin":"127.0.0.1",
"
url":"http://127.0.0.1:5000/post"
}

テストサーバーは、リクエストした内容をJSON形式で返してくれる。


3.リクエスト


3-1.GETリクエストの送信

Requestsを使用してGETリクエストを送信する


# coding utf-8
import pprint
import requests

def main():
#GETパラメータはparams引数に辞書で指定する

response = requests.get(
'http://127.0.0.1:5000/get',
params={'foo': 'bar'})
#レスポンスオブジェクトのjsonメソッドを使うと、
#JSONデータをPythonの辞書オブジェクトを変換して取得できる。
pprint.pprint(response.json())

if __name__== '__main__':
main()

requests.get関数に対象のURLとparamsキーワード引数でGETパラメーターを指定する。

サーバーからのレスポンスはJSON形式なので、jsonメソッドで辞書に変換してから画面に表示する。

ソースコードを実行すると次のような結果になる。


$ python requests_get.py

{u'args':{u'foo':u'bar'},
u'headers': {u'Accept':u'*/*',
u'Accept-Encoding': u'gzip,deflate',
u'Connection':u'keep-alive',
u'Content-Length': u'',
u'Content-Type': u'',
u'Host': u'127.0.0.1:5000',
u'User-Agent' : u'python-requests/2.5.0 CPython/2.7.8 Linux/3.13.0-35-generic'},
u'origin' : u'127.0.0.1',
u'url' : u'http://127.0.0.1:5000/get?foo=bar'}


3-2.POSTリクエストの送信

Requestsを使用してPOSTリクエストを送信するコード


# coding: utf-8
import pprint
import requests

def main():
#POSTパラメータは二つ目の引数に辞書で指定する
response = requests.post(
'http://127.0.0.1:5000/post',
{'foo':'bar'})
#レスポンスオブジェクトのjsonメソッドを使うと、
#JSONデータをPythonの辞書オブジェクトに変換して取得できる
pprint.pprint(response.json())

if __name__=='__main__':
   main()

requests.post関数に対象のURLとPOSTパラメータを指定している。POSTパラメータに辞書を指定すると、URLエンコードされてから送信される。

このソースコードを実行すると次のような結果になる。


$python requests_post.py

{u'args':{},
u''data': u'',
u'data': u'',
u'files':{}
u'form':{u'foo' u'bar'},
u'headers':{u'Accept': u'*/*',
u'Accept-Encoding': u'gzip, deflate',
u'Connection':u'keep-alive',
u'Content-Length': u'7',
u'Content-Type': u'application/x-www-form-urlencoded',
u'Host': u'127.0.0.1:5000',
u'User-Agent': u'python-requests/2.5.0 CPython/2.7.8 Linux/3.13.0-35-generic'},
u'json': None,
u'origin': u'127.0.0.1',
u'url': u'http://127.0.0.1:5000/post'}


3-3.JSON形式でPOSTリクエストを送信する

APIインターフェイスによっては、送信するデータをURLエンコードではなくJSON形式の文字列で要求するものがある。

RequestsでJSON形式の文字列をPOSTリクエストで送信するコードは以下にようになる。


requests_post_json.py


import pprint
import json
import requests

def main()
response = requests.post(
'http://127.0.0.1:5000/post',
json.dumps({'foo':'bar'}),
headers={'Content-Type': 'application/json'})
pprint.pprint(response.json())

if __name__=='__main__':
main()


※json.dumpsで生成した文字列を指定すると、URLエンコードされずにそのままデータが送信される。

※Content-Typeを明示的に指定する必要がある。

※post関数の引数に送信するデータを文字列で指定している。

※文字列を指定した場合、URLエンコードされず送信される。

上記のソースコードを実行すると次の結果となる。

$python requests_post_json.py

{u'args}:{},
u'data': u'{"foo": "bar"} ',
u'files': {},
u'form': {},
u'headers':{u'Accept': u'*/*,
u''Accept-Encoding': u'gzip, deflate',
u'Connection': u'keep-alive',
u'Content-Length': u'14',
u'Content-Type': u'application/json',
u'Host': u'127.0.0.1:5000',
u''User-Agent': u'python-requests/2.5.0 CPython/2.7.8 Linux/3.13.0-35-generic'},
u'json':{u'foo': u'bar'},
u'origin': u'127.0.0.1',
u'url': u'http://127.0.0.1:5000/post'}


3-4.GET/POST以外のHTTPメソッドの使用

APIによってはGET,POST以外のHTTPメソッド(PUT、DELETE、HEAD、OPTIONS)を要求するものがある。

RequestsではGETやPOSTと同様に、これらのメソッドに対応する関数が用意されている。


# coding: utf-8
import requests

def main():
requests.put('http://127.0.0.1:5000/put',{'foo': 'bar'}) #put
requests.delete('http://127.0.0.1:5000/delete') #delete
requests.head('http://127.0.0.1:5000/get') #HEAD
requests.options('http://127.0.0.1:5000/options') #OPTIONS

if __name__ == '__main__':
main()

上記のソースコードは実行すると、

HTTPのPUT、DELETE、HEAD、OPTIONSメソッドのリクエストをサーバーへ送信し、

レスポンスを取得したら終了する。