cosmotech-api 3.1.1__py3-none-any.whl → 3.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cosmotech-api might be problematic. Click here for more details.

Files changed (244) hide show
  1. cosmotech_api/__init__.py +134 -9
  2. cosmotech_api/api/__init__.py +14 -3
  3. cosmotech_api/api/connector_api.py +1313 -641
  4. cosmotech_api/api/dataset_api.py +8974 -4465
  5. cosmotech_api/api/organization_api.py +4633 -2269
  6. cosmotech_api/api/run_api.py +2174 -778
  7. cosmotech_api/api/runner_api.py +4483 -2280
  8. cosmotech_api/api/scenario_api.py +6544 -3265
  9. cosmotech_api/api/scenariorun_api.py +4007 -1960
  10. cosmotech_api/api/scenariorunresult_api.py +659 -341
  11. cosmotech_api/api/solution_api.py +6341 -3140
  12. cosmotech_api/api/twingraph_api.py +4134 -2077
  13. cosmotech_api/api/validator_api.py +2501 -1249
  14. cosmotech_api/api/workspace_api.py +5999 -2977
  15. cosmotech_api/api_client.py +529 -637
  16. cosmotech_api/configuration.py +63 -73
  17. cosmotech_api/exceptions.py +71 -31
  18. cosmotech_api/model/component_role_permissions.py +1 -1
  19. cosmotech_api/model/connector.py +1 -1
  20. cosmotech_api/model/connector_parameter.py +1 -1
  21. cosmotech_api/model/connector_parameter_group.py +1 -1
  22. cosmotech_api/model/container_resource_size_info.py +1 -1
  23. cosmotech_api/model/container_resource_sizing.py +1 -1
  24. cosmotech_api/model/dataset.py +1 -1
  25. cosmotech_api/model/dataset_access_control.py +1 -1
  26. cosmotech_api/model/dataset_compatibility.py +1 -1
  27. cosmotech_api/model/dataset_connector.py +1 -1
  28. cosmotech_api/model/dataset_copy_parameters.py +1 -1
  29. cosmotech_api/model/dataset_role.py +1 -1
  30. cosmotech_api/model/dataset_search.py +1 -1
  31. cosmotech_api/model/dataset_security.py +1 -1
  32. cosmotech_api/model/dataset_source_type.py +1 -1
  33. cosmotech_api/model/dataset_twin_graph_hash.py +1 -1
  34. cosmotech_api/model/dataset_twin_graph_info.py +1 -1
  35. cosmotech_api/model/dataset_twin_graph_query.py +1 -1
  36. cosmotech_api/model/delete_historical_data.py +1 -1
  37. cosmotech_api/model/file_upload_metadata.py +1 -1
  38. cosmotech_api/model/file_upload_validation.py +1 -1
  39. cosmotech_api/model/graph_properties.py +1 -1
  40. cosmotech_api/model/organization.py +1 -1
  41. cosmotech_api/model/organization_access_control.py +1 -1
  42. cosmotech_api/model/organization_role.py +1 -1
  43. cosmotech_api/model/organization_security.py +1 -1
  44. cosmotech_api/model/organization_service.py +1 -1
  45. cosmotech_api/model/organization_services.py +1 -1
  46. cosmotech_api/model/resource_size_info.py +1 -1
  47. cosmotech_api/model/run.py +1 -1
  48. cosmotech_api/model/run_container.py +1 -1
  49. cosmotech_api/model/run_container_artifact.py +1 -1
  50. cosmotech_api/model/run_container_logs.py +1 -1
  51. cosmotech_api/model/run_logs.py +1 -1
  52. cosmotech_api/model/run_resource_requested.py +1 -1
  53. cosmotech_api/model/run_search.py +1 -1
  54. cosmotech_api/model/run_start_containers.py +1 -1
  55. cosmotech_api/model/run_state.py +1 -1
  56. cosmotech_api/model/run_status.py +1 -1
  57. cosmotech_api/model/run_status_node.py +1 -1
  58. cosmotech_api/model/run_template.py +1 -1
  59. cosmotech_api/model/run_template_handler_id.py +1 -1
  60. cosmotech_api/model/run_template_orchestrator.py +1 -1
  61. cosmotech_api/model/run_template_parameter.py +1 -1
  62. cosmotech_api/model/run_template_parameter_group.py +1 -1
  63. cosmotech_api/model/run_template_parameter_value.py +1 -1
  64. cosmotech_api/model/run_template_resource_sizing.py +1 -1
  65. cosmotech_api/model/run_template_step_source.py +1 -1
  66. cosmotech_api/model/runner.py +1 -1
  67. cosmotech_api/model/runner_access_control.py +1 -1
  68. cosmotech_api/model/runner_changed_parameter_value.py +1 -1
  69. cosmotech_api/model/runner_comparison_result.py +1 -1
  70. cosmotech_api/model/runner_data_download_info.py +1 -1
  71. cosmotech_api/model/runner_data_download_job.py +1 -1
  72. cosmotech_api/model/runner_job_state.py +1 -1
  73. cosmotech_api/model/runner_last_run.py +1 -1
  74. cosmotech_api/model/runner_resource_sizing.py +1 -1
  75. cosmotech_api/model/runner_role.py +1 -1
  76. cosmotech_api/model/runner_run_template_parameter_value.py +1 -1
  77. cosmotech_api/model/runner_security.py +1 -1
  78. cosmotech_api/model/runner_validation_status.py +1 -1
  79. cosmotech_api/model/scenario.py +1 -1
  80. cosmotech_api/model/scenario_access_control.py +1 -1
  81. cosmotech_api/model/scenario_changed_parameter_value.py +1 -1
  82. cosmotech_api/model/scenario_comparison_result.py +1 -1
  83. cosmotech_api/model/scenario_data_download_info.py +1 -1
  84. cosmotech_api/model/scenario_data_download_job.py +1 -1
  85. cosmotech_api/model/scenario_job_state.py +1 -1
  86. cosmotech_api/model/scenario_last_run.py +1 -1
  87. cosmotech_api/model/scenario_resource_sizing.py +1 -1
  88. cosmotech_api/model/scenario_role.py +1 -1
  89. cosmotech_api/model/scenario_run.py +1 -1
  90. cosmotech_api/model/scenario_run_container.py +1 -1
  91. cosmotech_api/model/scenario_run_container_artifact.py +1 -1
  92. cosmotech_api/model/scenario_run_container_logs.py +1 -1
  93. cosmotech_api/model/scenario_run_logs.py +1 -1
  94. cosmotech_api/model/scenario_run_resource_requested.py +1 -1
  95. cosmotech_api/model/scenario_run_result.py +1 -1
  96. cosmotech_api/model/scenario_run_search.py +1 -1
  97. cosmotech_api/model/scenario_run_start_containers.py +1 -1
  98. cosmotech_api/model/scenario_run_state.py +1 -1
  99. cosmotech_api/model/scenario_run_status.py +1 -1
  100. cosmotech_api/model/scenario_run_status_node.py +1 -1
  101. cosmotech_api/model/scenario_run_template_parameter_value.py +1 -1
  102. cosmotech_api/model/scenario_security.py +1 -1
  103. cosmotech_api/model/scenario_validation_status.py +1 -1
  104. cosmotech_api/model/solution.py +1 -1
  105. cosmotech_api/model/solution_access_control.py +1 -1
  106. cosmotech_api/model/solution_role.py +1 -1
  107. cosmotech_api/model/solution_security.py +1 -1
  108. cosmotech_api/model/source_info.py +1 -1
  109. cosmotech_api/model/sub_dataset_graph_query.py +1 -1
  110. cosmotech_api/model/translated_labels.py +1 -1
  111. cosmotech_api/model/twin_graph_batch_result.py +1 -1
  112. cosmotech_api/model/twin_graph_hash.py +1 -1
  113. cosmotech_api/model/twin_graph_import.py +1 -1
  114. cosmotech_api/model/twin_graph_import_info.py +1 -1
  115. cosmotech_api/model/twin_graph_query.py +1 -1
  116. cosmotech_api/model/validator.py +1 -1
  117. cosmotech_api/model/validator_run.py +1 -1
  118. cosmotech_api/model/workspace.py +1 -1
  119. cosmotech_api/model/workspace_access_control.py +1 -1
  120. cosmotech_api/model/workspace_file.py +1 -1
  121. cosmotech_api/model/workspace_role.py +1 -1
  122. cosmotech_api/model/workspace_secret.py +1 -1
  123. cosmotech_api/model/workspace_security.py +1 -1
  124. cosmotech_api/model/workspace_solution.py +1 -1
  125. cosmotech_api/model/workspace_web_app.py +1 -1
  126. cosmotech_api/model_utils.py +1 -1
  127. cosmotech_api/models/__init__.py +124 -114
  128. cosmotech_api/models/component_role_permissions.py +1 -1
  129. cosmotech_api/models/connector.py +1 -1
  130. cosmotech_api/models/connector_parameter.py +1 -1
  131. cosmotech_api/models/connector_parameter_group.py +1 -1
  132. cosmotech_api/models/container_resource_size_info.py +1 -1
  133. cosmotech_api/models/container_resource_sizing.py +1 -1
  134. cosmotech_api/models/dataset.py +1 -1
  135. cosmotech_api/models/dataset_access_control.py +1 -1
  136. cosmotech_api/models/dataset_compatibility.py +1 -1
  137. cosmotech_api/models/dataset_connector.py +1 -1
  138. cosmotech_api/models/dataset_copy_parameters.py +1 -1
  139. cosmotech_api/models/dataset_role.py +1 -1
  140. cosmotech_api/models/dataset_search.py +1 -1
  141. cosmotech_api/models/dataset_security.py +1 -1
  142. cosmotech_api/models/dataset_source_type.py +1 -1
  143. cosmotech_api/models/dataset_twin_graph_hash.py +1 -1
  144. cosmotech_api/models/dataset_twin_graph_info.py +1 -1
  145. cosmotech_api/models/dataset_twin_graph_query.py +1 -1
  146. cosmotech_api/models/delete_historical_data.py +1 -1
  147. cosmotech_api/models/file_upload_metadata.py +1 -1
  148. cosmotech_api/models/file_upload_validation.py +1 -1
  149. cosmotech_api/models/graph_properties.py +1 -1
  150. cosmotech_api/models/organization.py +1 -1
  151. cosmotech_api/models/organization_access_control.py +1 -1
  152. cosmotech_api/models/organization_role.py +1 -1
  153. cosmotech_api/models/organization_security.py +1 -1
  154. cosmotech_api/models/organization_service.py +1 -1
  155. cosmotech_api/models/organization_services.py +1 -1
  156. cosmotech_api/models/query_result.py +88 -0
  157. cosmotech_api/models/resource_size_info.py +1 -1
  158. cosmotech_api/models/run.py +1 -1
  159. cosmotech_api/models/run_container.py +1 -1
  160. cosmotech_api/models/run_container_artifact.py +1 -1
  161. cosmotech_api/models/run_container_logs.py +1 -1
  162. cosmotech_api/models/run_data.py +92 -0
  163. cosmotech_api/models/run_data_query.py +88 -0
  164. cosmotech_api/models/run_logs.py +1 -1
  165. cosmotech_api/models/run_resource_requested.py +1 -1
  166. cosmotech_api/models/run_search.py +1 -1
  167. cosmotech_api/models/run_start_containers.py +1 -1
  168. cosmotech_api/models/run_state.py +1 -1
  169. cosmotech_api/models/run_status.py +1 -1
  170. cosmotech_api/models/run_status_node.py +1 -1
  171. cosmotech_api/models/run_template.py +1 -1
  172. cosmotech_api/models/run_template_handler_id.py +1 -1
  173. cosmotech_api/models/run_template_orchestrator.py +1 -1
  174. cosmotech_api/models/run_template_parameter.py +1 -1
  175. cosmotech_api/models/run_template_parameter_group.py +1 -1
  176. cosmotech_api/models/run_template_parameter_value.py +1 -1
  177. cosmotech_api/models/run_template_resource_sizing.py +1 -1
  178. cosmotech_api/models/run_template_step_source.py +1 -1
  179. cosmotech_api/models/runner.py +1 -1
  180. cosmotech_api/models/runner_access_control.py +1 -1
  181. cosmotech_api/models/runner_changed_parameter_value.py +1 -1
  182. cosmotech_api/models/runner_comparison_result.py +1 -1
  183. cosmotech_api/models/runner_data_download_info.py +1 -1
  184. cosmotech_api/models/runner_data_download_job.py +1 -1
  185. cosmotech_api/models/runner_job_state.py +1 -1
  186. cosmotech_api/models/runner_last_run.py +1 -1
  187. cosmotech_api/models/runner_parent_last_run.py +1 -1
  188. cosmotech_api/models/runner_resource_sizing.py +1 -1
  189. cosmotech_api/models/runner_role.py +1 -1
  190. cosmotech_api/models/runner_root_last_run.py +1 -1
  191. cosmotech_api/models/runner_run_template_parameter_value.py +1 -1
  192. cosmotech_api/models/runner_security.py +1 -1
  193. cosmotech_api/models/runner_validation_status.py +1 -1
  194. cosmotech_api/models/scenario.py +1 -1
  195. cosmotech_api/models/scenario_access_control.py +1 -1
  196. cosmotech_api/models/scenario_changed_parameter_value.py +1 -1
  197. cosmotech_api/models/scenario_comparison_result.py +1 -1
  198. cosmotech_api/models/scenario_data_download_info.py +1 -1
  199. cosmotech_api/models/scenario_data_download_job.py +1 -1
  200. cosmotech_api/models/scenario_job_state.py +1 -1
  201. cosmotech_api/models/scenario_last_run.py +1 -1
  202. cosmotech_api/models/scenario_resource_sizing.py +1 -1
  203. cosmotech_api/models/scenario_role.py +1 -1
  204. cosmotech_api/models/scenario_run.py +1 -1
  205. cosmotech_api/models/scenario_run_container.py +1 -1
  206. cosmotech_api/models/scenario_run_container_artifact.py +1 -1
  207. cosmotech_api/models/scenario_run_container_logs.py +1 -1
  208. cosmotech_api/models/scenario_run_logs.py +1 -1
  209. cosmotech_api/models/scenario_run_resource_requested.py +1 -1
  210. cosmotech_api/models/scenario_run_search.py +1 -1
  211. cosmotech_api/models/scenario_run_start_containers.py +1 -1
  212. cosmotech_api/models/scenario_run_state.py +1 -1
  213. cosmotech_api/models/scenario_run_status.py +1 -1
  214. cosmotech_api/models/scenario_run_status_node.py +1 -1
  215. cosmotech_api/models/scenario_run_template_parameter_value.py +1 -1
  216. cosmotech_api/models/scenario_security.py +1 -1
  217. cosmotech_api/models/scenario_validation_status.py +1 -1
  218. cosmotech_api/models/send_run_data_request.py +90 -0
  219. cosmotech_api/models/solution.py +1 -1
  220. cosmotech_api/models/solution_access_control.py +1 -1
  221. cosmotech_api/models/solution_role.py +1 -1
  222. cosmotech_api/models/solution_security.py +1 -1
  223. cosmotech_api/models/source_info.py +1 -1
  224. cosmotech_api/models/sub_dataset_graph_query.py +1 -1
  225. cosmotech_api/models/twin_graph_batch_result.py +1 -1
  226. cosmotech_api/models/twin_graph_hash.py +1 -1
  227. cosmotech_api/models/twin_graph_query.py +1 -1
  228. cosmotech_api/models/validator.py +1 -1
  229. cosmotech_api/models/validator_run.py +1 -1
  230. cosmotech_api/models/workspace.py +1 -1
  231. cosmotech_api/models/workspace_access_control.py +1 -1
  232. cosmotech_api/models/workspace_file.py +1 -1
  233. cosmotech_api/models/workspace_role.py +1 -1
  234. cosmotech_api/models/workspace_secret.py +1 -1
  235. cosmotech_api/models/workspace_security.py +1 -1
  236. cosmotech_api/models/workspace_solution.py +1 -1
  237. cosmotech_api/models/workspace_web_app.py +1 -1
  238. cosmotech_api/rest.py +139 -230
  239. {cosmotech_api-3.1.1.dist-info → cosmotech_api-3.2.0.dist-info}/METADATA +6 -4
  240. cosmotech_api-3.2.0.dist-info/RECORD +255 -0
  241. cosmotech_api-3.1.1.dist-info/RECORD +0 -251
  242. {cosmotech_api-3.1.1.dist-info → cosmotech_api-3.2.0.dist-info}/LICENSE +0 -0
  243. {cosmotech_api-3.1.1.dist-info → cosmotech_api-3.2.0.dist-info}/WHEEL +0 -0
  244. {cosmotech_api-3.1.1.dist-info → cosmotech_api-3.2.0.dist-info}/top_level.txt +0 -0
@@ -1,46 +1,47 @@
1
+ # coding: utf-8
2
+
1
3
  """
2
4
  Cosmo Tech Platform API
3
5
 
4
- Cosmo Tech Platform API # noqa: E501
6
+ Cosmo Tech Platform API
5
7
 
6
- The version of the OpenAPI document: 3.1.1
8
+ The version of the OpenAPI document: 3.2.0
7
9
  Contact: platform@cosmotech.com
8
- Generated by: https://openapi-generator.tech
9
- """
10
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
11
+
12
+ Do not edit the class manually.
13
+ """ # noqa: E501
10
14
 
11
15
 
16
+ import datetime
17
+ from dateutil.parser import parse
18
+ from enum import Enum
12
19
  import json
13
- import atexit
14
20
  import mimetypes
15
- from multiprocessing.pool import ThreadPool
16
- import io
17
21
  import os
18
22
  import re
19
- import typing
20
- from urllib.parse import quote
21
- from urllib3.fields import RequestField
23
+ import tempfile
22
24
 
25
+ from urllib.parse import quote
26
+ from typing import Tuple, Optional, List, Dict
23
27
 
24
- from cosmotech_api import rest
25
28
  from cosmotech_api.configuration import Configuration
26
- from cosmotech_api.exceptions import ApiTypeError, ApiValueError, ApiException
27
- from cosmotech_api.model_utils import (
28
- ModelNormal,
29
- ModelSimple,
30
- ModelComposed,
31
- check_allowed_values,
32
- check_validations,
33
- date,
34
- datetime,
35
- deserialize_file,
36
- file_type,
37
- model_to_dict,
38
- none_type,
39
- validate_and_convert_types
29
+ from cosmotech_api.api_response import ApiResponse, T as ApiResponseT
30
+ import cosmotech_api.models
31
+ from cosmotech_api import rest
32
+ from cosmotech_api.exceptions import (
33
+ ApiValueError,
34
+ ApiException,
35
+ BadRequestException,
36
+ UnauthorizedException,
37
+ ForbiddenException,
38
+ NotFoundException,
39
+ ServiceException
40
40
  )
41
41
 
42
+ RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]]
42
43
 
43
- class ApiClient(object):
44
+ class ApiClient:
44
45
  """Generic API client for OpenAPI client library builds.
45
46
 
46
47
  OpenAPI generic API client. This client handles the client-
@@ -48,28 +49,38 @@ class ApiClient(object):
48
49
  the methods and models for each application are generated from the OpenAPI
49
50
  templates.
50
51
 
51
- NOTE: This class is auto generated by OpenAPI Generator.
52
- Ref: https://openapi-generator.tech
53
- Do not edit the class manually.
54
-
55
52
  :param configuration: .Configuration object for this client
56
53
  :param header_name: a header to pass when making calls to the API.
57
54
  :param header_value: a header value to pass when making calls to
58
55
  the API.
59
56
  :param cookie: a cookie to include in the header when making calls
60
57
  to the API
61
- :param pool_threads: The number of threads to use for async requests
62
- to the API. More threads means more concurrent API requests.
63
58
  """
64
59
 
60
+ PRIMITIVE_TYPES = (float, bool, bytes, str, int)
61
+ NATIVE_TYPES_MAPPING = {
62
+ 'int': int,
63
+ 'long': int, # TODO remove as only py3 is supported?
64
+ 'float': float,
65
+ 'str': str,
66
+ 'bool': bool,
67
+ 'date': datetime.date,
68
+ 'datetime': datetime.datetime,
69
+ 'object': object,
70
+ }
65
71
  _pool = None
66
72
 
67
- def __init__(self, configuration=None, header_name=None, header_value=None,
68
- cookie=None, pool_threads=1):
73
+ def __init__(
74
+ self,
75
+ configuration=None,
76
+ header_name=None,
77
+ header_value=None,
78
+ cookie=None
79
+ ) -> None:
80
+ # use default configuration if none is provided
69
81
  if configuration is None:
70
- configuration = Configuration.get_default_copy()
82
+ configuration = Configuration.get_default()
71
83
  self.configuration = configuration
72
- self.pool_threads = pool_threads
73
84
 
74
85
  self.rest_client = rest.RESTClientObject(configuration)
75
86
  self.default_headers = {}
@@ -78,30 +89,13 @@ class ApiClient(object):
78
89
  self.cookie = cookie
79
90
  # Set default User-Agent.
80
91
  self.user_agent = 'OpenAPI-Generator/1.0.0/python'
92
+ self.client_side_validation = configuration.client_side_validation
81
93
 
82
94
  def __enter__(self):
83
95
  return self
84
96
 
85
97
  def __exit__(self, exc_type, exc_value, traceback):
86
- self.close()
87
-
88
- def close(self):
89
- if self._pool:
90
- self._pool.close()
91
- self._pool.join()
92
- self._pool = None
93
- if hasattr(atexit, 'unregister'):
94
- atexit.unregister(self.close)
95
-
96
- @property
97
- def pool(self):
98
- """Create thread pool on first request
99
- avoids instantiating unused threadpool for blocking clients.
100
- """
101
- if self._pool is None:
102
- atexit.register(self.close)
103
- self._pool = ThreadPool(self.pool_threads)
104
- return self._pool
98
+ pass
105
99
 
106
100
  @property
107
101
  def user_agent(self):
@@ -115,26 +109,69 @@ class ApiClient(object):
115
109
  def set_default_header(self, header_name, header_value):
116
110
  self.default_headers[header_name] = header_value
117
111
 
118
- def __call_api(
112
+
113
+ _default = None
114
+
115
+ @classmethod
116
+ def get_default(cls):
117
+ """Return new instance of ApiClient.
118
+
119
+ This method returns newly created, based on default constructor,
120
+ object of ApiClient class or returns a copy of default
121
+ ApiClient.
122
+
123
+ :return: The ApiClient object.
124
+ """
125
+ if cls._default is None:
126
+ cls._default = ApiClient()
127
+ return cls._default
128
+
129
+ @classmethod
130
+ def set_default(cls, default):
131
+ """Set default instance of ApiClient.
132
+
133
+ It stores default ApiClient.
134
+
135
+ :param default: object of ApiClient.
136
+ """
137
+ cls._default = default
138
+
139
+ def param_serialize(
119
140
  self,
120
- resource_path: str,
121
- method: str,
122
- path_params: typing.Optional[typing.Dict[str, typing.Any]] = None,
123
- query_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None,
124
- header_params: typing.Optional[typing.Dict[str, typing.Any]] = None,
125
- body: typing.Optional[typing.Any] = None,
126
- post_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None,
127
- files: typing.Optional[typing.Dict[str, typing.List[io.IOBase]]] = None,
128
- response_type: typing.Optional[typing.Tuple[typing.Any]] = None,
129
- auth_settings: typing.Optional[typing.List[str]] = None,
130
- _return_http_data_only: typing.Optional[bool] = None,
131
- collection_formats: typing.Optional[typing.Dict[str, str]] = None,
132
- _preload_content: bool = True,
133
- _request_timeout: typing.Optional[typing.Union[int, float, typing.Tuple]] = None,
134
- _host: typing.Optional[str] = None,
135
- _check_type: typing.Optional[bool] = None,
136
- _content_type: typing.Optional[str] = None
137
- ):
141
+ method,
142
+ resource_path,
143
+ path_params=None,
144
+ query_params=None,
145
+ header_params=None,
146
+ body=None,
147
+ post_params=None,
148
+ files=None, auth_settings=None,
149
+ collection_formats=None,
150
+ _host=None,
151
+ _request_auth=None
152
+ ) -> RequestSerialized:
153
+
154
+ """Builds the HTTP request params needed by the request.
155
+ :param method: Method to call.
156
+ :param resource_path: Path to method endpoint.
157
+ :param path_params: Path parameters in the url.
158
+ :param query_params: Query parameters in the url.
159
+ :param header_params: Header parameters to be
160
+ placed in the request header.
161
+ :param body: Request body.
162
+ :param post_params dict: Request post form parameters,
163
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
164
+ :param auth_settings list: Auth Settings names for the request.
165
+ :param files dict: key -> filename, value -> filepath,
166
+ for `multipart/form-data`.
167
+ :param collection_formats: dict of collection formats for path, query,
168
+ header, and post parameters.
169
+ :param _request_auth: set to override the auth_settings for an a single
170
+ request; this effectively ignores the authentication
171
+ in the spec for a single request.
172
+ :return: tuple of form (path, http_method, query_params, header_params,
173
+ body, post_params, files)
174
+ """
138
175
 
139
176
  config = self.configuration
140
177
 
@@ -145,14 +182,17 @@ class ApiClient(object):
145
182
  header_params['Cookie'] = self.cookie
146
183
  if header_params:
147
184
  header_params = self.sanitize_for_serialization(header_params)
148
- header_params = dict(self.parameters_to_tuples(header_params,
149
- collection_formats))
185
+ header_params = dict(
186
+ self.parameters_to_tuples(header_params,collection_formats)
187
+ )
150
188
 
151
189
  # path parameters
152
190
  if path_params:
153
191
  path_params = self.sanitize_for_serialization(path_params)
154
- path_params = self.parameters_to_tuples(path_params,
155
- collection_formats)
192
+ path_params = self.parameters_to_tuples(
193
+ path_params,
194
+ collection_formats
195
+ )
156
196
  for k, v in path_params:
157
197
  # specified safe chars, encode everything
158
198
  resource_path = resource_path.replace(
@@ -160,31 +200,31 @@ class ApiClient(object):
160
200
  quote(str(v), safe=config.safe_chars_for_path_param)
161
201
  )
162
202
 
163
- # query parameters
164
- if query_params:
165
- query_params = self.sanitize_for_serialization(query_params)
166
- query_params = self.parameters_to_tuples(query_params,
167
- collection_formats)
168
-
169
203
  # post parameters
170
204
  if post_params or files:
171
205
  post_params = post_params if post_params else []
172
206
  post_params = self.sanitize_for_serialization(post_params)
173
- post_params = self.parameters_to_tuples(post_params,
174
- collection_formats)
207
+ post_params = self.parameters_to_tuples(
208
+ post_params,
209
+ collection_formats
210
+ )
175
211
  post_params.extend(self.files_parameters(files))
176
- if header_params['Content-Type'].startswith("multipart"):
177
- post_params = self.parameters_to_multipart(post_params,
178
- (dict) )
212
+
213
+ # auth setting
214
+ self.update_params_for_auth(
215
+ header_params,
216
+ query_params,
217
+ auth_settings,
218
+ resource_path,
219
+ method,
220
+ body,
221
+ request_auth=_request_auth
222
+ )
179
223
 
180
224
  # body
181
225
  if body:
182
226
  body = self.sanitize_for_serialization(body)
183
227
 
184
- # auth setting
185
- self.update_params_for_auth(header_params, query_params,
186
- auth_settings, resource_path, method, body)
187
-
188
228
  # request url
189
229
  if _host is None:
190
230
  url = self.configuration.host + resource_path
@@ -192,73 +232,106 @@ class ApiClient(object):
192
232
  # use server/host defined in path or operation instead
193
233
  url = _host + resource_path
194
234
 
235
+ # query parameters
236
+ if query_params:
237
+ query_params = self.sanitize_for_serialization(query_params)
238
+ url_query = self.parameters_to_url_query(
239
+ query_params,
240
+ collection_formats
241
+ )
242
+ url += "?" + url_query
243
+
244
+ return method, url, header_params, body, post_params
245
+
246
+
247
+ def call_api(
248
+ self,
249
+ method,
250
+ url,
251
+ header_params=None,
252
+ body=None,
253
+ post_params=None,
254
+ _request_timeout=None
255
+ ) -> rest.RESTResponse:
256
+ """Makes the HTTP request (synchronous)
257
+ :param method: Method to call.
258
+ :param url: Path to method endpoint.
259
+ :param header_params: Header parameters to be
260
+ placed in the request header.
261
+ :param body: Request body.
262
+ :param post_params dict: Request post form parameters,
263
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
264
+ :param _request_timeout: timeout setting for this request.
265
+ :return: RESTResponse
266
+ """
267
+
195
268
  try:
196
269
  # perform request and return response
197
- response_data = self.request(
198
- method, url, query_params=query_params, headers=header_params,
199
- post_params=post_params, body=body,
200
- _preload_content=_preload_content,
201
- _request_timeout=_request_timeout)
270
+ response_data = self.rest_client.request(
271
+ method, url,
272
+ headers=header_params,
273
+ body=body, post_params=post_params,
274
+ _request_timeout=_request_timeout
275
+ )
276
+
202
277
  except ApiException as e:
203
- e.body = e.body.decode('utf-8')
204
278
  raise e
205
279
 
206
- self.last_response = response_data
280
+ return response_data
281
+
282
+ def response_deserialize(
283
+ self,
284
+ response_data: rest.RESTResponse,
285
+ response_types_map: Optional[Dict[str, ApiResponseT]]=None
286
+ ) -> ApiResponse[ApiResponseT]:
287
+ """Deserializes response into an object.
288
+ :param response_data: RESTResponse object to be deserialized.
289
+ :param response_types_map: dict of response types.
290
+ :return: ApiResponse
291
+ """
207
292
 
208
- return_data = response_data
293
+ msg = "RESTResponse.read() must be called before passing it to response_deserialize()"
294
+ assert response_data.data is not None, msg
209
295
 
210
- if not _preload_content:
211
- return (return_data)
212
- return return_data
296
+ response_type = response_types_map.get(str(response_data.status), None)
297
+ if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:
298
+ # if not found, look for '1XX', '2XX', etc.
299
+ response_type = response_types_map.get(str(response_data.status)[0] + "XX", None)
213
300
 
214
301
  # deserialize response data
215
- if response_type:
216
- if response_type != (file_type,):
217
- encoding = "utf-8"
302
+ response_text = None
303
+ return_data = None
304
+ try:
305
+ if response_type == "bytearray":
306
+ return_data = response_data.data
307
+ elif response_type == "file":
308
+ return_data = self.__deserialize_file(response_data)
309
+ elif response_type is not None:
310
+ match = None
218
311
  content_type = response_data.getheader('content-type')
219
312
  if content_type is not None:
220
- match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type)
221
- if match:
222
- encoding = match.group(1)
223
- response_data.data = response_data.data.decode(encoding)
224
-
225
- return_data = self.deserialize(
226
- response_data,
227
- response_type,
228
- _check_type
229
- )
230
- else:
231
- return_data = None
313
+ match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type)
314
+ encoding = match.group(1) if match else "utf-8"
315
+ response_text = response_data.data.decode(encoding)
316
+ return_data = self.deserialize(response_text, response_type)
317
+ finally:
318
+ if not 200 <= response_data.status <= 299:
319
+ raise ApiException.from_response(
320
+ http_resp=response_data,
321
+ body=response_text,
322
+ data=return_data,
323
+ )
232
324
 
233
- if _return_http_data_only:
234
- return (return_data)
235
- else:
236
- return (return_data, response_data.status,
237
- response_data.getheaders())
325
+ return ApiResponse(
326
+ status_code = response_data.status,
327
+ data = return_data,
328
+ headers = response_data.getheaders(),
329
+ raw_data = response_data.data
330
+ )
238
331
 
239
- def parameters_to_multipart(self, params, collection_types):
240
- """Get parameters as list of tuples, formatting as json if value is collection_types
332
+ def sanitize_for_serialization(self, obj):
333
+ """Builds a JSON POST object.
241
334
 
242
- :param params: Parameters as list of two-tuples
243
- :param dict collection_types: Parameter collection types
244
- :return: Parameters as list of tuple or urllib3.fields.RequestField
245
- """
246
- new_params = []
247
- if collection_types is None:
248
- collection_types = (dict)
249
- for k, v in params.items() if isinstance(params, dict) else params: # noqa: E501
250
- if isinstance(v, collection_types): # v is instance of collection_type, formatting as application/json
251
- v = json.dumps(v, ensure_ascii=False).encode("utf-8")
252
- field = RequestField(k, v)
253
- field.make_multipart(content_type="application/json; charset=utf-8")
254
- new_params.append(field)
255
- else:
256
- new_params.append((k, v))
257
- return new_params
258
-
259
- @classmethod
260
- def sanitize_for_serialization(cls, obj):
261
- """Prepares data for transmission before it is sent with the rest client
262
335
  If obj is None, return None.
263
336
  If obj is str, int, long, float, bool, return directly.
264
337
  If obj is datetime.datetime, datetime.date
@@ -266,228 +339,102 @@ class ApiClient(object):
266
339
  If obj is list, sanitize each element in the list.
267
340
  If obj is dict, return the dict.
268
341
  If obj is OpenAPI model, return the properties dict.
269
- If obj is io.IOBase, return the bytes
342
+
270
343
  :param obj: The data to serialize.
271
344
  :return: The serialized form of data.
272
345
  """
273
- if isinstance(obj, (ModelNormal, ModelComposed)):
274
- return {
275
- key: cls.sanitize_for_serialization(val) for key, val in model_to_dict(obj, serialize=True).items()
276
- }
277
- elif isinstance(obj, io.IOBase):
278
- return cls.get_file_data_and_close_file(obj)
279
- elif isinstance(obj, (str, int, float, none_type, bool)):
346
+ if obj is None:
347
+ return None
348
+ elif isinstance(obj, self.PRIMITIVE_TYPES):
280
349
  return obj
281
- elif isinstance(obj, (datetime, date)):
350
+ elif isinstance(obj, list):
351
+ return [
352
+ self.sanitize_for_serialization(sub_obj) for sub_obj in obj
353
+ ]
354
+ elif isinstance(obj, tuple):
355
+ return tuple(
356
+ self.sanitize_for_serialization(sub_obj) for sub_obj in obj
357
+ )
358
+ elif isinstance(obj, (datetime.datetime, datetime.date)):
282
359
  return obj.isoformat()
283
- elif isinstance(obj, ModelSimple):
284
- return cls.sanitize_for_serialization(obj.value)
285
- elif isinstance(obj, (list, tuple)):
286
- return [cls.sanitize_for_serialization(item) for item in obj]
287
- if isinstance(obj, dict):
288
- return {key: cls.sanitize_for_serialization(val) for key, val in obj.items()}
289
- raise ApiValueError('Unable to prepare type {} for serialization'.format(obj.__class__.__name__))
290
-
291
- def deserialize(self, response, response_type, _check_type):
360
+
361
+ elif isinstance(obj, dict):
362
+ obj_dict = obj
363
+ else:
364
+ # Convert model obj to dict except
365
+ # attributes `openapi_types`, `attribute_map`
366
+ # and attributes which value is not None.
367
+ # Convert attribute name to json key in
368
+ # model definition for request.
369
+ obj_dict = obj.to_dict()
370
+
371
+ return {
372
+ key: self.sanitize_for_serialization(val)
373
+ for key, val in obj_dict.items()
374
+ }
375
+
376
+ def deserialize(self, response_text, response_type):
292
377
  """Deserializes response into an object.
293
378
 
294
379
  :param response: RESTResponse object to be deserialized.
295
- :param response_type: For the response, a tuple containing:
296
- valid classes
297
- a list containing valid classes (for list schemas)
298
- a dict containing a tuple of valid classes as the value
299
- Example values:
300
- (str,)
301
- (Pet,)
302
- (float, none_type)
303
- ([int, none_type],)
304
- ({str: (bool, str, int, float, date, datetime, str, none_type)},)
305
- :param _check_type: boolean, whether to check the types of the data
306
- received from the server
307
- :type _check_type: bool
380
+ :param response_type: class literal for
381
+ deserialized object, or string of class name.
308
382
 
309
383
  :return: deserialized object.
310
384
  """
311
- # handle file downloading
312
- # save response body into a tmp file and return the instance
313
- if response_type == (file_type,):
314
- content_disposition = response.getheader("Content-Disposition")
315
- return deserialize_file(response.data, self.configuration,
316
- content_disposition=content_disposition)
317
385
 
318
386
  # fetch data from response object
319
387
  try:
320
- received_data = json.loads(response.data)
388
+ data = json.loads(response_text)
321
389
  except ValueError:
322
- received_data = response.data
323
-
324
- # store our data under the key of 'received_data' so users have some
325
- # context if they are deserializing a string and the data type is wrong
326
- deserialized_data = validate_and_convert_types(
327
- received_data,
328
- response_type,
329
- ['received_data'],
330
- True,
331
- _check_type,
332
- configuration=self.configuration
333
- )
334
- return deserialized_data
390
+ data = response_text
335
391
 
336
- def call_api(
337
- self,
338
- resource_path: str,
339
- method: str,
340
- path_params: typing.Optional[typing.Dict[str, typing.Any]] = None,
341
- query_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None,
342
- header_params: typing.Optional[typing.Dict[str, typing.Any]] = None,
343
- body: typing.Optional[typing.Any] = None,
344
- post_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None,
345
- files: typing.Optional[typing.Dict[str, typing.List[io.IOBase]]] = None,
346
- response_type: typing.Optional[typing.Tuple[typing.Any]] = None,
347
- auth_settings: typing.Optional[typing.List[str]] = None,
348
- async_req: typing.Optional[bool] = None,
349
- _return_http_data_only: typing.Optional[bool] = None,
350
- collection_formats: typing.Optional[typing.Dict[str, str]] = None,
351
- _preload_content: bool = True,
352
- _request_timeout: typing.Optional[typing.Union[int, float, typing.Tuple]] = None,
353
- _host: typing.Optional[str] = None,
354
- _check_type: typing.Optional[bool] = None
355
- ):
356
- """Makes the HTTP request (synchronous) and returns deserialized data.
357
-
358
- To make an async_req request, set the async_req parameter.
392
+ return self.__deserialize(data, response_type)
359
393
 
360
- :param resource_path: Path to method endpoint.
361
- :param method: Method to call.
362
- :param path_params: Path parameters in the url.
363
- :param query_params: Query parameters in the url.
364
- :param header_params: Header parameters to be
365
- placed in the request header.
366
- :param body: Request body.
367
- :param post_params dict: Request post form parameters,
368
- for `application/x-www-form-urlencoded`, `multipart/form-data`.
369
- :param auth_settings list: Auth Settings names for the request.
370
- :param response_type: For the response, a tuple containing:
371
- valid classes
372
- a list containing valid classes (for list schemas)
373
- a dict containing a tuple of valid classes as the value
374
- Example values:
375
- (str,)
376
- (Pet,)
377
- (float, none_type)
378
- ([int, none_type],)
379
- ({str: (bool, str, int, float, date, datetime, str, none_type)},)
380
- :param files: key -> field name, value -> a list of open file
381
- objects for `multipart/form-data`.
382
- :type files: dict
383
- :param async_req bool: execute request asynchronously
384
- :type async_req: bool, optional
385
- :param _return_http_data_only: response data without head status code
386
- and headers
387
- :type _return_http_data_only: bool, optional
388
- :param collection_formats: dict of collection formats for path, query,
389
- header, and post parameters.
390
- :type collection_formats: dict, optional
391
- :param _preload_content: if False, the urllib3.HTTPResponse object will
392
- be returned without reading/decoding response
393
- data. Default is True.
394
- :type _preload_content: bool, optional
395
- :param _request_timeout: timeout setting for this request. If one
396
- number provided, it will be total request
397
- timeout. It can also be a pair (tuple) of
398
- (connection, read) timeouts.
399
- :param _check_type: boolean describing if the data back from the server
400
- should have its type checked.
401
- :type _check_type: bool, optional
402
- :return:
403
- If async_req parameter is True,
404
- the request will be called asynchronously.
405
- The method will return the request thread.
406
- If parameter async_req is False or missing,
407
- then the method will return the response directly.
394
+ def __deserialize(self, data, klass):
395
+ """Deserializes dict, list, str into an object.
396
+
397
+ :param data: dict, list or str.
398
+ :param klass: class literal, or string of class name.
399
+
400
+ :return: object.
408
401
  """
409
- if not async_req:
410
- return self.__call_api(resource_path, method,
411
- path_params, query_params, header_params,
412
- body, post_params, files,
413
- response_type, auth_settings,
414
- _return_http_data_only, collection_formats,
415
- _preload_content, _request_timeout, _host,
416
- _check_type)
417
-
418
- return self.pool.apply_async(self.__call_api, (resource_path,
419
- method, path_params,
420
- query_params,
421
- header_params, body,
422
- post_params, files,
423
- response_type,
424
- auth_settings,
425
- _return_http_data_only,
426
- collection_formats,
427
- _preload_content,
428
- _request_timeout,
429
- _host, _check_type))
430
-
431
- def request(self, method, url, query_params=None, headers=None,
432
- post_params=None, body=None, _preload_content=True,
433
- _request_timeout=None):
434
- """Makes the HTTP request using RESTClient."""
435
- if method == "GET":
436
- return self.rest_client.GET(url,
437
- query_params=query_params,
438
- _preload_content=_preload_content,
439
- _request_timeout=_request_timeout,
440
- headers=headers)
441
- elif method == "HEAD":
442
- return self.rest_client.HEAD(url,
443
- query_params=query_params,
444
- _preload_content=_preload_content,
445
- _request_timeout=_request_timeout,
446
- headers=headers)
447
- elif method == "OPTIONS":
448
- return self.rest_client.OPTIONS(url,
449
- query_params=query_params,
450
- headers=headers,
451
- post_params=post_params,
452
- _preload_content=_preload_content,
453
- _request_timeout=_request_timeout,
454
- body=body)
455
- elif method == "POST":
456
- return self.rest_client.POST(url,
457
- query_params=query_params,
458
- headers=headers,
459
- post_params=post_params,
460
- _preload_content=_preload_content,
461
- _request_timeout=_request_timeout,
462
- body=body)
463
- elif method == "PUT":
464
- return self.rest_client.PUT(url,
465
- query_params=query_params,
466
- headers=headers,
467
- post_params=post_params,
468
- _preload_content=_preload_content,
469
- _request_timeout=_request_timeout,
470
- body=body)
471
- elif method == "PATCH":
472
- return self.rest_client.PATCH(url,
473
- query_params=query_params,
474
- headers=headers,
475
- post_params=post_params,
476
- _preload_content=_preload_content,
477
- _request_timeout=_request_timeout,
478
- body=body)
479
- elif method == "DELETE":
480
- return self.rest_client.DELETE(url,
481
- query_params=query_params,
482
- headers=headers,
483
- _preload_content=_preload_content,
484
- _request_timeout=_request_timeout,
485
- body=body)
402
+ if data is None:
403
+ return None
404
+
405
+ if isinstance(klass, str):
406
+ if klass.startswith('List['):
407
+ m = re.match(r'List\[(.*)]', klass)
408
+ assert m is not None, "Malformed List type definition"
409
+ sub_kls = m.group(1)
410
+ return [self.__deserialize(sub_data, sub_kls)
411
+ for sub_data in data]
412
+
413
+ if klass.startswith('Dict['):
414
+ m = re.match(r'Dict\[([^,]*), (.*)]', klass)
415
+ assert m is not None, "Malformed Dict type definition"
416
+ sub_kls = m.group(2)
417
+ return {k: self.__deserialize(v, sub_kls)
418
+ for k, v in data.items()}
419
+
420
+ # convert str to class
421
+ if klass in self.NATIVE_TYPES_MAPPING:
422
+ klass = self.NATIVE_TYPES_MAPPING[klass]
423
+ else:
424
+ klass = getattr(cosmotech_api.models, klass)
425
+
426
+ if klass in self.PRIMITIVE_TYPES:
427
+ return self.__deserialize_primitive(data, klass)
428
+ elif klass == object:
429
+ return self.__deserialize_object(data)
430
+ elif klass == datetime.date:
431
+ return self.__deserialize_date(data)
432
+ elif klass == datetime.datetime:
433
+ return self.__deserialize_datetime(data)
434
+ elif issubclass(klass, Enum):
435
+ return self.__deserialize_enum(data, klass)
486
436
  else:
487
- raise ApiValueError(
488
- "http method must be `GET`, `HEAD`, `OPTIONS`,"
489
- " `POST`, `PATCH`, `PUT` or `DELETE`."
490
- )
437
+ return self.__deserialize_model(data, klass)
491
438
 
492
439
  def parameters_to_tuples(self, params, collection_formats):
493
440
  """Get parameters as list of tuples, formatting collections.
@@ -496,10 +443,10 @@ class ApiClient(object):
496
443
  :param dict collection_formats: Parameter collection formats
497
444
  :return: Parameters as list of tuples, collections formatted
498
445
  """
499
- new_params = []
446
+ new_params: List[Tuple[str, str]] = []
500
447
  if collection_formats is None:
501
448
  collection_formats = {}
502
- for k, v in params.items() if isinstance(params, dict) else params: # noqa: E501
449
+ for k, v in params.items() if isinstance(params, dict) else params:
503
450
  if k in collection_formats:
504
451
  collection_format = collection_formats[k]
505
452
  if collection_format == 'multi':
@@ -519,349 +466,294 @@ class ApiClient(object):
519
466
  new_params.append((k, v))
520
467
  return new_params
521
468
 
522
- @staticmethod
523
- def get_file_data_and_close_file(file_instance: io.IOBase) -> bytes:
524
- file_data = file_instance.read()
525
- file_instance.close()
526
- return file_data
469
+ def parameters_to_url_query(self, params, collection_formats):
470
+ """Get parameters as list of tuples, formatting collections.
527
471
 
528
- def files_parameters(self, files: typing.Optional[typing.Dict[str, typing.List[io.IOBase]]] = None):
472
+ :param params: Parameters as dict or list of two-tuples
473
+ :param dict collection_formats: Parameter collection formats
474
+ :return: URL query string (e.g. a=Hello%20World&b=123)
475
+ """
476
+ new_params: List[Tuple[str, str]] = []
477
+ if collection_formats is None:
478
+ collection_formats = {}
479
+ for k, v in params.items() if isinstance(params, dict) else params:
480
+ if isinstance(v, bool):
481
+ v = str(v).lower()
482
+ if isinstance(v, (int, float)):
483
+ v = str(v)
484
+ if isinstance(v, dict):
485
+ v = json.dumps(v)
486
+
487
+ if k in collection_formats:
488
+ collection_format = collection_formats[k]
489
+ if collection_format == 'multi':
490
+ new_params.extend((k, str(value)) for value in v)
491
+ else:
492
+ if collection_format == 'ssv':
493
+ delimiter = ' '
494
+ elif collection_format == 'tsv':
495
+ delimiter = '\t'
496
+ elif collection_format == 'pipes':
497
+ delimiter = '|'
498
+ else: # csv is the default
499
+ delimiter = ','
500
+ new_params.append(
501
+ (k, delimiter.join(quote(str(value)) for value in v))
502
+ )
503
+ else:
504
+ new_params.append((k, quote(str(v))))
505
+
506
+ return "&".join(["=".join(map(str, item)) for item in new_params])
507
+
508
+ def files_parameters(self, files=None):
529
509
  """Builds form parameters.
530
510
 
531
- :param files: None or a dict with key=param_name and
532
- value is a list of open file objects
533
- :return: List of tuples of form parameters with file data
511
+ :param files: File parameters.
512
+ :return: Form parameters with files.
534
513
  """
535
- if files is None:
536
- return []
537
-
538
514
  params = []
539
- for param_name, file_instances in files.items():
540
- if file_instances is None:
541
- # if the file field is nullable, skip None values
542
- continue
543
- for file_instance in file_instances:
544
- if file_instance is None:
545
- # if the file field is nullable, skip None values
515
+
516
+ if files:
517
+ for k, v in files.items():
518
+ if not v:
546
519
  continue
547
- if file_instance.closed is True:
548
- raise ApiValueError(
549
- "Cannot read a closed file. The passed in file_type "
550
- "for %s must be open." % param_name
551
- )
552
- filename = os.path.basename(file_instance.name)
553
- filedata = self.get_file_data_and_close_file(file_instance)
554
- mimetype = (mimetypes.guess_type(filename)[0] or
555
- 'application/octet-stream')
556
- params.append(
557
- tuple([param_name, tuple([filename, filedata, mimetype])]))
520
+ file_names = v if type(v) is list else [v]
521
+ for n in file_names:
522
+ with open(n, 'rb') as f:
523
+ filename = os.path.basename(f.name)
524
+ filedata = f.read()
525
+ mimetype = (
526
+ mimetypes.guess_type(filename)[0]
527
+ or 'application/octet-stream'
528
+ )
529
+ params.append(
530
+ tuple([k, tuple([filename, filedata, mimetype])])
531
+ )
558
532
 
559
533
  return params
560
534
 
561
- def select_header_accept(self, accepts):
535
+ def select_header_accept(self, accepts: List[str]) -> Optional[str]:
562
536
  """Returns `Accept` based on an array of accepts provided.
563
537
 
564
538
  :param accepts: List of headers.
565
539
  :return: Accept (e.g. application/json).
566
540
  """
567
541
  if not accepts:
568
- return
542
+ return None
569
543
 
570
- accepts = [x.lower() for x in accepts]
544
+ for accept in accepts:
545
+ if re.search('json', accept, re.IGNORECASE):
546
+ return accept
571
547
 
572
- if 'application/json' in accepts:
573
- return 'application/json'
574
- else:
575
- return ', '.join(accepts)
548
+ return accepts[0]
576
549
 
577
- def select_header_content_type(self, content_types, method=None, body=None):
550
+ def select_header_content_type(self, content_types):
578
551
  """Returns `Content-Type` based on an array of content_types provided.
579
552
 
580
553
  :param content_types: List of content-types.
581
- :param method: http method (e.g. POST, PATCH).
582
- :param body: http body to send.
583
554
  :return: Content-Type (e.g. application/json).
584
555
  """
585
556
  if not content_types:
586
- return 'application/json'
587
-
588
- content_types = [x.lower() for x in content_types]
557
+ return None
589
558
 
590
- if (method == 'PATCH' and
591
- 'application/json-patch+json' in content_types and
592
- isinstance(body, list)):
593
- return 'application/json-patch+json'
559
+ for content_type in content_types:
560
+ if re.search('json', content_type, re.IGNORECASE):
561
+ return content_type
594
562
 
595
- if 'application/json' in content_types or '*/*' in content_types:
596
- return 'application/json'
597
- else:
598
- return content_types[0]
563
+ return content_types[0]
599
564
 
600
- def update_params_for_auth(self, headers, queries, auth_settings,
601
- resource_path, method, body):
565
+ def update_params_for_auth(
566
+ self,
567
+ headers,
568
+ queries,
569
+ auth_settings,
570
+ resource_path,
571
+ method,
572
+ body,
573
+ request_auth=None
574
+ ) -> None:
602
575
  """Updates header and query params based on authentication setting.
603
576
 
604
577
  :param headers: Header parameters dict to be updated.
605
578
  :param queries: Query parameters tuple list to be updated.
606
579
  :param auth_settings: Authentication setting identifiers list.
607
- :param resource_path: A string representation of the HTTP request resource path.
608
- :param method: A string representation of the HTTP request method.
609
- :param body: A object representing the body of the HTTP request.
610
- The object type is the return value of _encoder.default().
580
+ :resource_path: A string representation of the HTTP request resource path.
581
+ :method: A string representation of the HTTP request method.
582
+ :body: A object representing the body of the HTTP request.
583
+ The object type is the return value of sanitize_for_serialization().
584
+ :param request_auth: if set, the provided settings will
585
+ override the token in the configuration.
611
586
  """
612
587
  if not auth_settings:
613
588
  return
614
589
 
615
- for auth in auth_settings:
616
- auth_setting = self.configuration.auth_settings().get(auth)
617
- if auth_setting:
618
- if auth_setting['in'] == 'cookie':
619
- headers['Cookie'] = auth_setting['value']
620
- elif auth_setting['in'] == 'header':
621
- if auth_setting['type'] != 'http-signature':
622
- headers[auth_setting['key']] = auth_setting['value']
623
- elif auth_setting['in'] == 'query':
624
- queries.append((auth_setting['key'], auth_setting['value']))
625
- else:
626
- raise ApiValueError(
627
- 'Authentication token must be in `query` or `header`'
590
+ if request_auth:
591
+ self._apply_auth_params(
592
+ headers,
593
+ queries,
594
+ resource_path,
595
+ method,
596
+ body,
597
+ request_auth
598
+ )
599
+ else:
600
+ for auth in auth_settings:
601
+ auth_setting = self.configuration.auth_settings().get(auth)
602
+ if auth_setting:
603
+ self._apply_auth_params(
604
+ headers,
605
+ queries,
606
+ resource_path,
607
+ method,
608
+ body,
609
+ auth_setting
628
610
  )
629
611
 
612
+ def _apply_auth_params(
613
+ self,
614
+ headers,
615
+ queries,
616
+ resource_path,
617
+ method,
618
+ body,
619
+ auth_setting
620
+ ) -> None:
621
+ """Updates the request parameters based on a single auth_setting
630
622
 
631
- class Endpoint(object):
632
- def __init__(self, settings=None, params_map=None, root_map=None,
633
- headers_map=None, api_client=None, callable=None):
634
- """Creates an endpoint
635
-
636
- Args:
637
- settings (dict): see below key value pairs
638
- 'response_type' (tuple/None): response type
639
- 'auth' (list): a list of auth type keys
640
- 'endpoint_path' (str): the endpoint path
641
- 'operation_id' (str): endpoint string identifier
642
- 'http_method' (str): POST/PUT/PATCH/GET etc
643
- 'servers' (list): list of str servers that this endpoint is at
644
- params_map (dict): see below key value pairs
645
- 'all' (list): list of str endpoint parameter names
646
- 'required' (list): list of required parameter names
647
- 'nullable' (list): list of nullable parameter names
648
- 'enum' (list): list of parameters with enum values
649
- 'validation' (list): list of parameters with validations
650
- root_map
651
- 'validations' (dict): the dict mapping endpoint parameter tuple
652
- paths to their validation dictionaries
653
- 'allowed_values' (dict): the dict mapping endpoint parameter
654
- tuple paths to their allowed_values (enum) dictionaries
655
- 'openapi_types' (dict): param_name to openapi type
656
- 'attribute_map' (dict): param_name to camelCase name
657
- 'location_map' (dict): param_name to 'body', 'file', 'form',
658
- 'header', 'path', 'query'
659
- collection_format_map (dict): param_name to `csv` etc.
660
- headers_map (dict): see below key value pairs
661
- 'accept' (list): list of Accept header strings
662
- 'content_type' (list): list of Content-Type header strings
663
- api_client (ApiClient) api client instance
664
- callable (function): the function which is invoked when the
665
- Endpoint is called
623
+ :param headers: Header parameters dict to be updated.
624
+ :param queries: Query parameters tuple list to be updated.
625
+ :resource_path: A string representation of the HTTP request resource path.
626
+ :method: A string representation of the HTTP request method.
627
+ :body: A object representing the body of the HTTP request.
628
+ The object type is the return value of sanitize_for_serialization().
629
+ :param auth_setting: auth settings for the endpoint
666
630
  """
667
- self.settings = settings
668
- self.params_map = params_map
669
- self.params_map['all'].extend([
670
- 'async_req',
671
- '_host_index',
672
- '_preload_content',
673
- '_request_timeout',
674
- '_return_http_data_only',
675
- '_check_input_type',
676
- '_check_return_type',
677
- '_content_type',
678
- '_spec_property_naming'
679
- ])
680
- self.params_map['nullable'].extend(['_request_timeout'])
681
- self.validations = root_map['validations']
682
- self.allowed_values = root_map['allowed_values']
683
- self.openapi_types = root_map['openapi_types']
684
- extra_types = {
685
- 'async_req': (bool,),
686
- '_host_index': (none_type, int),
687
- '_preload_content': (bool,),
688
- '_request_timeout': (none_type, float, (float,), [float], int, (int,), [int]),
689
- '_return_http_data_only': (bool,),
690
- '_check_input_type': (bool,),
691
- '_check_return_type': (bool,),
692
- '_spec_property_naming': (bool,),
693
- '_content_type': (none_type, str)
694
- }
695
- self.openapi_types.update(extra_types)
696
- self.attribute_map = root_map['attribute_map']
697
- self.location_map = root_map['location_map']
698
- self.collection_format_map = root_map['collection_format_map']
699
- self.headers_map = headers_map
700
- self.api_client = api_client
701
- self.callable = callable
702
-
703
- def __validate_inputs(self, kwargs):
704
- for param in self.params_map['enum']:
705
- if param in kwargs:
706
- check_allowed_values(
707
- self.allowed_values,
708
- (param,),
709
- kwargs[param]
710
- )
631
+ if auth_setting['in'] == 'cookie':
632
+ headers['Cookie'] = auth_setting['value']
633
+ elif auth_setting['in'] == 'header':
634
+ if auth_setting['type'] != 'http-signature':
635
+ headers[auth_setting['key']] = auth_setting['value']
636
+ elif auth_setting['in'] == 'query':
637
+ queries.append((auth_setting['key'], auth_setting['value']))
638
+ else:
639
+ raise ApiValueError(
640
+ 'Authentication token must be in `query` or `header`'
641
+ )
711
642
 
712
- for param in self.params_map['validation']:
713
- if param in kwargs:
714
- check_validations(
715
- self.validations,
716
- (param,),
717
- kwargs[param],
718
- configuration=self.api_client.configuration
719
- )
643
+ def __deserialize_file(self, response):
644
+ """Deserializes body to file
720
645
 
721
- if kwargs['_check_input_type'] is False:
722
- return
646
+ Saves response body into a file in a temporary folder,
647
+ using the filename from the `Content-Disposition` header if provided.
648
+
649
+ handle file downloading
650
+ save response body into a tmp file and return the instance
723
651
 
724
- for key, value in kwargs.items():
725
- fixed_val = validate_and_convert_types(
726
- value,
727
- self.openapi_types[key],
728
- [key],
729
- kwargs['_spec_property_naming'],
730
- kwargs['_check_input_type'],
731
- configuration=self.api_client.configuration
652
+ :param response: RESTResponse.
653
+ :return: file path.
654
+ """
655
+ fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
656
+ os.close(fd)
657
+ os.remove(path)
658
+
659
+ content_disposition = response.getheader("Content-Disposition")
660
+ if content_disposition:
661
+ m = re.search(
662
+ r'filename=[\'"]?([^\'"\s]+)[\'"]?',
663
+ content_disposition
732
664
  )
733
- kwargs[key] = fixed_val
734
-
735
- def __gather_params(self, kwargs):
736
- params = {
737
- 'body': None,
738
- 'collection_format': {},
739
- 'file': {},
740
- 'form': [],
741
- 'header': {},
742
- 'path': {},
743
- 'query': []
744
- }
665
+ assert m is not None, "Unexpected 'content-disposition' header value"
666
+ filename = m.group(1)
667
+ path = os.path.join(os.path.dirname(path), filename)
745
668
 
746
- for param_name, param_value in kwargs.items():
747
- param_location = self.location_map.get(param_name)
748
- if param_location is None:
749
- continue
750
- if param_location:
751
- if param_location == 'body':
752
- params['body'] = param_value
753
- continue
754
- base_name = self.attribute_map[param_name]
755
- if (param_location == 'form' and
756
- self.openapi_types[param_name] == (file_type,)):
757
- params['file'][base_name] = [param_value]
758
- elif (param_location == 'form' and
759
- self.openapi_types[param_name] == ([file_type],)):
760
- # param_value is already a list
761
- params['file'][base_name] = param_value
762
- elif param_location in {'form', 'query'}:
763
- param_value_full = (base_name, param_value)
764
- params[param_location].append(param_value_full)
765
- if param_location not in {'form', 'query'}:
766
- params[param_location][base_name] = param_value
767
- collection_format = self.collection_format_map.get(param_name)
768
- if collection_format:
769
- params['collection_format'][base_name] = collection_format
669
+ with open(path, "wb") as f:
670
+ f.write(response.data)
770
671
 
771
- return params
672
+ return path
673
+
674
+ def __deserialize_primitive(self, data, klass):
675
+ """Deserializes string to primitive type.
772
676
 
773
- def __call__(self, *args, **kwargs):
774
- """ This method is invoked when endpoints are called
775
- Example:
677
+ :param data: str.
678
+ :param klass: class literal.
776
679
 
777
- api_instance = ConnectorApi()
778
- api_instance.find_all_connectors # this is an instance of the class Endpoint
779
- api_instance.find_all_connectors() # this invokes api_instance.find_all_connectors.__call__()
780
- which then invokes the callable functions stored in that endpoint at
781
- api_instance.find_all_connectors.callable or self.callable in this class
680
+ :return: int, long, float, str, bool.
681
+ """
682
+ try:
683
+ return klass(data)
684
+ except UnicodeEncodeError:
685
+ return str(data)
686
+ except TypeError:
687
+ return data
688
+
689
+ def __deserialize_object(self, value):
690
+ """Return an original value.
782
691
 
692
+ :return: object.
783
693
  """
784
- return self.callable(self, *args, **kwargs)
694
+ return value
785
695
 
786
- def call_with_http_info(self, **kwargs):
696
+ def __deserialize_date(self, string):
697
+ """Deserializes string to date.
787
698
 
699
+ :param string: str.
700
+ :return: date.
701
+ """
788
702
  try:
789
- index = self.api_client.configuration.server_operation_index.get(
790
- self.settings['operation_id'], self.api_client.configuration.server_index
791
- ) if kwargs['_host_index'] is None else kwargs['_host_index']
792
- server_variables = self.api_client.configuration.server_operation_variables.get(
793
- self.settings['operation_id'], self.api_client.configuration.server_variables
794
- )
795
- _host = self.api_client.configuration.get_host_from_settings(
796
- index, variables=server_variables, servers=self.settings['servers']
703
+ return parse(string).date()
704
+ except ImportError:
705
+ return string
706
+ except ValueError:
707
+ raise rest.ApiException(
708
+ status=0,
709
+ reason="Failed to parse `{0}` as date object".format(string)
797
710
  )
798
- except IndexError:
799
- if self.settings['servers']:
800
- raise ApiValueError(
801
- "Invalid host index. Must be 0 <= index < %s" %
802
- len(self.settings['servers'])
803
- )
804
- _host = None
805
-
806
- for key, value in kwargs.items():
807
- if key not in self.params_map['all']:
808
- raise ApiTypeError(
809
- "Got an unexpected parameter '%s'"
810
- " to method `%s`" %
811
- (key, self.settings['operation_id'])
812
- )
813
- # only throw this nullable ApiValueError if _check_input_type
814
- # is False, if _check_input_type==True we catch this case
815
- # in self.__validate_inputs
816
- if (key not in self.params_map['nullable'] and value is None
817
- and kwargs['_check_input_type'] is False):
818
- raise ApiValueError(
819
- "Value may not be None for non-nullable parameter `%s`"
820
- " when calling `%s`" %
821
- (key, self.settings['operation_id'])
822
- )
823
711
 
824
- for key in self.params_map['required']:
825
- if key not in kwargs.keys():
826
- raise ApiValueError(
827
- "Missing the required parameter `%s` when calling "
828
- "`%s`" % (key, self.settings['operation_id'])
712
+ def __deserialize_datetime(self, string):
713
+ """Deserializes string to datetime.
714
+
715
+ The string should be in iso8601 datetime format.
716
+
717
+ :param string: str.
718
+ :return: datetime.
719
+ """
720
+ try:
721
+ return parse(string)
722
+ except ImportError:
723
+ return string
724
+ except ValueError:
725
+ raise rest.ApiException(
726
+ status=0,
727
+ reason=(
728
+ "Failed to parse `{0}` as datetime object"
729
+ .format(string)
829
730
  )
731
+ )
830
732
 
831
- self.__validate_inputs(kwargs)
733
+ def __deserialize_enum(self, data, klass):
734
+ """Deserializes primitive type to enum.
832
735
 
833
- params = self.__gather_params(kwargs)
736
+ :param data: primitive type.
737
+ :param klass: class literal.
738
+ :return: enum value.
739
+ """
740
+ try:
741
+ return klass(data)
742
+ except ValueError:
743
+ raise rest.ApiException(
744
+ status=0,
745
+ reason=(
746
+ "Failed to parse `{0}` as `{1}`"
747
+ .format(data, klass)
748
+ )
749
+ )
834
750
 
835
- accept_headers_list = self.headers_map['accept']
836
- if accept_headers_list:
837
- params['header']['Accept'] = self.api_client.select_header_accept(
838
- accept_headers_list)
751
+ def __deserialize_model(self, data, klass):
752
+ """Deserializes list or dict to model.
839
753
 
840
- if kwargs.get('_content_type'):
841
- params['header']['Content-Type'] = kwargs['_content_type']
842
- else:
843
- content_type_headers_list = self.headers_map['content_type']
844
- if content_type_headers_list:
845
- if params['body'] != "":
846
- header_list = self.api_client.select_header_content_type(
847
- content_type_headers_list, self.settings['http_method'],
848
- params['body'])
849
- params['header']['Content-Type'] = header_list
850
-
851
- return self.api_client.call_api(
852
- self.settings['endpoint_path'], self.settings['http_method'],
853
- params['path'],
854
- params['query'],
855
- params['header'],
856
- body=params['body'],
857
- post_params=params['form'],
858
- files=params['file'],
859
- response_type=self.settings['response_type'],
860
- auth_settings=self.settings['auth'],
861
- async_req=kwargs['async_req'],
862
- _check_type=kwargs['_check_return_type'],
863
- _return_http_data_only=kwargs['_return_http_data_only'],
864
- _preload_content=kwargs['_preload_content'],
865
- _request_timeout=kwargs['_request_timeout'],
866
- _host=_host,
867
- collection_formats=params['collection_format'])
754
+ :param data: dict, list.
755
+ :param klass: class literal.
756
+ :return: model object.
757
+ """
758
+
759
+ return klass.from_dict(data)