Source code for freshpy.api

# -*- coding: utf-8 -*-
"""
:Module:            freshpy.api
:Synopsis:          This module handles interactions with the Freshservice REST API
:Created By:        Jeff Shurtliff
:Last Modified:     Jeff Shurtliff
:Modified Date:     04 Jan 2022
"""

import json

import requests

from . import errors
from .utils import log_utils

# Initialize logging
logger = log_utils.initialize_logging(__name__)


[docs]def define_headers(): """This function defines the headers to use in API calls. .. versionadded:: 1.0.0 """ headers = {'Content-Type': 'application/json'} return headers
[docs]def define_auth(api_key): """This function defines the authentication dictionary to use in API calls. .. versionadded:: 1.0.0 """ credentials = (api_key, 'X') return credentials
[docs]def get_request_with_retries(fresh_object, uri, headers=None, return_json=True, verify_ssl=True): """This function performs a GET request and will retry several times if a failure occurs. .. versionchanged:: 1.1.0 Added the ability to disable SSL verification on API calls. .. versionadded:: 1.0.0 :param fresh_object: The instantiated :py:class:`freshpy.core.FreshPy` object. :param uri: The URI to query :type uri: string :param headers: The HTTP headers to utilize in the REST API call :type headers: dict, None :param return_json: Determines if JSON data should be returned :type return_json: bool :param verify_ssl: Determines if SSL verification should occur (``True`` by default) :type verify_ssl: bool :returns: The JSON data from the response or the raw :py:mod:`requests` response. :raises: :py:exc:`freshpy.errors.exceptions.APIConnectionError` """ # Define headers if not supplied headers = define_headers() if not headers else headers # Construct the credentials dictionary credentials = define_auth(fresh_object.api_key) # Construct the query URL query_url = fresh_object.base_url + uri # Perform the API call retries, response = 0, None while retries <= 5: try: response = requests.get(query_url, headers=headers, auth=credentials, verify=verify_ssl) break except Exception as exc_msg: _report_failed_attempt(exc_msg, 'get', retries) retries += 1 if retries == 6: _raise_exception_for_repeated_timeouts() pass if return_json: response = response.json() return response
def _report_failed_attempt(_exc_msg, _request_type, _retries): """This function reports a failed API call that will be retried. .. versionadded:: 1.0.0 :param _exc_msg: The exception that was raised within a try/except clause :param _request_type: The type of API request (e.g. ``post``, ``put`` or ``get``) :type _request_type: str :param _retries: The attempt number for the API request :type _retries: int :returns: None """ _exc_name = type(_exc_msg).__name__ if 'connect' not in _exc_name.lower(): raise Exception(f"{_exc_name}: {_exc_msg}") _current_attempt = f"(Attempt {_retries} of 5)" _error_msg = f"The {_request_type.upper()} request has failed with the following exception: " + \ f"{_exc_name}: {_exc_msg} {_current_attempt}" errors.handlers.eprint(f"{_error_msg}\n{_exc_name}: {_exc_msg}\n") return def _raise_exception_for_repeated_timeouts(): """This function raises an exception when all API attempts (including) retries resulted in a timeout. .. versionadded:: 1.0.0 :returns: None :raises: :py:exc:`freshpy.errors.exceptions.APIConnectionError` """ _failure_msg = "The script was unable to complete successfully after five consecutive API timeouts. " + \ "Please run the script again or contact Freshservice Support for further assistance." raise errors.exceptions.APIConnectionError(_failure_msg)