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
.