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
« 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
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
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
13import datetime
14import json
15import mimetypes
16import os
17import re
18import tempfile
20# python 2 and python 3 compatibility library
21import six
22from six.moves.urllib.parse import quote
24from fingerprint_pro_server_api_sdk.configuration import Configuration
25import fingerprint_pro_server_api_sdk.models
26from fingerprint_pro_server_api_sdk import rest
29class ApiClient(object):
30 """Generic API client for Swagger client library builds.
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.
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.
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 """
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 }
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
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'
84 def __del__(self):
85 self.pool.close()
86 self.pool.join()
88 @property
89 def user_agent(self):
90 """User agent for this API client"""
91 return self.default_headers['User-Agent']
93 @user_agent.setter
94 def user_agent(self, value):
95 self.default_headers['User-Agent'] = value
97 def set_default_header(self, header_name, header_value):
98 self.default_headers[header_name] = header_value
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):
107 config = self.configuration
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))
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 )
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)
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)
144 # auth setting
145 self.update_params_for_auth(header_params, query_params, auth_settings)
147 # body
148 if body:
149 body = self.sanitize_for_serialization(body)
151 # request url
152 url = self.configuration.host + resource_path
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)
161 self.last_response = response_data
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
171 if _return_http_data_only:
172 return (return_data)
173 else:
174 return (return_data, response_data.status,
175 response_data.getheaders())
177 def sanitize_for_serialization(self, obj):
178 """Builds a JSON POST object.
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.
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()
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}
216 return {key: self.sanitize_for_serialization(val)
217 for key, val in six.iteritems(obj_dict)}
219 def deserialize(self, response, response_type, is_error=False):
220 """Deserializes response into an object.
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
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)
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
247 return self.__deserialize(data, response_type)
249 def __deserialize(self, data, klass):
250 """Deserializes dict, list, str into an object.
252 :param data: dict, list or str.
253 :param klass: class literal, or string of class name.
255 :return: object.
256 """
257 if data is None:
258 return None
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]
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)}
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)
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)
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.
296 To make an async request, set the async_req parameter.
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
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 )
409 def parameters_to_tuples(self, params, collection_formats):
410 """Get parameters as list of tuples, formatting collections.
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
439 def prepare_post_parameters(self, post_params=None, files=None):
440 """Builds form parameters.
442 :param post_params: Normal form parameters.
443 :param files: File parameters.
444 :return: Form parameters with files.
445 """
446 params = []
448 if post_params:
449 params = post_params
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])]))
465 return params
467 def select_header_accept(self, accepts):
468 """Returns `Accept` based on an array of accepts provided.
470 :param accepts: List of headers.
471 :return: Accept (e.g. application/json).
472 """
473 if not accepts:
474 return
476 accepts = [x.lower() for x in accepts]
478 if 'application/json' in accepts:
479 return 'application/json'
480 else:
481 return ', '.join(accepts)
483 def select_header_content_type(self, content_types):
484 """Returns `Content-Type` based on an array of content_types provided.
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'
492 content_types = [x.lower() for x in content_types]
494 if 'application/json' in content_types or '*/*' in content_types:
495 return 'application/json'
496 else:
497 return content_types[0]
499 def update_params_for_auth(self, headers, querys, auth_settings):
500 """Updates header and query params based on authentication setting.
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
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 )
523 def __deserialize_file(self, response):
524 """Deserializes body to file
526 Saves response body into a file in a temporary folder,
527 using the filename from the `Content-Disposition` header if provided.
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)
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
551 def __deserialize_primitive(self, data, klass):
552 """Deserializes string to primitive type.
554 :param data: str.
555 :param klass: class literal.
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
566 def __deserialize_object(self, value):
567 """Return a original value.
569 :return: object.
570 """
571 return value
573 def __deserialize_date(self, string):
574 """Deserializes string to date.
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 )
590 def __deserialize_datatime(self, string):
591 """Deserializes string to datetime.
593 The string should be in iso8601 datetime format.
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 )
612 def __hasattr(self, object, name):
613 return name in object.__class__.__dict__
615 def __deserialize_model(self, data, klass):
616 """Deserializes list or dict to model.
618 :param data: dict, list.
619 :param klass: class literal.
620 :return: model object.
621 """
623 if not klass.swagger_types and not self.__hasattr(klass, 'get_real_child_model'):
624 return data
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)
635 instance = klass(**kwargs)
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