Coverage for fingerprint_pro_server_api_sdk/api_client.py: 59%

274 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-27 22:39 +0000

1# coding: utf-8 

2""" 

3 Fingerprint Pro Server API 

4 

5 Fingerprint Pro Server API allows you to get information about visitors and about individual events in a server environment. It can be used for data exports, decision-making, and data analysis scenarios. Server 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. # noqa: E501 

6 

7 OpenAPI spec version: 3 

8 Contact: support@fingerprint.com 

9 Generated by: https://github.com/swagger-api/swagger-codegen.git 

10""" 

11from __future__ import absolute_import 

12 

13import datetime 

14import json 

15import mimetypes 

16import os 

17import re 

18import tempfile 

19 

20# python 2 and python 3 compatibility library 

21import six 

22from six.moves.urllib.parse import quote 

23 

24from fingerprint_pro_server_api_sdk.configuration import Configuration 

25import fingerprint_pro_server_api_sdk.models 

26from fingerprint_pro_server_api_sdk import rest 

27 

28 

29class ApiClient(object): 

30 """Generic API client for Swagger client library builds. 

31 

32 Swagger generic API client. This client handles the client- 

33 server communication, and is invariant across implementations. Specifics of 

34 the methods and models for each application are generated from the Swagger 

35 templates. 

36 

37 NOTE: This class is auto generated by the swagger code generator program. 

38 Ref: https://github.com/swagger-api/swagger-codegen 

39 Do not edit the class manually. 

40 

41 :param configuration: .Configuration object for this client 

42 :param header_name: a header to pass when making calls to the API. 

43 :param header_value: a header value to pass when making calls to 

44 the API. 

45 :param cookie: a cookie to include in the header when making calls 

46 to the API 

47 """ 

48 

49 PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types 

50 NATIVE_TYPES_MAPPING = { 

51 'int': int, 

52 'long': int if six.PY3 else long, # noqa: F821 

53 'float': float, 

54 'str': str, 

55 'bool': bool, 

56 'date': datetime.date, 

57 'datetime': datetime.datetime, 

58 'object': object, 

59 } 

60 

61 def __init__(self, configuration=None, header_name=None, header_value=None, 

62 cookie=None, pool=None): 

63 if configuration is None: 

64 configuration = Configuration() 

65 self.configuration = configuration 

66 

67 if pool is None: 

68 try: 

69 from multiprocessing.pool import ThreadPool 

70 self.pool = ThreadPool() 

71 except (ImportError, OSError): 

72 from fingerprint_pro_server_api_sdk.dummy_pool import DummyPool 

73 self.pool = DummyPool() 

74 else: 

75 self.pool = pool 

76 self.rest_client = rest.RESTClientObject(configuration) 

77 self.default_headers = {} 

78 if header_name is not None: 

79 self.default_headers[header_name] = header_value 

80 self.cookie = cookie 

81 # Set default User-Agent. 

82 self.user_agent = 'Swagger-Codegen/5.0.0/python' 

83 

84 def __del__(self): 

85 self.pool.close() 

86 self.pool.join() 

87 

88 @property 

89 def user_agent(self): 

90 """User agent for this API client""" 

91 return self.default_headers['User-Agent'] 

92 

93 @user_agent.setter 

94 def user_agent(self, value): 

95 self.default_headers['User-Agent'] = value 

96 

97 def set_default_header(self, header_name, header_value): 

98 self.default_headers[header_name] = header_value 

99 

100 def __call_api( 

101 self, resource_path, method, path_params=None, 

102 query_params=None, header_params=None, body=None, post_params=None, 

103 files=None, response_type=None, auth_settings=None, 

104 _return_http_data_only=None, collection_formats=None, 

105 _preload_content=True, _request_timeout=None): 

106 

107 config = self.configuration 

108 

109 # header parameters 

110 header_params = header_params or {} 

111 header_params.update(self.default_headers) 

112 if self.cookie: 

113 header_params['Cookie'] = self.cookie 

114 if header_params: 

115 header_params = self.sanitize_for_serialization(header_params) 

116 header_params = dict(self.parameters_to_tuples(header_params, 

117 collection_formats)) 

118 

119 # path parameters 

120 if path_params: 

121 path_params = self.sanitize_for_serialization(path_params) 

122 path_params = self.parameters_to_tuples(path_params, 

123 collection_formats) 

124 for k, v in path_params: 

125 # specified safe chars, encode everything 

126 resource_path = resource_path.replace( 

127 '{%s}' % k, 

128 quote(str(v), safe=config.safe_chars_for_path_param) 

129 ) 

130 

131 # query parameters 

132 if query_params: 

133 query_params = self.sanitize_for_serialization(query_params) 

134 query_params = self.parameters_to_tuples(query_params, 

135 collection_formats) 

136 

137 # post parameters 

138 if post_params or files: 

139 post_params = self.prepare_post_parameters(post_params, files) 

140 post_params = self.sanitize_for_serialization(post_params) 

141 post_params = self.parameters_to_tuples(post_params, 

142 collection_formats) 

143 

144 # auth setting 

145 self.update_params_for_auth(header_params, query_params, auth_settings) 

146 

147 # body 

148 if body: 

149 body = self.sanitize_for_serialization(body) 

150 

151 # request url 

152 url = self.configuration.host + resource_path 

153 

154 # perform request and return response 

155 response_data = self.request( 

156 method, url, query_params=query_params, headers=header_params, 

157 post_params=post_params, body=body, 

158 _preload_content=_preload_content, 

159 _request_timeout=_request_timeout) 

160 

161 self.last_response = response_data 

162 

163 return_data = response_data 

164 if _preload_content: 

165 # deserialize response data 

166 if response_type: 

167 return_data = self.deserialize(response_data, response_type) 

168 else: 

169 return_data = None 

170 

171 if _return_http_data_only: 

172 return (return_data) 

173 else: 

174 return (return_data, response_data.status, 

175 response_data.getheaders()) 

176 

177 def sanitize_for_serialization(self, obj): 

178 """Builds a JSON POST object. 

179 

180 If obj is None, return None. 

181 If obj is str, int, long, float, bool, return directly. 

182 If obj is datetime.datetime, datetime.date 

183 convert to string in iso8601 format. 

184 If obj is list, sanitize each element in the list. 

185 If obj is dict, return the dict. 

186 If obj is swagger model, return the properties dict. 

187 

188 :param obj: The data to serialize. 

189 :return: The serialized form of data. 

190 """ 

191 if obj is None: 

192 return None 

193 elif isinstance(obj, self.PRIMITIVE_TYPES): 

194 return obj 

195 elif isinstance(obj, list): 

196 return [self.sanitize_for_serialization(sub_obj) 

197 for sub_obj in obj] 

198 elif isinstance(obj, tuple): 

199 return tuple(self.sanitize_for_serialization(sub_obj) 

200 for sub_obj in obj) 

201 elif isinstance(obj, (datetime.datetime, datetime.date)): 

202 return obj.isoformat() 

203 

204 if isinstance(obj, dict): 

205 obj_dict = obj 

206 else: 

207 # Convert model obj to dict except 

208 # attributes `swagger_types`, `attribute_map` 

209 # and attributes which value is not None. 

210 # Convert attribute name to json key in 

211 # model definition for request. 

212 obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) 

213 for attr, _ in six.iteritems(obj.swagger_types) 

214 if getattr(obj, attr) is not None} 

215 

216 return {key: self.sanitize_for_serialization(val) 

217 for key, val in six.iteritems(obj_dict)} 

218 

219 def deserialize(self, response, response_type, is_error=False): 

220 """Deserializes response into an object. 

221 

222 :param response: RESTResponse object to be deserialized. 

223 :param response_type: class literal for 

224 deserialized object, or string of class name. 

225 :param is_error: boolean means deserialization should 

226 be made for `response.body` field 

227 

228 :return: deserialized object. 

229 """ 

230 # handle file downloading 

231 # save response body into a tmp file and return the instance 

232 if response_type == "file": 

233 return self.__deserialize_file(response) 

234 

235 if is_error: 

236 try: 

237 data = json.loads(response.body) 

238 except ValueError: 

239 data = response.body 

240 # fetch data from response object 

241 else: 

242 try: 

243 data = json.loads(response.data) 

244 except ValueError: 

245 data = response.data 

246 

247 return self.__deserialize(data, response_type) 

248 

249 def __deserialize(self, data, klass): 

250 """Deserializes dict, list, str into an object. 

251 

252 :param data: dict, list or str. 

253 :param klass: class literal, or string of class name. 

254 

255 :return: object. 

256 """ 

257 if data is None: 

258 return None 

259 

260 if type(klass) == str: 

261 if klass.startswith('list['): 

262 sub_kls = re.match(r'list\[(.*)\]', klass).group(1) 

263 return [self.__deserialize(sub_data, sub_kls) 

264 for sub_data in data] 

265 

266 if klass.startswith('dict('): 

267 sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) 

268 return {k: self.__deserialize(v, sub_kls) 

269 for k, v in six.iteritems(data)} 

270 

271 # convert str to class 

272 if klass in self.NATIVE_TYPES_MAPPING: 

273 klass = self.NATIVE_TYPES_MAPPING[klass] 

274 else: 

275 klass = getattr(fingerprint_pro_server_api_sdk.models, klass) 

276 

277 if klass in self.PRIMITIVE_TYPES: 

278 return self.__deserialize_primitive(data, klass) 

279 elif klass == object: 

280 return self.__deserialize_object(data) 

281 elif klass == datetime.date: 

282 return self.__deserialize_date(data) 

283 elif klass == datetime.datetime: 

284 return self.__deserialize_datatime(data) 

285 else: 

286 return self.__deserialize_model(data, klass) 

287 

288 def call_api(self, resource_path, method, 

289 path_params=None, query_params=None, header_params=None, 

290 body=None, post_params=None, files=None, 

291 response_type=None, auth_settings=None, async_req=None, 

292 _return_http_data_only=None, collection_formats=None, 

293 _preload_content=True, _request_timeout=None): 

294 """Makes the HTTP request (synchronous) and returns deserialized data. 

295 

296 To make an async request, set the async_req parameter. 

297 

298 :param resource_path: Path to method endpoint. 

299 :param method: Method to call. 

300 :param path_params: Path parameters in the url. 

301 :param query_params: Query parameters in the url. 

302 :param header_params: Header parameters to be 

303 placed in the request header. 

304 :param body: Request body. 

305 :param post_params dict: Request post form parameters, 

306 for `application/x-www-form-urlencoded`, `multipart/form-data`. 

307 :param auth_settings list: Auth Settings names for the request. 

308 :param response: Response data type. 

309 :param files dict: key -> filename, value -> filepath, 

310 for `multipart/form-data`. 

311 :param async_req bool: execute request asynchronously 

312 :param _return_http_data_only: response data without head status code 

313 and headers 

314 :param collection_formats: dict of collection formats for path, query, 

315 header, and post parameters. 

316 :param _preload_content: if False, the urllib3.HTTPResponse object will 

317 be returned without reading/decoding response 

318 data. Default is True. 

319 :param _request_timeout: timeout setting for this request. If one 

320 number provided, it will be total request 

321 timeout. It can also be a pair (tuple) of 

322 (connection, read) timeouts. 

323 :return: 

324 If async_req parameter is True, 

325 the request will be called asynchronously. 

326 The method will return the request thread. 

327 If parameter async_req is False or missing, 

328 then the method will return the response directly. 

329 """ 

330 if not async_req: 

331 return self.__call_api(resource_path, method, 

332 path_params, query_params, header_params, 

333 body, post_params, files, 

334 response_type, auth_settings, 

335 _return_http_data_only, collection_formats, 

336 _preload_content, _request_timeout) 

337 else: 

338 thread = self.pool.apply_async(self.__call_api, (resource_path, 

339 method, path_params, query_params, 

340 header_params, body, 

341 post_params, files, 

342 response_type, auth_settings, 

343 _return_http_data_only, 

344 collection_formats, 

345 _preload_content, _request_timeout)) 

346 return thread 

347 

348 def request(self, method, url, query_params=None, headers=None, 

349 post_params=None, body=None, _preload_content=True, 

350 _request_timeout=None): 

351 """Makes the HTTP request using RESTClient.""" 

352 if method == "GET": 

353 return self.rest_client.GET(url, 

354 query_params=query_params, 

355 _preload_content=_preload_content, 

356 _request_timeout=_request_timeout, 

357 headers=headers) 

358 elif method == "HEAD": 

359 return self.rest_client.HEAD(url, 

360 query_params=query_params, 

361 _preload_content=_preload_content, 

362 _request_timeout=_request_timeout, 

363 headers=headers) 

364 elif method == "OPTIONS": 

365 return self.rest_client.OPTIONS(url, 

366 query_params=query_params, 

367 headers=headers, 

368 post_params=post_params, 

369 _preload_content=_preload_content, 

370 _request_timeout=_request_timeout, 

371 body=body) 

372 elif method == "POST": 

373 return self.rest_client.POST(url, 

374 query_params=query_params, 

375 headers=headers, 

376 post_params=post_params, 

377 _preload_content=_preload_content, 

378 _request_timeout=_request_timeout, 

379 body=body) 

380 elif method == "PUT": 

381 return self.rest_client.PUT(url, 

382 query_params=query_params, 

383 headers=headers, 

384 post_params=post_params, 

385 _preload_content=_preload_content, 

386 _request_timeout=_request_timeout, 

387 body=body) 

388 elif method == "PATCH": 

389 return self.rest_client.PATCH(url, 

390 query_params=query_params, 

391 headers=headers, 

392 post_params=post_params, 

393 _preload_content=_preload_content, 

394 _request_timeout=_request_timeout, 

395 body=body) 

396 elif method == "DELETE": 

397 return self.rest_client.DELETE(url, 

398 query_params=query_params, 

399 headers=headers, 

400 _preload_content=_preload_content, 

401 _request_timeout=_request_timeout, 

402 body=body) 

403 else: 

404 raise ValueError( 

405 "http method must be `GET`, `HEAD`, `OPTIONS`," 

406 " `POST`, `PATCH`, `PUT` or `DELETE`." 

407 ) 

408 

409 def parameters_to_tuples(self, params, collection_formats): 

410 """Get parameters as list of tuples, formatting collections. 

411 

412 :param params: Parameters as dict or list of two-tuples 

413 :param dict collection_formats: Parameter collection formats 

414 :return: Parameters as list of tuples, collections formatted 

415 """ 

416 new_params = [] 

417 if collection_formats is None: 

418 collection_formats = {} 

419 for k, v in six.iteritems(params) if isinstance(params, dict) else params: # noqa: E501 

420 if k in collection_formats: 

421 collection_format = collection_formats[k] 

422 if collection_format == 'multi': 

423 new_params.extend((k, value) for value in v) 

424 else: 

425 if collection_format == 'ssv': 

426 delimiter = ' ' 

427 elif collection_format == 'tsv': 

428 delimiter = '\t' 

429 elif collection_format == 'pipes': 

430 delimiter = '|' 

431 else: # csv is the default 

432 delimiter = ',' 

433 new_params.append( 

434 (k, delimiter.join(str(value) for value in v))) 

435 else: 

436 new_params.append((k, v)) 

437 return new_params 

438 

439 def prepare_post_parameters(self, post_params=None, files=None): 

440 """Builds form parameters. 

441 

442 :param post_params: Normal form parameters. 

443 :param files: File parameters. 

444 :return: Form parameters with files. 

445 """ 

446 params = [] 

447 

448 if post_params: 

449 params = post_params 

450 

451 if files: 

452 for k, v in six.iteritems(files): 

453 if not v: 

454 continue 

455 file_names = v if type(v) is list else [v] 

456 for n in file_names: 

457 with open(n, 'rb') as f: 

458 filename = os.path.basename(f.name) 

459 filedata = f.read() 

460 mimetype = (mimetypes.guess_type(filename)[0] or 

461 'application/octet-stream') 

462 params.append( 

463 tuple([k, tuple([filename, filedata, mimetype])])) 

464 

465 return params 

466 

467 def select_header_accept(self, accepts): 

468 """Returns `Accept` based on an array of accepts provided. 

469 

470 :param accepts: List of headers. 

471 :return: Accept (e.g. application/json). 

472 """ 

473 if not accepts: 

474 return 

475 

476 accepts = [x.lower() for x in accepts] 

477 

478 if 'application/json' in accepts: 

479 return 'application/json' 

480 else: 

481 return ', '.join(accepts) 

482 

483 def select_header_content_type(self, content_types): 

484 """Returns `Content-Type` based on an array of content_types provided. 

485 

486 :param content_types: List of content-types. 

487 :return: Content-Type (e.g. application/json). 

488 """ 

489 if not content_types: 

490 return 'application/json' 

491 

492 content_types = [x.lower() for x in content_types] 

493 

494 if 'application/json' in content_types or '*/*' in content_types: 

495 return 'application/json' 

496 else: 

497 return content_types[0] 

498 

499 def update_params_for_auth(self, headers, querys, auth_settings): 

500 """Updates header and query params based on authentication setting. 

501 

502 :param headers: Header parameters dict to be updated. 

503 :param querys: Query parameters tuple list to be updated. 

504 :param auth_settings: Authentication setting identifiers list. 

505 """ 

506 if not auth_settings: 

507 return 

508 

509 for auth in auth_settings: 

510 auth_setting = self.configuration.auth_settings().get(auth) 

511 if auth_setting: 

512 if not auth_setting['value']: 

513 continue 

514 elif auth_setting['in'] == 'header': 

515 headers[auth_setting['key']] = auth_setting['value'] 

516 elif auth_setting['in'] == 'query': 

517 querys.append((auth_setting['key'], auth_setting['value'])) 

518 else: 

519 raise ValueError( 

520 'Authentication token must be in `query` or `header`' 

521 ) 

522 

523 def __deserialize_file(self, response): 

524 """Deserializes body to file 

525 

526 Saves response body into a file in a temporary folder, 

527 using the filename from the `Content-Disposition` header if provided. 

528 

529 :param response: RESTResponse. 

530 :return: file path. 

531 """ 

532 fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) 

533 os.close(fd) 

534 os.remove(path) 

535 

536 content_disposition = response.getheader("Content-Disposition") 

537 if content_disposition: 

538 filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', 

539 content_disposition).group(1) 

540 path = os.path.join(os.path.dirname(path), filename) 

541 response_data = response.data 

542 with open(path, "w") as f: 

543 if isinstance(response_data, str): 

544 # change str to bytes so we can write it 

545 response_data = response_data.encode('utf-8') 

546 f.write(response_data) 

547 else: 

548 f.write(response_data) 

549 return path 

550 

551 def __deserialize_primitive(self, data, klass): 

552 """Deserializes string to primitive type. 

553 

554 :param data: str. 

555 :param klass: class literal. 

556 

557 :return: int, long, float, str, bool. 

558 """ 

559 try: 

560 return klass(data) 

561 except UnicodeEncodeError: 

562 return six.text_type(data) 

563 except TypeError: 

564 return data 

565 

566 def __deserialize_object(self, value): 

567 """Return a original value. 

568 

569 :return: object. 

570 """ 

571 return value 

572 

573 def __deserialize_date(self, string): 

574 """Deserializes string to date. 

575 

576 :param string: str. 

577 :return: date. 

578 """ 

579 try: 

580 from dateutil.parser import parse 

581 return parse(string).date() 

582 except ImportError: 

583 return string 

584 except ValueError: 

585 raise rest.ApiException( 

586 status=0, 

587 reason="Failed to parse `{0}` as date object".format(string) 

588 ) 

589 

590 def __deserialize_datatime(self, string): 

591 """Deserializes string to datetime. 

592 

593 The string should be in iso8601 datetime format. 

594 

595 :param string: str. 

596 :return: datetime. 

597 """ 

598 try: 

599 from dateutil.parser import parse 

600 return parse(string) 

601 except ImportError: 

602 return string 

603 except ValueError: 

604 raise rest.ApiException( 

605 status=0, 

606 reason=( 

607 "Failed to parse `{0}` as datetime object" 

608 .format(string) 

609 ) 

610 ) 

611 

612 def __hasattr(self, object, name): 

613 return name in object.__class__.__dict__ 

614 

615 def __deserialize_model(self, data, klass): 

616 """Deserializes list or dict to model. 

617 

618 :param data: dict, list. 

619 :param klass: class literal. 

620 :return: model object. 

621 """ 

622 

623 if not klass.swagger_types and not self.__hasattr(klass, 'get_real_child_model'): 

624 return data 

625 

626 kwargs = {} 

627 if klass.swagger_types is not None: 

628 for attr, attr_type in six.iteritems(klass.swagger_types): 

629 if (data is not None and 

630 klass.attribute_map[attr] in data and 

631 isinstance(data, (list, dict))): 

632 value = data[klass.attribute_map[attr]] 

633 kwargs[attr] = self.__deserialize(value, attr_type) 

634 

635 instance = klass(**kwargs) 

636 

637 if (isinstance(instance, dict) and 

638 klass.swagger_types is not None and 

639 isinstance(data, dict)): 

640 for key, value in data.items(): 

641 if key not in klass.swagger_types: 

642 instance[key] = value 

643 if self.__hasattr(instance, 'get_real_child_model'): 

644 klass_name = instance.get_real_child_model(data) 

645 if klass_name: 

646 instance = self.__deserialize(data, klass_name) 

647 return instance