Source code for wystia.requests_models
from __future__ import annotations
from functools import partial
import requests
from requests import Session
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from .requests_config import (
DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_FACTOR, DEFAULT_STATUS_FORCE_LIST)
[docs]class SessionWithRetry(Session):
"""
Extend the :class:`request.Session` class to provide support for HTTP
retries (in cases of timeout or other server-side errors)
"""
def __init__(self, auth=None,
num_retries=DEFAULT_MAX_RETRIES,
backoff_factor=DEFAULT_BACKOFF_FACTOR,
additional_status_force_list: list[int] | None = None):
super().__init__()
self.auth = auth
status_force_list = DEFAULT_STATUS_FORCE_LIST
# Retry on additional status codes (ex. HTTP 400) if needed
if additional_status_force_list:
status_force_list.extend(additional_status_force_list)
retry_strategy = Retry(
read=0,
total=num_retries,
status_forcelist=status_force_list,
allowed_methods=["HEAD", "GET", "PUT", "POST", "DELETE",
"OPTIONS", "TRACE"],
backoff_factor=backoff_factor
)
adapter = HTTPAdapter(max_retries=retry_strategy)
self.mount("https://", adapter)
self.mount("http://", adapter)
[docs]def prefix_url_session(prefix: str, session=None) -> Session:
"""
Returns a :class:`requests.Session` object which makes all HTTP requests
against a base API endpoint.
https://stackoverflow.com/a/53140699/10237506
"""
prefix = prefix.rstrip('/') + '/'
def new_request(prefix, f, method, url, *args, **kwargs):
return f(method, prefix + url.lstrip('/'), *args, **kwargs)
if session is None:
session = requests.Session()
session.request = partial(new_request, prefix, session.request)
return session