Coverage for fingerprint_server_sdk/exceptions.py: 58%
102 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-14 10:45 +0000
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-14 10:45 +0000
1"""
2Server API
3Fingerprint Server API allows you to get, search, and update Events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios.
4Server API is intended for server-side usage, it's not intended to be used from the client side, whether it's a browser or a mobile device.
5The API also supports collection of Automation Intelligence for requests to your server in edge, pre-origin, or middleware contexts.
7The version of the OpenAPI document: 4
8Contact: support@fingerprint.com
9Generated by OpenAPI Generator (https://openapi-generator.tech)
11Do not edit the class manually.
12""" # noqa: E501
14from __future__ import annotations
16import contextlib
17from typing import TYPE_CHECKING, Any, Optional
19from typing_extensions import Self
21if TYPE_CHECKING:
22 from fingerprint_server_sdk.rest import RESTResponse
25class OpenApiException(Exception):
26 """The base exception class for all OpenAPIExceptions"""
29class ApiTypeError(OpenApiException, TypeError):
30 def __init__(
31 self,
32 msg: str,
33 path_to_item: Optional[list[Any]] = None,
34 valid_classes: Optional[tuple[type, ...]] = None,
35 key_type: Optional[bool] = None,
36 ) -> None:
37 """Raises an exception for TypeErrors
39 Args:
40 msg (str): the exception message
42 Keyword Args:
43 path_to_item (list): a list of keys an indices to get to the
44 current_item
45 None if unset
46 valid_classes (tuple): the primitive classes that current item
47 should be an instance of
48 None if unset
49 key_type (bool): False if our value is a value in a dict
50 True if it is a key in a dict
51 False if our item is an item in a list
52 None if unset
53 """
54 self.path_to_item = path_to_item
55 self.valid_classes = valid_classes
56 self.key_type = key_type
57 full_msg = msg
58 if path_to_item:
59 full_msg = f'{msg} at {render_path(path_to_item)}'
60 super().__init__(full_msg)
63class ApiValueError(OpenApiException, ValueError):
64 def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None:
65 """
66 Args:
67 msg (str): the exception message
69 Keyword Args:
70 path_to_item (list) the path to the exception in the
71 received_data dict. None if unset
72 """
74 self.path_to_item = path_to_item
75 full_msg = msg
76 if path_to_item:
77 full_msg = f'{msg} at {render_path(path_to_item)}'
78 super().__init__(full_msg)
81class ApiAttributeError(OpenApiException, AttributeError):
82 def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None:
83 """
84 Raised when an attribute reference or assignment fails.
86 Args:
87 msg (str): the exception message
89 Keyword Args:
90 path_to_item (None/list) the path to the exception in the
91 received_data dict
92 """
93 self.path_to_item = path_to_item
94 full_msg = msg
95 if path_to_item:
96 full_msg = f'{msg} at {render_path(path_to_item)}'
97 super().__init__(full_msg)
100class ApiKeyError(OpenApiException, KeyError):
101 def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None:
102 """
103 Args:
104 msg (str): the exception message
106 Keyword Args:
107 path_to_item (None/list) the path to the exception in the
108 received_data dict
109 """
110 self.path_to_item = path_to_item
111 full_msg = msg
112 if path_to_item:
113 full_msg = f'{msg} at {render_path(path_to_item)}'
114 super().__init__(full_msg)
117class ApiException(OpenApiException):
118 def __init__(
119 self,
120 status: Optional[int] = None,
121 reason: Optional[str] = None,
122 http_resp: Optional[RESTResponse] = None,
123 *,
124 body: Optional[str] = None,
125 data: Optional[Any] = None,
126 ) -> None:
127 self.status = status
128 self.reason = reason
129 self.body = body
130 self.data = data
131 self.headers = None
133 if http_resp:
134 if self.status is None:
135 self.status = http_resp.status
136 if self.reason is None:
137 self.reason = http_resp.reason
138 if self.body is None and http_resp.data is not None:
139 with contextlib.suppress(UnicodeDecodeError):
140 self.body = http_resp.data.decode('utf-8')
141 self.headers = http_resp.headers
143 @classmethod
144 def from_response(
145 cls,
146 *,
147 http_resp: RESTResponse,
148 body: Optional[str],
149 data: Optional[Any],
150 ) -> Self:
151 if http_resp.status == 400:
152 raise BadRequestException(http_resp=http_resp, body=body, data=data)
154 if http_resp.status == 401:
155 raise UnauthorizedException(http_resp=http_resp, body=body, data=data)
157 if http_resp.status == 403:
158 raise ForbiddenException(http_resp=http_resp, body=body, data=data)
160 if http_resp.status == 404:
161 raise NotFoundException(http_resp=http_resp, body=body, data=data)
163 # Added new conditions for 409 and 422
164 if http_resp.status == 409:
165 raise ConflictException(http_resp=http_resp, body=body, data=data)
167 if http_resp.status == 422:
168 raise UnprocessableEntityException(http_resp=http_resp, body=body, data=data)
170 if http_resp.status == 429:
171 raise TooManyRequestsException(http_resp=http_resp, body=body, data=data)
173 if 500 <= http_resp.status <= 599:
174 raise ServiceException(http_resp=http_resp, body=body, data=data)
175 raise ApiException(http_resp=http_resp, body=body, data=data)
177 def __str__(self) -> str:
178 """Custom error messages for exception"""
179 error_message = f'({self.status})\nReason: {self.reason}\n'
180 if self.headers:
181 error_message += f'HTTP response headers: {self.headers}\n'
183 if self.body:
184 error_message += f'HTTP response body: {self.body}\n'
186 if self.data:
187 error_message += f'HTTP response data: {self.data}\n'
189 return error_message
192class BadRequestException(ApiException):
193 pass
196class NotFoundException(ApiException):
197 pass
200class UnauthorizedException(ApiException):
201 pass
204class ForbiddenException(ApiException):
205 pass
208class ServiceException(ApiException):
209 pass
212class ConflictException(ApiException):
213 """Exception for HTTP 409 Conflict."""
215 pass
218class UnprocessableEntityException(ApiException):
219 """Exception for HTTP 422 Unprocessable Entity."""
221 pass
224class TooManyRequestsException(ApiException):
225 """Exception for HTTP 429 Too Many Requests."""
227 pass
230def render_path(path_to_item: list[Any]) -> str:
231 """Returns a string representation of a path"""
232 result = ''
233 for pth in path_to_item:
234 if isinstance(pth, int):
235 result += f'[{pth}]'
236 else:
237 result += f"['{pth}']"
238 return result