Coverage for fingerprint_server_sdk / exceptions.py: 58%

102 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-11 18:41 +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. 

5 

6The version of the OpenAPI document: 4 

7Contact: support@fingerprint.com 

8Generated by OpenAPI Generator (https://openapi-generator.tech) 

9 

10Do not edit the class manually. 

11""" # noqa: E501 

12 

13from __future__ import annotations 

14 

15import contextlib 

16from typing import TYPE_CHECKING, Any, Optional 

17 

18from typing_extensions import Self 

19 

20if TYPE_CHECKING: 

21 from fingerprint_server_sdk.rest import RESTResponse 

22 

23 

24class OpenApiException(Exception): 

25 """The base exception class for all OpenAPIExceptions""" 

26 

27 

28class ApiTypeError(OpenApiException, TypeError): 

29 def __init__( 

30 self, 

31 msg: str, 

32 path_to_item: Optional[list[Any]] = None, 

33 valid_classes: Optional[tuple[type, ...]] = None, 

34 key_type: Optional[bool] = None, 

35 ) -> None: 

36 """Raises an exception for TypeErrors 

37 

38 Args: 

39 msg (str): the exception message 

40 

41 Keyword Args: 

42 path_to_item (list): a list of keys an indices to get to the 

43 current_item 

44 None if unset 

45 valid_classes (tuple): the primitive classes that current item 

46 should be an instance of 

47 None if unset 

48 key_type (bool): False if our value is a value in a dict 

49 True if it is a key in a dict 

50 False if our item is an item in a list 

51 None if unset 

52 """ 

53 self.path_to_item = path_to_item 

54 self.valid_classes = valid_classes 

55 self.key_type = key_type 

56 full_msg = msg 

57 if path_to_item: 

58 full_msg = f'{msg} at {render_path(path_to_item)}' 

59 super().__init__(full_msg) 

60 

61 

62class ApiValueError(OpenApiException, ValueError): 

63 def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None: 

64 """ 

65 Args: 

66 msg (str): the exception message 

67 

68 Keyword Args: 

69 path_to_item (list) the path to the exception in the 

70 received_data dict. None if unset 

71 """ 

72 

73 self.path_to_item = path_to_item 

74 full_msg = msg 

75 if path_to_item: 

76 full_msg = f'{msg} at {render_path(path_to_item)}' 

77 super().__init__(full_msg) 

78 

79 

80class ApiAttributeError(OpenApiException, AttributeError): 

81 def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None: 

82 """ 

83 Raised when an attribute reference or assignment fails. 

84 

85 Args: 

86 msg (str): the exception message 

87 

88 Keyword Args: 

89 path_to_item (None/list) the path to the exception in the 

90 received_data dict 

91 """ 

92 self.path_to_item = path_to_item 

93 full_msg = msg 

94 if path_to_item: 

95 full_msg = f'{msg} at {render_path(path_to_item)}' 

96 super().__init__(full_msg) 

97 

98 

99class ApiKeyError(OpenApiException, KeyError): 

100 def __init__(self, msg: str, path_to_item: Optional[list[Any]] = None) -> None: 

101 """ 

102 Args: 

103 msg (str): the exception message 

104 

105 Keyword Args: 

106 path_to_item (None/list) the path to the exception in the 

107 received_data dict 

108 """ 

109 self.path_to_item = path_to_item 

110 full_msg = msg 

111 if path_to_item: 

112 full_msg = f'{msg} at {render_path(path_to_item)}' 

113 super().__init__(full_msg) 

114 

115 

116class ApiException(OpenApiException): 

117 def __init__( 

118 self, 

119 status: Optional[int] = None, 

120 reason: Optional[str] = None, 

121 http_resp: Optional[RESTResponse] = None, 

122 *, 

123 body: Optional[str] = None, 

124 data: Optional[Any] = None, 

125 ) -> None: 

126 self.status = status 

127 self.reason = reason 

128 self.body = body 

129 self.data = data 

130 self.headers = None 

131 

132 if http_resp: 

133 if self.status is None: 

134 self.status = http_resp.status 

135 if self.reason is None: 

136 self.reason = http_resp.reason 

137 if self.body is None and http_resp.data is not None: 

138 with contextlib.suppress(UnicodeDecodeError): 

139 self.body = http_resp.data.decode('utf-8') 

140 self.headers = http_resp.headers 

141 

142 @classmethod 

143 def from_response( 

144 cls, 

145 *, 

146 http_resp: RESTResponse, 

147 body: Optional[str], 

148 data: Optional[Any], 

149 ) -> Self: 

150 if http_resp.status == 400: 

151 raise BadRequestException(http_resp=http_resp, body=body, data=data) 

152 

153 if http_resp.status == 401: 

154 raise UnauthorizedException(http_resp=http_resp, body=body, data=data) 

155 

156 if http_resp.status == 403: 

157 raise ForbiddenException(http_resp=http_resp, body=body, data=data) 

158 

159 if http_resp.status == 404: 

160 raise NotFoundException(http_resp=http_resp, body=body, data=data) 

161 

162 # Added new conditions for 409 and 422 

163 if http_resp.status == 409: 

164 raise ConflictException(http_resp=http_resp, body=body, data=data) 

165 

166 if http_resp.status == 422: 

167 raise UnprocessableEntityException(http_resp=http_resp, body=body, data=data) 

168 

169 if http_resp.status == 429: 

170 raise TooManyRequestsException(http_resp=http_resp, body=body, data=data) 

171 

172 if 500 <= http_resp.status <= 599: 

173 raise ServiceException(http_resp=http_resp, body=body, data=data) 

174 raise ApiException(http_resp=http_resp, body=body, data=data) 

175 

176 def __str__(self) -> str: 

177 """Custom error messages for exception""" 

178 error_message = f'({self.status})\nReason: {self.reason}\n' 

179 if self.headers: 

180 error_message += f'HTTP response headers: {self.headers}\n' 

181 

182 if self.body: 

183 error_message += f'HTTP response body: {self.body}\n' 

184 

185 if self.data: 

186 error_message += f'HTTP response data: {self.data}\n' 

187 

188 return error_message 

189 

190 

191class BadRequestException(ApiException): 

192 pass 

193 

194 

195class NotFoundException(ApiException): 

196 pass 

197 

198 

199class UnauthorizedException(ApiException): 

200 pass 

201 

202 

203class ForbiddenException(ApiException): 

204 pass 

205 

206 

207class ServiceException(ApiException): 

208 pass 

209 

210 

211class ConflictException(ApiException): 

212 """Exception for HTTP 409 Conflict.""" 

213 

214 pass 

215 

216 

217class UnprocessableEntityException(ApiException): 

218 """Exception for HTTP 422 Unprocessable Entity.""" 

219 

220 pass 

221 

222 

223class TooManyRequestsException(ApiException): 

224 """Exception for HTTP 429 Too Many Requests.""" 

225 

226 pass 

227 

228 

229def render_path(path_to_item: list[Any]) -> str: 

230 """Returns a string representation of a path""" 

231 result = '' 

232 for pth in path_to_item: 

233 if isinstance(pth, int): 

234 result += f'[{pth}]' 

235 else: 

236 result += f"['{pth}']" 

237 return result