Pythonを使用したRESTful APIへのリクエスト


221

EC2インスタンスでElasticsearchの実装を使用して公開したRESTful APIを使用して、コンテンツのコーパスにインデックスを付けました。端末(MacOSX)から次のコマンドを実行して、検索のクエリを実行できます。

curl -XGET 'http://ES_search_demo.com/document/record/_search?pretty=true' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'

上記を使用して、python/requestsまたはを使用してAPIリクエストに変換するにはどうすればよいですかpython/urllib2(どちらを使用するかわからない-urllib2を使用しているが、リクエストの方が優れていると聞いている...)?ヘッダーなどとして渡しますか?

回答:


340

リクエストの使用:

import requests
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
data = '''{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'''
response = requests.post(url, data=data)

APIが返す応答の種類に応じて、おそらく、response.textまたはresponse.json()(またはおそらくresponse.status_code最初に検査)する必要があります。クイックスタートのドキュメントを参照してくださいここでは、特にこのセクションを


3
私はそう思うはずです:response = requests.post(url、data = data)
CK.Nguyen

8
「requests.get」は「data」パラメータを取りません。これは、通常はクエリ文字列を運ぶdictであるオプションの「params」パラメータを取ることができます。データをフェッチするためにペイロードが必要な場合(問題の投稿の例など)、 "requests.post"を使用する必要があります。さらに、「json」ライブラリを使用すると、json応答の解析が容易になります。
HVS 2016年

4
@ParveenShukhala "リクエストは正式にPython 2.6–2.7および3.3–3.5をサポートし、PyPyで適切に実行されます。" - pypi.python.org/pypi/requests
ゼブラ

2
送信するのはJSONなので、次のようにデータではなくjsonパラメータを使用できます:response = requests.post(url、json = data)
Mark Chorley

101

リクエストjsonを使用すると簡単になります。

  1. APIを呼び出す
  2. APIがJSONを返すと仮定して、json.loads関数を使用してJSONオブジェクトをPython dictに解析します
  3. 辞書をループして情報を抽出します。

リクエストモジュールは、成功と失敗をループする便利な機能を提供します。

if(Response.ok):API呼び出しが成功したかどうかを判断するのに役立ちます(応答コード-200)

Response.raise_for_status() APIから返されるhttpコードを取得するのに役立ちます。

以下は、そのようなAPI呼び出しを行うためのサンプルコードです。また、中に見つけることができますgithubの。コードは、APIがダイジェスト認証を使用することを前提としています。これをスキップするか、他の適切な認証モジュールを使用して、APIを呼び出すクライアントを認証できます。

#Python 2.7.6
#RestfulClient.py

import requests
from requests.auth import HTTPDigestAuth
import json

# Replace with the correct URL
url = "http://api_url"

# It is a good practice not to hardcode the credentials. So ask the user to enter credentials at runtime
myResponse = requests.get(url,auth=HTTPDigestAuth(raw_input("username: "), raw_input("Password: ")), verify=True)
#print (myResponse.status_code)

# For successful API call, response code will be 200 (OK)
if(myResponse.ok):

    # Loading the response data into a dict variable
    # json.loads takes in only binary or string variables so using content to fetch binary content
    # Loads (Load String) takes a Json file and converts into python data structure (dict or list, depending on JSON)
    jData = json.loads(myResponse.content)

    print("The response contains {0} properties".format(len(jData)))
    print("\n")
    for key in jData:
        print key + " : " + jData[key]
else:
  # If response code is not ok (200), print the resulting http error code with description
    myResponse.raise_for_status()

2
JSONドキュメントには最上位の要素として配列が含まれている可能性があるため、キーを反復する最後の部分は常に機能するとは限りません。したがって、取得しようとするとエラーになりますjData[key]
Denis The Menace

@DenisTheMenace配列の場合、どのようにループできますか?
qasimalbaqali 2017年

@qasimalbaqaliは、辞書をループするのと同じ方法です。しかし、配列要素は単純jDataではなく、jData[key]
Denis The Menace '13年

:追記:あなたのAPIが大きいJSONレスポンスを返した場合、あなたはかなりこのようにそれを印刷することができます print(json.dumps(jData, indent=4, sort_keys=True))
マルコ

2
python3では、以下は 'JSONはバイトではなくstrでなければならない'と吐き出しました。これは、出力をデコードすることで修正されます。つまり、json.loads(myResponse.content.decode( 'utf-8'))。また、キーとjDataキーをstr()でラップして、RESTful APIが整数を返すときに文句を言わないようにする必要があります。
ミルクレス

11

したがって、GETリクエストの本文でデータを渡したい場合は、POST呼び出しで行う方が適切です。両方のリクエストを使用してこれを実現できます。

生のリクエスト

GET http://ES_search_demo.com/document/record/_search?pretty=true HTTP/1.1
Host: ES_search_demo.com
Content-Length: 183
User-Agent: python-requests/2.9.0
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate

{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

リクエストを使用したサンプルコール

import requests

def consumeGETRequestSync():
data = '{
  "query": {
    "bool": {
      "must": [
        {
          "text": {
            "record.document": "SOME_JOURNAL"
          }
        },
        {
          "text": {
            "record.articleTitle": "farmers"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}'
url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {"Accept": "application/json"}
# call get service with headers and params
response = requests.get(url,data = data)
print "code:"+ str(response.status_code)
print "******************"
print "headers:"+ str(response.headers)
print "******************"
print "content:"+ str(response.text)

consumeGETRequestSync()

デッドリンクがそこにありました
user3157940

4
headers変数を使用する必要があります。requests.get(... headers = headers、....)
Markus Meyer

9

以下は、Pythonで残りのAPIを実行するプログラムです。

import requests
url = 'https://url'
data = '{  "platform": {    "login": {      "userName": "name",      "password": "pwd"    }  } }'
response = requests.post(url, data=data,headers={"Content-Type": "application/json"})
print(response)
sid=response.json()['platform']['login']['sessionId']   //to extract the detail from response
print(response.text)
print(sid)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.