How to make a RESTful API call in Python

I have set up a RESTful API using Elasticsearch hosted on an EC2 instance to index various content. Currently, I can execute searches through the terminal on my Mac with the following command:

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": {}
}'

How can I convert this command into an API request using either the requests library or urllib2 in Python? I’m leaning towards requests but have primarily used urllib2; how should I structure the request, and should any specific headers be included?

You can convert your curl command to a Python API call using the requests library like this:

import requests

url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {'Content-Type': 'application/json'}
data = {
  "query": {
    "bool": {
      "must": [
        {"text": {"record.document": "SOME_JOURNAL"}},
        {"text": {"record.articleTitle": "farmers"}}
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

response = requests.get(url, headers=headers, json=data)

print(response.json())

Just make sure the requests library is installed by using pip install requests if needed.

Expanding on what CreatingStone has explained, using the requests library is indeed very practical and aligns well with most Python applications for making HTTP requests. Let me offer an alternative approach using the urllib library, which is sometimes preferred when you want to avoid additional dependencies:

import urllib.request
import json

url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {'Content-Type': 'application/json'}
data = {
  "query": {
    "bool": {
      "must": [
        {"text": {"record.document": "SOME_JOURNAL"}},
        {"text": {"record.articleTitle": "farmers"}}
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

# Convert dictionary to JSON string
json_data = json.dumps(data).encode('utf-8')

# Create a request object
request = urllib.request.Request(url, data=json_data, headers=headers, method='GET')

# Invoke the request
with urllib.request.urlopen(request) as response:
    result = response.read()
    print(json.loads(result))

In this version, note how we use json.dumps() to format the data into a JSON string that urllib can transmit properly. Also, make use of urllib.request.urlopen() to execute the request.

Though urllib doesn't require any additional installation, if your application is scalable, requests is generally recommended for better readability and more straightforward handling of responses and requests.

To create a RESTful API call using the requests library in Python, follow the steps below. The requests library is quite user-friendly and efficient for handling HTTP requests:

import requests

url = 'http://ES_search_demo.com/document/record/_search?pretty=true'
headers = {'Content-Type': 'application/json'}
data = {
  "query": {
    "bool": {
      "must": [
        {"text": {"record.document": "SOME_JOURNAL"}},
        {"text": {"record.articleTitle": "farmers"}}
      ],
      "must_not": [],
      "should": []
    }
  },
  "from": 0,
  "size": 50,
  "sort": [],
  "facets": {}
}

# Make the GET request
response = requests.get(url, headers=headers, json=data)

# Print formatted output
print(response.json())

To make sure the requests library is available, you may install it using:

pip install requests

This approach simplifies making HTTP requests and handling responses, perfect for tasks like connecting to your Elasticsearch API. If you're often dealing with REST APIs, requests should be your go-to library.