Source code for pykechain.exceptions

import warnings

from requests import PreparedRequest, Response


[docs] class APIError(Exception): """A general KE-chain API Error occurred. A end-user descriptive message is required. :ivar response: response object :ivar request: request object that precedes the response :ivar msg: error message in the response :ivar traceback: traceback in the response (from the KE-chain server) :ivar detail: details of the error """ def __init__(self, *args, **kwargs): """Initialise the `APIError` with `response`, `request`, `msg`, `traceback` and `detail`. :param response: :param kwargs: """ self.response = kwargs.pop("response", None) if hasattr(self.response, "request"): self.request = self.response.request else: self.request = kwargs.pop("request", None) self.msg, self.traceback, self.detail = None, None, None if args: arg = args[0] context = [arg if isinstance(arg, str) else arg.__repr__()] else: context = [ "Error in request to the server." ] # Default message if `APIError()`, without inputs, is used. import json if self.response is not None and isinstance(self.response, Response): try: response_json = self.response.json() except json.decoder.JSONDecodeError: response_json = None if response_json: self.msg = response_json.get("msg") self.traceback = response_json.get( "traceback", "provided no traceback." ) self.detail = response_json.get("detail") self.results = response_json.get("results") else: self.traceback = self.response.text self.msg = self.traceback.split(r"\n"[-1]) self.detail = None self.results = None context.extend( [ f"Server {self.traceback}", f"Results:\n{json.dumps(self.results, indent=4)}", f"Detail: {self.detail}", f"Elapsed: {self.response.elapsed}", ] ) if self.request is not None and isinstance(self.request, PreparedRequest): context.extend( [ f"Request URL: {self.request.url}", f"Request method: {self.request.method}", ] ) if self.request.body: try: decoded_body = self.request.body.decode( "UTF-8" ) # Convert byte-string to string except AttributeError: decoded_body = ( self.request.body ) # strings (e.g. from testing cassettes) cant be decoded try: body = json.loads( decoded_body ) # Convert string to Python object(s) except json.decoder.JSONDecodeError: body = decoded_body.split("&") # parameters in URL context.append( f"Request data:\n{json.dumps(body, indent=4)}" ) # pretty printing of a json message = "\n".join(context) new_args = [message] super().__init__(*new_args)
[docs] class ForbiddenError(APIError): """A login is required.""" pass
[docs] class MultipleFoundError(APIError): """Multiple objects are found, while a single object is requested.""" pass
[docs] class NotFoundError(APIError): """No object is found.""" pass
[docs] class ClientError(APIError): """When instantiating the Client an Error occurred.""" pass
[docs] class IllegalArgumentError(ValueError): """Illegal arguments where provided.""" pass
[docs] class InspectorComponentError(Exception): """Error in the InspectorComponent.""" pass
[docs] class PDFDownloadTimeoutError(APIError): """Error downloading the PDF because of a timeouterror.""" pass
class _DeprecationMixin: __notified = False def __new__(cls, *args, **kwargs): if not cls.__notified: warnings.warn( f"`{cls.__name__}` is a wrapping class for `{str(cls.__name__)[:-1]}`. " f"`{cls.__name__}` will be deprecated in July 2022.", PendingDeprecationWarning, ) cls.__notified = True return super().__new__(cls)