2013-06-25 150 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) 
相关问题