2013-06-25 144 views
109

我有一個RESTful API,我使用EC2實例上的Elasticsearch實現來公開內容的語料庫。我可以通過運行查詢搜索從我的終端(MacOSX的)以下:使用python向RESTful API發出請求

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/requestspython/urllib2一個API請求(不知道該在哪一個 - 已使用的urllib2,但聽說請求更好......)?作爲標題或其他方式傳遞嗎?

回答

179

使用requests

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.textresponse.json()(或可能檢查response.status_code第一)。請參閱快速入門文檔here,尤其是this section

+3

我認爲,它應該是:response = requests.post(url,data = data) –

+4

「requests.get」不帶「data」參數。它可以採用可選的「params」參數,它通常是一個攜帶查詢字符串的字典。如果需要有效負載來獲取數據(例如發佈的示例),則需要使用「requests.post」。另外使用「json」庫可以更輕鬆地解析json響應。 – HVS

+2

它可以用python 3嗎? –

55

使用requestsjson使其變得簡單。

  1. 調用API
  2. 假設API返回一個JSON,解析JSON對象到使用json.loads功能
  3. 循環遍歷字典來提取信息的 Python的字典。

Requests模塊爲您提供了有用的功能來循環成功和失敗。

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

Last迭代關鍵字的部分不會總是有效,因爲JSON文檔可能會將數組作爲頂級元素。所以,如果它是一個數組,那麼嘗試獲取'jData [key]' –

+0

@DenisTheMenace將會是一個錯誤,我將如何循環它? – qasimalbaqali

+0

@qasimalbaqali就像循環字典一樣。但是數組元素只是'jData',而不是'jData [key]' –

8

所以你想在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() 

您可以檢查出使用要求在[http://stackandqueue.com/?p=75]

+0

在那裏得到了一個死鏈接 – user3157940

0

下面更多的呼叫是在Python執行REST 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) 
相關問題