Requests
02 / 02

Sessions, File Uploads & Retries

Requests: Sessions, File Uploads & Retries

Session: Connection Reuse & Cookie Persistence

# A Session reuses the underlying TCP connection (connection
# pooling/keep-alive) across requests to the same host -- meaningfully
# faster than plain requests.get() each time for multiple calls,
# and automatically persists cookies across requests too
session = requests.Session()
session.headers.update({'Authorization': f'Bearer {token}'})

response1 = session.get('https://api.example.com/users')
response2 = session.get('https://api.example.com/orders')
# Same underlying connection reused, shared auth header applied to both

File Uploads (multipart/form-data)

# Handles multipart body construction automatically -- no manual
# boundary/header building needed
with open('report.pdf', 'rb') as f:
    response = requests.post(
        'https://api.example.com/upload',
        files={'document': f},
        data={'description': 'Q3 report'},  # additional form fields
    )

Automatic Retries

from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# Configure retry behavior for TRANSIENT failures (a temporarily
# overloaded server, a flaky connection) -- centralized on the
# session instead of wrapping every call in a manual retry loop
retry_strategy = Retry(
    total=3,
    backoff_factor=0.5,
    status_forcelist=[502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retry_strategy)

session = requests.Session()
session.mount('https://', adapter)
session.mount('http://', adapter)

response = session.get(url, timeout=5)  # now retries automatically on 502/503/504

TLS Verification & Async Alternatives

  • verify=False disables SSL certificate validation -- skips a real protection against man-in-the-middle attacks. Only for known internal self-signed certs, never production/public endpoints.

  • Requests is purely synchronous -- each call blocks until it completes. Concurrent requests require threading as a workaround.

  • httpx/aiohttp support native async/await -- typically far more efficient for I/O-bound workloads needing many concurrent requests (crawling many URLs).

  • For a handful of sequential requests, Requests' simplicity remains the default choice; async libraries fill the high-concurrency niche.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free