class_docstr: A wrapper class around the requests library which handles chores like logging, retries, and timeouts
  automatically.
code: def __init__(
      self,
      base_url: str,
      auth_token: Optional[str] = None,
      log_callback: Optional[Callable] = None,
      use_retry: bool = True,
  ) -> None:
      self.base_url = base_url
      retry_strategy = Retry(
          # wait time between retries increases exponentially according to: backoff_factor * (2 ** (retry - 1))
          # but the the maximum wait time is 120 secs. By setting a large value (2880), we'll make sure clients
          # are going to be alive for a very long time (~ 4 days) but retries every 120 seconds
          total=_CONNECTION_RETRY_TOTAL,
          backoff_factor=_CONNECTION_RETRY_BACKOFF_FACTOR,
          status_forcelist=[
              408,  # Request Timeout
              429,  # Too Many Requests
              500,  # Internal Server Error
              502,  # Bad Gateway
              503,  # Service Unavailable
              504,  # Gateway Timeout
          ],
      )
      adapter = _CustomRetryAdapter(
          max_retries=retry_strategy, timeout=_DEFAULT_REQUEST_TIMEOUT
      )
      self.session = requests.Session()
  
      self.session.hooks = {"response": _response}
  
      if use_retry:
          self.session.mount("http://", adapter)
          self.session.mount("https://", adapter)
  
      if auth_token:
          self.session.headers.update(
              {"Authorization": f"Bearer {auth_token}"}
          )
  
imports: import json
  import os
  import pickle
  from logging import Logger
  from typing import Any, Callable, Dict, Optional
  from urllib.parse import urljoin
  import requests
  import urllib3
  from requests.adapters import HTTPAdapter
  from urllib3.util.retry import Retry
label_desc: Use image node_id 1 to create a new _HTTPClient object  with example: obj = _HTTPClient(base_url, auth_token, log_callback, use_retry)