Skip to content

Requests - Handling Sessions

A Session object in the requests library allows you to persist certain parameters across multiple requests. This is particularly useful for:

  • Cookie Persistence: Cookies set by the server are automatically stored in the session and sent with subsequent requests to the same domain.
  • Connection Pooling: When making multiple requests to the same host, a session reuses the underlying TCP connection, which can result in a significant performance improvement.
  • Default Data: Setting default headers, authentication, or query parameters for all requests made through the session.

If you make several requests to the same host, using a Session object will ensure that cookies are handled correctly, just like a web browser would.

import requests
# Create a Session object
session = requests.Session()
# Make a request that sets a cookie (httpbin.org/cookies/set?name=value)
# This endpoint will redirect to /cookies, showing the set cookies.
print("Setting a cookie using a session...")
response1 = session.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
print("Cookies after setting (from redirect to /cookies):")
print(response1.json())
# Make another request to the same domain using the same session
# The 'sessioncookie' should be sent automatically.
print("\nRequesting /cookies again to check persistence:")
response2 = session.get('https://httpbin.org/cookies')
print(response2.json())
Setting a cookie using a session...
Cookies after setting (from redirect to /cookies):
{'cookies': {'sessioncookie': '123456789'}}
Requesting /cookies again to check persistence:
{'cookies': {'sessioncookie': '123456789'}}

As you can see, the sessioncookie set in the first request was automatically sent in the second request to httpbin.org/cookies.

You can set default headers on a Session object. These headers will be included in all requests made by that session. Headers provided directly in a request method (e.g., session.get(url, headers=...)) will be merged with session headers, with method-specific headers taking precedence for the same key.

import requests
# Create a Session object
session = requests.Session()
# Update the session's default headers
session.headers.update({
'x-custom-session-header': 'DefaultValue',
'User-Agent': 'MyCustomApp/1.0'
})
print("Request with session default headers:")
response1 = session.get('https://httpbin.org/headers')
print(response1.json()['headers'])
print("\nRequest with session headers and method-specific headers (overriding User-Agent):")
# Method-specific headers can override or add to session headers
custom_request_headers = {
'x-custom-request-header': 'SpecificValue',
'User-Agent': 'MyCustomApp/2.0-Override'
}
response2 = session.get('https://httpbin.org/headers', headers=custom_request_headers)
print(response2.json()['headers'])

Expected Output (simplified, actual order may vary)

Section titled “Expected Output (simplified, actual order may vary)”
Request with session default headers:
{
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "MyCustomApp/1.0",
"X-Amzn-Trace-Id": "Root=...",
"X-Custom-Session-Header": "DefaultValue"
}
Request with session headers and method-specific headers (overriding User-Agent):
{
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "MyCustomApp/2.0-Override",
"X-Amzn-Trace-Id": "Root=...",
"X-Custom-Request-Header": "SpecificValue",
"X-Custom-Session-Header": "DefaultValue"
}

Using Session objects is a best practice when interacting with APIs, especially if you need to make multiple calls or handle authentication that relies on cookies. Learn more from the official documentation on Session Objects.