How to send POST request?

Learn how to send post request? with practical examples, diagrams, and best practices. Covers urllib, python-2.x, httplib development techniques with visual explanations.

Mastering POST Requests in Python: urllib and httplib

Hero image for How to send POST request?

Learn how to send HTTP POST requests using Python 2.x's urllib and httplib libraries, covering basic data submission and handling responses.

Sending POST requests is a fundamental operation in web development, allowing clients to submit data to a server. Unlike GET requests, which append data to the URL, POST requests send data in the body of the HTTP message. This is crucial for operations like submitting forms, uploading files, or sending sensitive information. This article will guide you through performing POST requests using Python 2.x's built-in urllib and httplib modules, providing practical examples and explanations.

Understanding POST Requests

A POST request is one of the most common HTTP methods used to send data to a server to create or update a resource. The data sent in a POST request is typically encoded and included in the request body, making it suitable for larger amounts of data or sensitive information that shouldn't appear in the URL. Common use cases include submitting login credentials, creating new user accounts, or posting comments on a forum.

sequenceDiagram
    participant Client
    participant Server

    Client->>Server: POST /api/data HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\n\nkey1=value1&key2=value2
    Server-->>Client: HTTP/1.1 200 OK\nContent-Type: application/json\n\n{"status": "success", "id": 123}

Sequence diagram illustrating a typical POST request flow.

Sending POST Requests with urllib (Python 2.x)

The urllib module in Python 2.x provides a straightforward way to interact with URLs, including sending POST requests. The key is to encode your data and pass it as the data argument to urllib.urlopen(). This automatically sets the Content-Type header to application/x-www-form-urlencoded.

import urllib

url = 'http://example.com/api/submit'

# Data to be sent (dictionary)
data = {
    'name': 'John Doe',
    'email': 'john.doe@example.com',
    'message': 'Hello from urllib!'
}

# Encode the data
encoded_data = urllib.urlencode(data)

# Send the POST request
response = urllib.urlopen(url, encoded_data)

# Read the response
print "Status Code:", response.getcode()
print "Response Body:\n", response.read()

Example of sending a POST request using urllib in Python 2.x.

Sending POST Requests with httplib (Python 2.x)

For more control over HTTP requests, especially when dealing with custom headers or different content types, httplib is a more robust choice in Python 2.x. It allows you to manually construct the request, including setting headers and providing the request body. This is particularly useful for sending JSON or other non-form-encoded data.

import httplib
import urllib
import json

host = 'example.com'
path = '/api/submit'

# Data to be sent (dictionary)
data = {
    'product_id': 123,
    'quantity': 5,
    'options': ['color:red', 'size:M']
}

# Encode data as JSON (for application/json content type)
json_data = json.dumps(data)

# Or encode as form data (for application/x-www-form-urlencoded)
form_data = urllib.urlencode(data)

# --- Example 1: Sending JSON data ---
conn_json = httplib.HTTPConnection(host)
headers_json = {"Content-type": "application/json", "Accept": "application/json"}
conn_json.request("POST", path, json_data, headers_json)
response_json = conn_json.getresponse()
print "\n--- JSON POST Request ---"
print "Status Code:", response_json.status, response_json.reason
print "Response Body:\n", response_json.read()
conn_json.close()

# --- Example 2: Sending form-urlencoded data ---
conn_form = httplib.HTTPConnection(host)
headers_form = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn_form.request("POST", path, form_data, headers_form)
response_form = conn_form.getresponse()
print "\n--- Form-urlencoded POST Request ---"
print "Status Code:", response_form.status, response_form.reason
print "Response Body:\n", response_form.read()
conn_form.close()

Sending POST requests with httplib for both JSON and form-urlencoded data.

Handling Responses and Errors

After sending a POST request, it's crucial to handle the server's response. Both urllib and httplib provide methods to access the status code, headers, and the response body. A successful POST request typically returns a 200 OK or 201 Created status code. It's good practice to check the status code before attempting to parse the response body.

import urllib

url = 'http://example.com/api/submit'
data = {'key': 'value'}
encoded_data = urllib.urlencode(data)

try:
    response = urllib.urlopen(url, encoded_data)
    status_code = response.getcode()
    response_body = response.read()

    if 200 <= status_code < 300:
        print "Success! Status:", status_code
        print "Response:", response_body
    else:
        print "Error! Status:", status_code
        print "Error Response:", response_body

except IOError as e:
    print "Network or HTTP error:", e
    # For urllib, HTTP errors (4xx, 5xx) raise IOError
    # You can access the error response via e.fp.read() if available
    if hasattr(e, 'fp') and e.fp:
        print "Error details:", e.fp.read()


# --- httplib error handling ---
import httplib
import json

host = 'example.com'
path = '/api/nonexistent'
json_data = json.dumps({'invalid': 'data'})
headers = {"Content-type": "application/json"}

try:
    conn = httplib.HTTPConnection(host)
    conn.request("POST", path, json_data, headers)
    response = conn.getresponse()

    status_code = response.status
    reason = response.reason
    response_body = response.read()

    if 200 <= status_code < 300:
        print "\nhttplib Success! Status:", status_code, reason
        print "Response:", response_body
    else:
        print "\nhttplib Error! Status:", status_code, reason
        print "Error Response:", response_body

except httplib.HTTPException as e:
    print "\nhttplib connection error:", e
except Exception as e:
    print "\nAn unexpected error occurred:", e
finally:
    if 'conn' in locals() and conn:
        conn.close()

Robust error handling for POST requests using urllib and httplib.