Bootstrap FreeKB - Python (Scripting) - POST request
Python (Scripting) - POST request

Updated:   |  Python (Scripting) articles

The requests module can be used to issue a REST API request.

Here is how you can make a POST request.

Notice in this example that json={"foo": "hello world"} is being used. This automatically set header "Content-Type": "application/json" and serializes the dictionary {"foo": "hello world"} into a JSON string. 

#!/usr/bin/python3
import requests

try:
  response = requests.post(
    "http://www.example.com/api", 
    json={"foo": "hello world"}
  )
except requests.exceptions.Timeout:
  print(f"POST request timed out")
except Exception as exception:
  print(f"requests.post raised the following exception: {exception}")
else:
  print("requests.post appears to have been successful")

 

Sometimes, you may want (or need to) instead use "data". Almost always, this is going to require that you set header "Content-Type": "application/json" and to also use json.dumps to convert the payload dictionary into a JSON string. It is also fairly common to include "Accept": "application/json" to let the API know that JSON is being used in the POST request.

#!/usr/bin/python3
import requests

url     = "http://www.example.com/api"
headers = { "Content-Type": "application/json" }
payload = {"foo": "hello world"}
data    = json.dumps(payload)

try:
  response = requests.post(url, headers=headers, data=data)
except requests.exceptions.Timeout:
  print(f"POST request timed out")
except Exception as exception:
  print(f"requests.post raised the following exception: {exception}")
else:
  print("requests.post appears to have been successful")

 

Perhaps this helps to visualize this, where we can see that "a" is a dictionary whereas "b" is a string.

#!/usr/bin/python
import json

a = {"foo": "hello world"}
b = json.dumps(a)

print(f"a type = {type(a)}")
print(f"b type = {type(b)}")

 

With this output.

a type = <class 'dict'>
b type = <class 'str'>

 

verify=False can be used to ignore SSL issues, such as when using a self-signed certificate. This is like using the --insecure flag in curl.

response = requests.post(url, json=payload, headers=headers, verify=False)

 

timeout can be used to specify how many seconds should elapse before the PUT request is timed out.

response = requests.put(url, json=payload, headers=headers, timeout=10)

 

Here is how you can include a username and password if basic authentication is required.

#!/usr/bin/python3
import requests

url     = "http://www.example.com/api"
payload = { "foo": "hello", "bar": "world" }
headers = { "Content-Type": "application/json" }
session = requests.Session()

try:
  session.auth = ("john.doe", "itsasecret")
except Exception as exception:
  print(f"session.auth raised the following exception: {exception}")
else:
  print("session.auth appears to have been successful")

try:
  response = session.post(url, data=payload, headers=headers)
except requests.exceptions.Timeout:
  print(f"POST request timed out")
except Exception as exception:
  print(f"session.post raised the following exception: {exception}")
else:
  print("session.post appears to have been successful")

 

There are a number of different objects that can be used to return useful information.

print(f"response             = {response}")
print(f"response.status_code = {response.status_code}")
print(f"response.ok          = {response.ok}")
print(f"response.content     = {response.content}")
print(f"response.text        = {response.text}")
print(f"response.json        = {response.json()}")
print(f"response.headers     = {response.headers}")

 

Since each API has it's own unique response, the response you get back will different between APIs. However, I typically expect to get some sort of response that let's me know if the request was successful or if it failed.

response             = <Response [200]>
response.status_code = 200
response.ok          = True
response.content     = {"result":{"success":true}}
response.text        = {"result":{"success":true}}
response.json        = {u'result': {u'success': True}}

 

If some issue occurs, you may want to set logging to DEBUG to view the full request and response.

#!/usr/bin/python
import logging

try:
    import http.client as http_client
except ImportError:
    import httplib as http_client

http_client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

 

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 085b75 in the box below so that we can be sure you are a human.