5.1 Getting to Know HttpClient
In Python, just like in many programming languages, there's a standard HttpClient. In Python, it's called http.client and it lets you make low-level HTTP requests and work with HTTP responses. You can create connections to HTTP servers and interact with them.
A low-level module like http.client gives you more detailed control over HTTP operations, but requires more code to complete tasks. Unlike it, high-level modules, like requests, offer a simpler interface, hiding many implementation details.
Main Features of http.client
The http.client module offers the following main features:
- Creating HTTP connections.
- Sending HTTP requests.
- Reading HTTP responses.
- Handling headers and bodies of requests and responses.
Unlike the requests module, the http.client module is more low-level and pays great attention to the details of HTTP request operations.
Main Classes and Methods in http.client
| Class/Method | Description |
|---|---|
HTTPConnection |
Creating an HTTP connection. |
HTTPSConnection |
Creating an HTTPS connection. |
request(method, url, ...) |
Sending an HTTP request. |
getresponse() |
Getting the response to a request. |
response.status |
Response status code. |
response.reason |
Text description of the response status. |
response.read() |
Reading response data. |
response.getheaders() |
Getting all response headers. |
response.getheader(name) |
Getting the value of a specific header. |
We'll take a closer look at some of these below.
5.2 Executing a GET Request
To perform requests using the http.client library, you need to follow this order of actions:
Establish a connection
Send a request
Get a response
Close the connection
It's important to note that closing the connection after use is necessary to free up resources and prevent memory leaks. This is especially crucial when dealing with large numbers of requests or in long-living applications.
Example of using HTTPConnection for a regular HTTP request:
import http.client
# Creating an HTTP connection
conn = http.client.HTTPConnection("example.com")
# Sending a GET request
conn.request("GET", "/")
# Getting a response
response = conn.getresponse()
print(response.status, response.reason)
# Closing the connection
conn.close()
Example of using HTTPSConnection:
import http.client
# Establishing a connection
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Sending a GET request
conn.request("GET", "/posts/1")
# Getting a response
response = conn.getresponse()
print(response.status, response.reason)
# Reading and decoding response data
data = response.read().decode('utf-8')
print(data)
# Getting all response headers
headers = response.getheaders()
for header in headers:
print(f"{header[0]}: {header[1]}")
# Closing the connection
conn.close()
A bit longer than when using requests, right?
5.3 Executing a POST Request
A POST request using http.client is quite similar to a GET request, but you need to package the data into a json string yourself and also manually specify the type of data being sent by adding a Content-Type header.
Example:
import http.client
import json
# Sending a POST request
conn.request("POST", "/posts", body=payload, headers=headers)
As the body, you need to pass a json object serialized into a string, and as the headers — a dictionary containing information about the data type.
They might look something like this:
# Data to send
payload = json.dumps({
"title": "foo",
"body": "bar",
"userId": 1
})
# Headers – type of content being sent
headers = {
'Content-Type': 'application/json'
}
Then the full code for a POST request would look like this:
import http.client
import json
# Data to send
payload = json.dumps({
"title": "foo",
"body": "bar",
"userId": 1
})
# Headers
headers = {
'Content-Type': 'application/json'
}
# Establishing a connection
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Sending a POST request
conn.request("POST", "/posts", body=payload, headers=headers)
# Getting a response
response = conn.getresponse()
print(response.status, response.reason)
# Reading and decoding response data
data = response.read().decode('utf-8')
print(data)
# Closing the connection
conn.close()
5.4 Error Handling when Executing Requests
I also think it’ll be helpful to show an example of error handling, as it's different from the requests behavior. In the http.client module, an exception is automatically thrown if there were connection issues or other HTTP errors.
Example:
import http.client
try:
# Establishing a connection
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Sending a GET request
conn.request("GET", "/posts/1")
# Getting a response
response = conn.getresponse()
print(response.status, response.reason)
# Reading and decoding response data
data = response.read().decode('utf-8')
print(data)
except http.client.HTTPException as e:
print("HTTP error occurred:", e)
except Exception as e:
print("An error occurred:", e)
finally:
# Closing the connection
conn.close()
What can I say? Using the requests module is definitely easier. But! Many modules and frameworks use the low-level http.client under the hood. You need to know how to work with it so you can properly configure their operations.
GO TO FULL VERSION