</> Vikas Sharma

Requests Library Deep Dive - 5


Continuing the study of the requests module. Today, I am diving into requests/sessions.py, one of the most important modules in the library. It handles persistent settings and provides the reusable Session object.

Key Concepts in requests/sessions.py

The Session Class

A Session object allows you to:

Key Attributes of Session:

Session.request Method

The core method that sends a prepared HTTP request.

Signature:

def request(self, method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, ...):
    # Logic to send the request

Key Steps Inside Session.request:

merged_headers = self.headers.copy()
if headers:
    merged_headers.update(headers)
req = Request(
    method=method.upper(),
    url=url,
    headers=merged_headers,
    params=params,
    data=data,
    cookies=cookies,
    auth=auth,
    ...
)
prep = req.prepare()
resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)

Session.send Method

The send method sends a PreparedRequest and returns a Response object.

Key Responsibilities:

def send(self, request, **kwargs):
    adapter = self.get_adapter(url=request.url)
    return adapter.send(request, **kwargs)

Connection Pooling

The Session class uses transport adapters (from adapters.py) for connection pooling and reusing TCP connections, which improves performance for multiple requests to the same host.

Example of Using a Session:

with requests.Session() as session:
    session.headers.update({'Authorization': 'Bearer TOKEN'})
    response = session.get('https://api.example.com/data')
    print(response.json())

The Authorization header is reused for all requests made with the session. The same connection is reused for performance. This is where the magic of persistent settings and efficient networking happens in requests.sessions.py!