Python tutorials > Working with External Resources > Networking > How to make HTTP requests?
How to make HTTP requests?
This tutorial explores how to make HTTP requests in Python using the requests
library. We'll cover the basics of sending different types of requests (GET, POST, etc.), handling responses, and common use cases.
Introduction to the requests
library
The requests
library is the de facto standard for making HTTP requests in Python. It simplifies the process of sending requests and handling responses compared to Python's built-in urllib
library. It's known for its ease of use and human-friendly API.
Installing the requests
library
Before you can use the requests
library, you need to install it using pip, the Python package installer. Open your terminal or command prompt and run the command shown in the code block.
pip install requests
Making a GET request
This is the most basic type of HTTP request, used to retrieve data from a server. The code snippet demonstrates how to make a GET request to 'https://www.example.com'. The requests.get()
function sends the request, and the returned response
object contains the server's response. response.status_code
gives the HTTP status code (e.g., 200 for OK, 404 for Not Found). response.content
provides the raw bytes of the response, while response.text
gives the response content as a string (decoded according to the server's encoding).
import requests
url = 'https://www.example.com'
response = requests.get(url)
print(f'Status Code: {response.status_code}')
print(f'Content: {response.content[:200]}...') # Print first 200 characters
Understanding the Response Object
The response
object returned by requests.get()
(and other request methods) contains valuable information about the server's response. Key attributes include:
status_code
: The HTTP status code (e.g., 200, 404, 500).text
: The response content as a Unicode string (decoded automatically).content
: The raw response content as bytes.headers
: A dictionary-like object containing the response headers.json()
: A method to parse the response as JSON (if the response is JSON).
Making a POST request
POST requests are used to send data to a server, often to create or update resources. This snippet demonstrates sending a POST request to 'https://httpbin.org/post' with a dictionary of data. The data
parameter of requests.post()
is used to send the data. The server will echo back the data you sent in the response, which is parsed as JSON using response.json()
.
import requests
url = 'https://httpbin.org/post'
data = {'key': 'value', 'another_key': 'another_value'}
response = requests.post(url, data=data)
print(f'Status Code: {response.status_code}')
print(f'Response JSON: {response.json()}')
Sending JSON Data
When sending JSON data, use the json
parameter of the request methods. The requests
library will automatically set the Content-Type
header to application/json
. This is crucial for the server to correctly interpret the data.
import requests
import json
url = 'https://httpbin.org/post'
data = {'key': 'value', 'another_key': 'another_value'}
response = requests.post(url, json=data)
print(f'Status Code: {response.status_code}')
print(f'Response JSON: {response.json()}')
Setting Headers
You can customize the HTTP headers sent with your request. The code snippet shows how to set a custom User-Agent
header. Headers are passed as a dictionary to the headers
parameter of the request methods. Setting the correct headers is important for interacting with APIs and websites that require specific information about the client.
import requests
url = 'https://www.example.com'
headers = {'User-Agent': 'My Custom User Agent'}
response = requests.get(url, headers=headers)
print(f'Status Code: {response.status_code}')
print(f'Headers: {response.headers}')
Handling Timeouts
It's important to handle potential timeouts when making HTTP requests. The timeout
parameter specifies the maximum time (in seconds) to wait for a response from the server. If the timeout is exceeded, a requests.exceptions.Timeout
exception is raised. It is good practice to wrap the request in a try...except
block to gracefully handle this exception.
import requests
url = 'https://www.example.com'
try:
response = requests.get(url, timeout=5) # Timeout after 5 seconds
print(f'Status Code: {response.status_code}')
except requests.exceptions.Timeout:
print('Request timed out!')
Handling Errors
Handling errors is crucial for robust network programming. The requests
library provides various exception classes for different types of errors. response.raise_for_status()
raises an HTTPError
exception for bad responses (status codes 4xx or 5xx). Other common exceptions include ConnectionError
(network problems), Timeout
, and RequestException
(a base class for all exceptions). Wrapping your request code in a try...except
block allows you to gracefully handle these errors and prevent your program from crashing.
import requests
url = 'https://www.example.com/nonexistent'
try:
response = requests.get(url)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
print(f'Status Code: {response.status_code}')
except requests.exceptions.HTTPError as errh:
print(f'HTTP Error: {errh}')
except requests.exceptions.ConnectionError as errc:
print(f'Connection Error: {errc}')
except requests.exceptions.Timeout as errt:
print(f'Timeout Error: {errt}')
except requests.exceptions.RequestException as err:
print(f'General Error: {err}')
Real-Life Use Case: Fetching Data from an API
This example demonstrates fetching data from the GitHub API. It retrieves information about the user 'octocat'. The response is parsed as JSON, and specific fields (login, name, bio) are extracted and printed. This illustrates a common use case for HTTP requests: interacting with web services and APIs.
import requests
url = 'https://api.github.com/users/octocat'
response = requests.get(url)
if response.status_code == 200:
data = response.json()
print(f"User: {data['login']}")
print(f"Name: {data['name']}")
print(f"Bio: {data['bio']}")
else:
print(f'Error: {response.status_code}')
Best Practices
Timeout
and HTTPError
.User-Agent
.
When to use HTTP Requests
Use HTTP requests when you need to interact with web servers and APIs to retrieve or send data. This includes:
Alternatives to requests
urllib
(Python's built-in library): More complex to use than requests
.aiohttp
: Asynchronous HTTP client for asynchronous programming.httpx
: A next generation HTTP client for Python that supports both HTTP/1.1 and HTTP/2.
Pros of using requests
Cons of using requests
aiohttp
or httpx
for asynchronous operations.urllib
for very large responses (less of a concern in most practical scenarios).
FAQ
-
What is the difference between
response.text
andresponse.content
?
response.text
returns the response content as a Unicode string, automatically decoded based on the response's encoding.response.content
returns the raw response content as bytes. -
How do I handle SSL certificate verification errors?
By default,
requests
verifies SSL certificates. You can disable verification using theverify=False
parameter, but this is generally not recommended for security reasons. Instead, consider installing the necessary CA certificates or specifying a custom CA bundle using theverify
parameter. -
How can I make asynchronous HTTP requests?
Use the
aiohttp
orhttpx
libraries, which provide asynchronous HTTP client implementations.