How to send POST request?
Categories:
Mastering POST Requests in Python: urllib and httplib

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.
urllib.urlencode(), ensure your data is a dictionary. It automatically handles URL-encoding of keys and values, which is essential for application/x-www-form-urlencoded content types.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.
httplib requires you to manually set the Content-Type header based on how you encode your data (e.g., application/json for JSON strings, application/x-www-form-urlencoded for URL-encoded form 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.