HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/buyercall/blueprints/email/utils/request_dispatcher.py
# __author__ = "Jayashankar Ramakrishnan"

from functools import wraps
import requests


class RequestDispatcher:
    @staticmethod
    def retry(exceptions, tries=4, delay=3, backoff=3):
        """
        Retry if there is an exception.
        Retry calling the decorated function using an exponential backoff.  If all retries fail,
        the exception is simply raised.  https://www.calazan.com/retry-decorator-for-python-3/
        :param exceptions: The exception to check. may be a tuple of exceptions to check.
            (ConnectionError, requests.Timeout) -> Retry the request if it throws a ConnectionError or Timeout
            (Exception)                         -> Retry if any exception occurs.
        :param tries: Number of times to try before giving up.
        :param delay: Initial delay between retries in seconds.
        :param backoff: Backoff multiplier (value of 3 will triple the delay each retry).
        :return:
        """

        def deco_retry(f):
            @wraps(f)
            def f_retry(*args, **kwargs):
                # set defaults
                tries2 = tries
                delay2 = delay
                backoff2 = backoff

                mod_tries, mod_delay = tries2, delay2
                attempt = 1
                while mod_tries > 1:
                    try:
                        return f(*args, **kwargs)
                    except exceptions as err:
                        attempt += 1
                        mod_tries -= 1
                        mod_delay *= backoff2
                return f(*args, **kwargs)

            return f_retry  # true decorator

        return deco_retry

    @staticmethod
    def head_request(url, headers=None, params=None):
        """
        send a head request to given url and return the response
        :param url: string (fully qualified URL)
        :param headers: dict
        :param params: dict
        """
        try:
            r = requests.head(url=url, params=params, headers=headers)
            resp = {'success': True if r.ok else False, 'status_code': r.status_code, 'data': r.text,
                    'message': 'success'}
        except Exception as err:
            resp = {'success': False, 'status_code': 500, 'message': str(err), 'data': ''}
        return resp

    @staticmethod
    # @retry(Exception)  # Exception = retry on any Exception
    def request_retry(url, headers=None, params=None, data=None, method='get', timeout=(10, 120)):
        """
        calls requests with the retry decorator
        :param url: string (fully qualified URL)
        :param headers: dict
        :param params: dict
        :param data: dict
        :param method: string (get, post, delete, patch, head, options)
        :param timeout: The value in seconds for connect and read timeouts respectively.
        :return: dict

        status codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
        """
        if not headers:
            headers = {}
        response = {}
        try:
            r = requests.request(method=method, url=url, headers=headers, params=params, data=data,
                                 timeout=timeout, verify=False)
            if r.ok:
                response = {'success': True, 'status_code': r.status_code, 'message': 'success', 'data': r.text}
            else:
                # HTTPError will be raised for 4XX client errors or 5XX server errors. No raise if successful 2XX
                r.raise_for_status()
        except requests.HTTPError as http_err:
            response = {'success': False, 'status_code': r.status_code, 'message': str(http_err), 'data': ''}
        except Exception as err:  # timeouts, server errors, etc.
            response = {'success': False, 'status_code': 500, 'message': str(err), 'data': ''}
        return response