Making a request to a RESTful API using python Making a request to a RESTful API using python python python

Making a request to a RESTful API using python


Using requests:

import requestsurl = '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)

Depending on what kind of response your API returns, you will then probably want to look at response.text or response.json() (or possibly inspect response.status_code first). See the quickstart docs here, especially this section.


Using requests and json makes it simple.

  1. Call the API
  2. Assuming the API returns a JSON, parse the JSON object into aPython dict using json.loads function
  3. Loop through the dict to extract information.

Requests module provides you useful function to loop for success and failure.

if(Response.ok): will help help you determine if your API call is successful (Response code - 200)

Response.raise_for_status() will help you fetch the http code that is returned from the API.

Below is a sample code for making such API calls. Also can be found in github. The code assumes that the API makes use of digest authentication. You can either skip this or use other appropriate authentication modules to authenticate the client invoking the API.

#Python 2.7.6#RestfulClient.pyimport requestsfrom requests.auth import HTTPDigestAuthimport json# Replace with the correct URLurl = "http://api_url"# It is a good practice not to hardcode the credentials. So ask the user to enter credentials at runtimemyResponse = 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()


So you want to pass data in body of a GET request, better would be to do it in POST call. You can achieve this by using both Requests.

Raw Request

GET http://ES_search_demo.com/document/record/_search?pretty=true HTTP/1.1Host: ES_search_demo.comContent-Length: 183User-Agent: python-requests/2.9.0Connection: keep-aliveAccept: */*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": {}}

Sample call with Requests

import requestsdef 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 paramsresponse = requests.get(url,data = data)print "code:"+ str(response.status_code)print "******************"print "headers:"+ str(response.headers)print "******************"print "content:"+ str(response.text)consumeGETRequestSync()