Coverage for fingerprint_server_sdk / configuration.py: 78%

137 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 

13import copy 

14import http.client as httplib 

15import logging 

16import multiprocessing 

17import sys 

18from enum import Enum 

19from logging import FileHandler 

20from typing import Any, ClassVar, Literal, Optional, TypedDict, Union 

21 

22from typing_extensions import Self 

23 

24from fingerprint_server_sdk import __version__ 

25 

26JSON_SCHEMA_VALIDATION_KEYWORDS = { 

27 'multipleOf', 

28 'maximum', 

29 'exclusiveMaximum', 

30 'minimum', 

31 'exclusiveMinimum', 

32 'maxLength', 

33 'minLength', 

34 'pattern', 

35 'maxItems', 

36 'minItems', 

37} 

38 

39ServerVariablesT = dict[str, str] 

40 

41BearerFormatAuthSetting = TypedDict( 

42 'BearerFormatAuthSetting', 

43 { 

44 'type': Literal['bearer'], 

45 'in': Literal['header'], 

46 'format': Literal['JWT'], 

47 'key': Literal['Authorization'], 

48 'value': str, 

49 }, 

50) 

51 

52 

53class AuthSettings(TypedDict, total=False): 

54 bearerAuth: BearerFormatAuthSetting 

55 

56 

57class Region(Enum): 

58 US = 'us' 

59 EU = 'eu' 

60 AP = 'ap' 

61 

62 

63class Configuration: 

64 """This class contains various settings of the API client. 

65 

66 :param api_key: Required API key. 

67 :param region: Region. 

68 :param host: Optional base url. If this provided, region will not be used. 

69 :param ssl_ca_cert: str - the path to a file of concatenated CA certificates 

70 in PEM format. 

71 :param retries: Number of retries for API requests. 

72 :param ca_cert_data: verify the peer using concatenated CA certificate data 

73 in PEM (str) or DER (bytes) format. 

74 :param default_query_params: default additional query parameters. 

75 """ 

76 

77 _default: ClassVar[Optional[Self]] = None 

78 

79 def __init__( 

80 self, 

81 api_key: str, 

82 region: Region = Region.US, 

83 host: Optional[str] = None, 

84 ssl_ca_cert: Optional[str] = None, 

85 retries: Optional[int] = None, 

86 ca_cert_data: Optional[Union[str, bytes]] = None, 

87 default_query_params: Optional[list[tuple[str, str]]] = None, 

88 *, 

89 debug: Optional[bool] = None, 

90 ) -> None: 

91 """Constructor""" 

92 if host: 

93 self._base_path = host 

94 else: 

95 self._base_path = self.get_host(region) 

96 

97 self.api_key = api_key 

98 

99 self.logger = {} 

100 """Logging Settings 

101 """ 

102 self.logger['package_logger'] = logging.getLogger('fingerprint_server_sdk') 

103 self.logger['urllib3_logger'] = logging.getLogger('urllib3') 

104 self.logger_format = '%(asctime)s %(levelname)s %(message)s' 

105 """Log format 

106 """ 

107 self.logger_stream_handler = None 

108 """Log stream handler 

109 """ 

110 self.logger_file_handler: Optional[FileHandler] = None 

111 """Log file handler 

112 """ 

113 self.logger_file = None 

114 """Debug file location 

115 """ 

116 if debug is not None: 

117 self.debug = debug 

118 else: 

119 self.__debug = False 

120 """Debug switch 

121 """ 

122 

123 self.verify_ssl = True 

124 """SSL/TLS verification 

125 Set this to false to skip verifying SSL certificate when calling API 

126 from https server. 

127 """ 

128 self.ssl_ca_cert = ssl_ca_cert 

129 """Set this to customize the certificate file to verify the peer. 

130 """ 

131 self.ca_cert_data = ca_cert_data 

132 """Set this to verify the peer using PEM (str) or DER (bytes) 

133 certificate data. 

134 """ 

135 self.cert_file = None 

136 """client certificate file 

137 """ 

138 self.key_file = None 

139 """client key file 

140 """ 

141 self.assert_hostname = None 

142 """Set this to True/False to enable/disable SSL hostname verification. 

143 """ 

144 self.tls_server_name = None 

145 """SSL/TLS Server Name Indication (SNI) 

146 Set this to the SNI value expected by the server. 

147 """ 

148 

149 self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 

150 """urllib3 connection pool's maximum number of connections saved 

151 per pool. urllib3 uses 1 connection as default value, but this is 

152 not the best value when you are making a lot of possibly parallel 

153 requests to the same host, which is often the case here. 

154 cpu_count * 5 is used as default value to increase performance. 

155 """ 

156 

157 self.proxy: Optional[str] = None 

158 """Proxy URL 

159 """ 

160 self.proxy_headers = None 

161 """Proxy headers 

162 """ 

163 self.safe_chars_for_path_param = '' 

164 """Safe chars for path_param 

165 """ 

166 self.retries = retries 

167 """Adding retries to override urllib3 default value 3 

168 """ 

169 # Enable client side validation 

170 self.client_side_validation = True 

171 

172 self.socket_options = None 

173 """Options to pass down to the underlying urllib3 socket 

174 """ 

175 

176 self.datetime_format = '%Y-%m-%dT%H:%M:%S.%f%z' 

177 """datetime format 

178 """ 

179 

180 self.date_format = '%Y-%m-%d' 

181 """date format 

182 """ 

183 

184 self.default_query_params: list[tuple[str, str]] = ( 

185 default_query_params 

186 if default_query_params 

187 else [('ii', f'fingerprint-server-python-sdk/{__version__}')] 

188 ) 

189 

190 def __deepcopy__(self, memo: dict[int, Any]) -> Self: 

191 cls = self.__class__ 

192 result = cls.__new__(cls) 

193 memo[id(self)] = result 

194 for k, v in self.__dict__.items(): 

195 if k not in ('logger', 'logger_file_handler'): 

196 setattr(result, k, copy.deepcopy(v, memo)) 

197 # shallow copy of loggers 

198 result.logger = copy.copy(self.logger) 

199 # use setters to configure loggers 

200 result.logger_file = self.logger_file 

201 result.debug = self.debug 

202 return result 

203 

204 def __setattr__(self, name: str, value: Any) -> None: 

205 object.__setattr__(self, name, value) 

206 

207 @classmethod 

208 def set_default(cls, default: Optional[Self]) -> None: 

209 """Set default instance of configuration. 

210 

211 It stores default configuration, which can be 

212 returned by get_default_copy method. 

213 

214 :param default: object of Configuration 

215 """ 

216 cls._default = default 

217 

218 @property 

219 def logger_file(self) -> Optional[str]: 

220 """The logger file. 

221 

222 If the logger_file is None, then add stream handler and remove file 

223 handler. Otherwise, add file handler and remove stream handler. 

224 

225 :type: str 

226 """ 

227 return self.__logger_file 

228 

229 @logger_file.setter 

230 def logger_file(self, value: Optional[str]) -> None: 

231 """The logger file. 

232 

233 If the logger_file is None, then add stream handler and remove file 

234 handler. Otherwise, add file handler and remove stream handler. 

235 

236 :param value: The logger_file path. 

237 :type: str 

238 """ 

239 self.__logger_file = value 

240 if self.__logger_file: 

241 # If set logging file, 

242 # then add file handler and remove stream handler. 

243 self.logger_file_handler = logging.FileHandler(self.__logger_file) 

244 self.logger_file_handler.setFormatter(self.logger_formatter) 

245 for _, logger in self.logger.items(): 

246 logger.addHandler(self.logger_file_handler) 

247 

248 @property 

249 def debug(self) -> bool: 

250 """Debug status 

251 

252 :type: bool 

253 """ 

254 return self.__debug 

255 

256 @debug.setter 

257 def debug(self, value: bool) -> None: 

258 """Debug status 

259 

260 :param value: The debug status, True or False. 

261 :type: bool 

262 """ 

263 self.__debug = value 

264 if self.__debug: 

265 # if debug status is True, turn on debug logging 

266 for _, logger in self.logger.items(): 

267 logger.setLevel(logging.DEBUG) 

268 # turn on httplib debug 

269 httplib.HTTPConnection.debuglevel = 1 

270 else: 

271 # if debug status is False, turn off debug logging, 

272 # setting log level to default `logging.WARNING` 

273 for _, logger in self.logger.items(): 

274 logger.setLevel(logging.WARNING) 

275 # turn off httplib debug 

276 httplib.HTTPConnection.debuglevel = 0 

277 

278 @property 

279 def logger_format(self) -> str: 

280 """The logger format. 

281 

282 The logger_formatter will be updated when sets logger_format. 

283 

284 :type: str 

285 """ 

286 return self.__logger_format 

287 

288 @logger_format.setter 

289 def logger_format(self, value: str) -> None: 

290 """The logger format. 

291 

292 The logger_formatter will be updated when sets logger_format. 

293 

294 :param value: The format string. 

295 :type: str 

296 """ 

297 self.__logger_format = value 

298 self.logger_formatter = logging.Formatter(self.__logger_format) 

299 

300 def auth_settings(self) -> AuthSettings: 

301 """Gets Auth Settings dict for api client. 

302 

303 :return: The Auth Settings information dict. 

304 """ 

305 auth: AuthSettings = {} 

306 bearerAuth: BearerFormatAuthSetting = { 

307 'type': 'bearer', 

308 'in': 'header', 

309 'format': 'JWT', 

310 'key': 'Authorization', 

311 'value': 'Bearer ' + self.api_key, 

312 } 

313 

314 auth['bearerAuth'] = bearerAuth 

315 return auth 

316 

317 def to_debug_report(self) -> str: 

318 """Gets the essential information for debugging. 

319 

320 :return: The report for debugging. 

321 """ 

322 return ( 

323 'Python SDK Debug Report:\n' 

324 f'OS: {sys.platform}\n' 

325 f'Python Version: {sys.version}\n' 

326 'Version of the API: 4\n' 

327 'SDK Package Version: 9.0.0-rc.1' 

328 ) 

329 

330 @staticmethod 

331 def get_host(region: Region) -> str: 

332 return { 

333 Region.US: 'https://api.fpjs.io/v4', 

334 Region.EU: 'https://eu.api.fpjs.io/v4', 

335 Region.AP: 'https://ap.api.fpjs.io/v4', 

336 }.get(region, 'https://api.fpjs.io/v4') 

337 

338 @property 

339 def host(self) -> str: 

340 """Return generated host.""" 

341 return self._base_path 

342 

343 @host.setter 

344 def host(self, value: str) -> None: 

345 """Fix base path.""" 

346 self._base_path = value