Skip to content

Requests - Handling Redirection

This chapter explores how the Requests library handles URL redirections. By default, Requests will automatically follow redirections for GET, OPTIONS, POST, PUT, PATCH, DELETE, and HEAD requests.

When a server responds with a redirect status code (like 301 Moved Permanently or 302 Found), Requests automatically makes a new request to the URL specified in the Location header. The Response object’s history attribute stores a list of Response objects that were part of this redirection chain, from oldest to most recent.

import requests
# httpbin.org/redirect/N will redirect N times
url = 'http://httpbin.org/redirect/2'
response = requests.get(url)
print(f"Final URL: {response.url}")
print(f"Status Code: {response.status_code}")
print(f"History: {response.history}")
if response.history:
print("Redirection path:")
for resp_in_history in response.history:
print(f" - Status: {resp_in_history.status_code}, URL: {resp_in_history.url}")
Final URL: http://httpbin.org/get
Status Code: 200
History: [<Response [302]>, <Response [302]>]
Redirection path:
- Status: 302, URL: http://httpbin.org/redirect/2
- Status: 302, URL: http://httpbin.org/relative-redirect/1

The response.history list contains Response objects. In this example, there were two redirections (both 302 Found status codes). The final URL is http://httpbin.org/get and has a status code of 200.

You can prevent Requests from automatically following redirections by setting the allow_redirects parameter to False in your request. This applies to all HTTP methods.

import requests
url = 'http://httpbin.org/redirect/1'
response = requests.get(url, allow_redirects=False)
print(f"Status Code: {response.status_code}")
print(f"History (should be empty): {response.history}")
print(f"Location header: {response.headers.get('Location')}")
# The content of a 3xx response often contains information about the redirect
# print(f"Response Text:\n{response.text[:200]}...") # Show first 200 chars
Status Code: 302
History (should be empty): []
Location header: /relative-redirect/0

When allow_redirects is False, the request stops at the first redirect response. The status code is 302 (or another redirect code), response.history is empty, and you can inspect response.headers['Location'] to see where it would have redirected.