Source code for lima_api.exceptions

import contextlib
import json
from typing import Any, Optional, TypeVar, Union

import httpx
import pydantic

from .utils import parse_data

T = TypeVar("T")


[docs] class LimaException(Exception): detail: str = "" model: Optional[T] = None
[docs] def __init__( self, detail: Optional[str] = None, status_code: Optional[Union[httpx.codes, int]] = None, content: Optional[bytes] = None, request: Optional[httpx.Request] = None, response: Optional[httpx.Response] = None, ): if detail is not None: self.detail = detail self._status_code: Optional[Union[httpx.codes, int]] = status_code self._content: Optional[bytes] = content self._request: Optional[httpx.Request] = request self._response: Optional[httpx.Response] = response
@property def http_request(self) -> Optional[httpx.Request]: if self._request is None and self._response: self._request = self._response.request return self._request @property def http_response(self) -> Optional[httpx.Response]: return self._response @property def status_code(self) -> Optional[Union[httpx.codes, int]]: if self._status_code is None and self._response: self._status_code = self._response.status_code return self._status_code @status_code.setter def status_code(self, status_code: Optional[Union[httpx.codes, int]]): self._status_code = status_code @property def content(self) -> Optional[bytes]: if self._content is None and self._response: self._content = self._response.content return self._content @content.setter def content(self, content: bytes): self._content = content def __repr__(self) -> str: class_name = self.__class__.__name__ return f"{class_name}(detail={self.detail!r}, status_code={self.status_code!r})" def __str__(self) -> str: return self.detail
[docs] def json(self, default: Optional[Any] = dict): """ Return the JSON-decoded content of the response. If the content is None, return the provided default value. The default value can be a callable, in which case it is called to obtain the return value. :param default: The default value to return if content is None. :return: The JSON-decoded content or the default value. :raises json.JSONDecodeError: If the content cannot be decoded. """ if self.content is None: return default() if callable(default) else default return json.loads(self.content.decode())
[docs] def object(self) -> pydantic.BaseModel: """ Parse the response content into a Pydantic model. :return: The parsed Pydantic model. :raises pydantic.ValidationError: If the content cannot be parsed. """ return parse_data(self.model, self.content)
[docs] def response(self, default: Optional[Any] = dict) -> Union[bytes, Any, T]: """ Parse the response content into a Pydantic model, json dump or default value. :param default: The default value to return if content is None. Callable or Any. :return: The parsed content or the default value. """ response = self.content if self.content is not None: with contextlib.suppress(json.JSONDecodeError): response = self.json(default=default) if self.model: with contextlib.suppress(pydantic.ValidationError): response = self.object() else: response = default() if callable(default) else default return response
[docs] class ValidationError(LimaException): detail = "Validation error" def __str__(self): if getattr(self, "__cause__", None): return str(self.__cause__) return self.detail