gsctl 0.29.0a20250114__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. graphscope/flex/rest/__init__.py +106 -0
  2. graphscope/flex/rest/api/__init__.py +12 -0
  3. graphscope/flex/rest/api/alert_api.py +2790 -0
  4. graphscope/flex/rest/api/data_source_api.py +1177 -0
  5. graphscope/flex/rest/api/deployment_api.py +1323 -0
  6. graphscope/flex/rest/api/graph_api.py +2813 -0
  7. graphscope/flex/rest/api/job_api.py +1408 -0
  8. graphscope/flex/rest/api/service_api.py +1316 -0
  9. graphscope/flex/rest/api/stored_procedure_api.py +1454 -0
  10. graphscope/flex/rest/api/utils_api.py +310 -0
  11. graphscope/flex/rest/api_client.py +789 -0
  12. graphscope/flex/rest/api_response.py +21 -0
  13. graphscope/flex/rest/configuration.py +451 -0
  14. graphscope/flex/rest/exceptions.py +200 -0
  15. graphscope/flex/rest/models/__init__.py +82 -0
  16. graphscope/flex/rest/models/base_edge_type.py +102 -0
  17. graphscope/flex/rest/models/base_edge_type_vertex_type_pair_relations_inner.py +108 -0
  18. graphscope/flex/rest/models/base_edge_type_vertex_type_pair_relations_inner_x_csr_params.py +98 -0
  19. graphscope/flex/rest/models/base_property_meta.py +105 -0
  20. graphscope/flex/rest/models/base_vertex_type.py +96 -0
  21. graphscope/flex/rest/models/base_vertex_type_x_csr_params.py +88 -0
  22. graphscope/flex/rest/models/column_mapping.py +94 -0
  23. graphscope/flex/rest/models/column_mapping_column.py +90 -0
  24. graphscope/flex/rest/models/create_alert_receiver_request.py +103 -0
  25. graphscope/flex/rest/models/create_alert_rule_request.py +112 -0
  26. graphscope/flex/rest/models/create_dataloading_job_response.py +88 -0
  27. graphscope/flex/rest/models/create_edge_type.py +114 -0
  28. graphscope/flex/rest/models/create_graph_request.py +106 -0
  29. graphscope/flex/rest/models/create_graph_response.py +88 -0
  30. graphscope/flex/rest/models/create_graph_schema_request.py +106 -0
  31. graphscope/flex/rest/models/create_property_meta.py +105 -0
  32. graphscope/flex/rest/models/create_stored_proc_request.py +101 -0
  33. graphscope/flex/rest/models/create_stored_proc_response.py +88 -0
  34. graphscope/flex/rest/models/create_vertex_type.py +108 -0
  35. graphscope/flex/rest/models/dataloading_job_config.py +136 -0
  36. graphscope/flex/rest/models/dataloading_job_config_edges_inner.py +92 -0
  37. graphscope/flex/rest/models/dataloading_job_config_loading_config.py +104 -0
  38. graphscope/flex/rest/models/dataloading_job_config_loading_config_format.py +90 -0
  39. graphscope/flex/rest/models/dataloading_job_config_vertices_inner.py +88 -0
  40. graphscope/flex/rest/models/dataloading_mr_job_config.py +88 -0
  41. graphscope/flex/rest/models/date_type.py +88 -0
  42. graphscope/flex/rest/models/edge_mapping.py +122 -0
  43. graphscope/flex/rest/models/edge_mapping_type_triplet.py +92 -0
  44. graphscope/flex/rest/models/error.py +90 -0
  45. graphscope/flex/rest/models/get_alert_message_response.py +123 -0
  46. graphscope/flex/rest/models/get_alert_receiver_response.py +107 -0
  47. graphscope/flex/rest/models/get_alert_rule_response.py +114 -0
  48. graphscope/flex/rest/models/get_edge_type.py +116 -0
  49. graphscope/flex/rest/models/get_graph_response.py +139 -0
  50. graphscope/flex/rest/models/get_graph_schema_response.py +106 -0
  51. graphscope/flex/rest/models/get_pod_log_response.py +88 -0
  52. graphscope/flex/rest/models/get_property_meta.py +107 -0
  53. graphscope/flex/rest/models/get_resource_usage_response.py +105 -0
  54. graphscope/flex/rest/models/get_storage_usage_response.py +88 -0
  55. graphscope/flex/rest/models/get_stored_proc_response.py +130 -0
  56. graphscope/flex/rest/models/get_vertex_type.py +110 -0
  57. graphscope/flex/rest/models/gs_data_type.py +152 -0
  58. graphscope/flex/rest/models/job_status.py +107 -0
  59. graphscope/flex/rest/models/long_text.py +93 -0
  60. graphscope/flex/rest/models/node_status.py +94 -0
  61. graphscope/flex/rest/models/parameter.py +96 -0
  62. graphscope/flex/rest/models/pod_status.py +108 -0
  63. graphscope/flex/rest/models/primitive_type.py +95 -0
  64. graphscope/flex/rest/models/resource_usage.py +92 -0
  65. graphscope/flex/rest/models/running_deployment_info.py +128 -0
  66. graphscope/flex/rest/models/running_deployment_status.py +124 -0
  67. graphscope/flex/rest/models/schema_mapping.py +106 -0
  68. graphscope/flex/rest/models/service_status.py +112 -0
  69. graphscope/flex/rest/models/service_status_sdk_endpoints.py +94 -0
  70. graphscope/flex/rest/models/start_service_request.py +88 -0
  71. graphscope/flex/rest/models/stored_procedure_meta.py +126 -0
  72. graphscope/flex/rest/models/string_type.py +92 -0
  73. graphscope/flex/rest/models/string_type_string.py +124 -0
  74. graphscope/flex/rest/models/temporal_type.py +92 -0
  75. graphscope/flex/rest/models/temporal_type_temporal.py +138 -0
  76. graphscope/flex/rest/models/time_stamp_type.py +88 -0
  77. graphscope/flex/rest/models/update_alert_message_status_request.py +97 -0
  78. graphscope/flex/rest/models/update_stored_proc_request.py +88 -0
  79. graphscope/flex/rest/models/upload_file_response.py +90 -0
  80. graphscope/flex/rest/models/vertex_mapping.py +100 -0
  81. graphscope/flex/rest/py.typed +0 -0
  82. graphscope/flex/rest/rest.py +258 -0
  83. graphscope/gsctl/V6D_VERSION +1 -0
  84. graphscope/gsctl/VERSION +1 -0
  85. graphscope/gsctl/__init__.py +22 -0
  86. graphscope/gsctl/commands/__init__.py +148 -0
  87. graphscope/gsctl/commands/common.py +200 -0
  88. graphscope/gsctl/commands/dev.py +448 -0
  89. graphscope/gsctl/commands/insight/__init__.py +17 -0
  90. graphscope/gsctl/commands/insight/glob.py +234 -0
  91. graphscope/gsctl/commands/insight/graph.py +205 -0
  92. graphscope/gsctl/commands/interactive/__init__.py +17 -0
  93. graphscope/gsctl/commands/interactive/glob.py +280 -0
  94. graphscope/gsctl/commands/interactive/graph.py +259 -0
  95. graphscope/gsctl/config.py +221 -0
  96. graphscope/gsctl/gsctl.py +51 -0
  97. graphscope/gsctl/impl/__init__.py +64 -0
  98. graphscope/gsctl/impl/alert.py +135 -0
  99. graphscope/gsctl/impl/common.py +53 -0
  100. graphscope/gsctl/impl/datasource.py +80 -0
  101. graphscope/gsctl/impl/deployment.py +62 -0
  102. graphscope/gsctl/impl/graph.py +150 -0
  103. graphscope/gsctl/impl/job.py +63 -0
  104. graphscope/gsctl/impl/service.py +62 -0
  105. graphscope/gsctl/impl/stored_procedure.py +92 -0
  106. graphscope/gsctl/impl/utils.py +38 -0
  107. graphscope/gsctl/scripts/install_deps.sh +969 -0
  108. graphscope/gsctl/tests/__init__.py +17 -0
  109. graphscope/gsctl/tests/test_graphscope_insight.py +401 -0
  110. graphscope/gsctl/tests/test_interactive.py +516 -0
  111. graphscope/gsctl/utils.py +337 -0
  112. graphscope/gsctl/version.py +31 -0
  113. gsctl-0.29.0a20250114.dist-info/METADATA +20 -0
  114. gsctl-0.29.0a20250114.dist-info/RECORD +117 -0
  115. gsctl-0.29.0a20250114.dist-info/WHEEL +6 -0
  116. gsctl-0.29.0a20250114.dist-info/entry_points.txt +3 -0
  117. gsctl-0.29.0a20250114.dist-info/top_level.txt +1 -0
@@ -0,0 +1,789 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ GraphScope FLEX HTTP SERVICE API
5
+
6
+ This is a specification for GraphScope FLEX HTTP service based on the OpenAPI 3.0 specification. You can find out more details about specification at [doc](https://swagger.io/specification/v3/).
7
+
8
+ The version of the OpenAPI document: 1.0.0
9
+ Contact: graphscope@alibaba-inc.com
10
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
11
+
12
+ Do not edit the class manually.
13
+ """ # noqa: E501
14
+
15
+
16
+ import datetime
17
+ from dateutil.parser import parse
18
+ from enum import Enum
19
+ import decimal
20
+ import json
21
+ import mimetypes
22
+ import os
23
+ import re
24
+ import tempfile
25
+
26
+ from urllib.parse import quote
27
+ from typing import Tuple, Optional, List, Dict, Union
28
+ from pydantic import SecretStr
29
+
30
+ from graphscope.flex.rest.configuration import Configuration
31
+ from graphscope.flex.rest.api_response import ApiResponse, T as ApiResponseT
32
+ import graphscope.flex.rest.models
33
+ from graphscope.flex.rest import rest
34
+ from graphscope.flex.rest.exceptions import (
35
+ ApiValueError,
36
+ ApiException,
37
+ BadRequestException,
38
+ UnauthorizedException,
39
+ ForbiddenException,
40
+ NotFoundException,
41
+ ServiceException
42
+ )
43
+
44
+ RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]]
45
+
46
+ class ApiClient:
47
+ """Generic API client for OpenAPI client library builds.
48
+
49
+ OpenAPI generic API client. This client handles the client-
50
+ server communication, and is invariant across implementations. Specifics of
51
+ the methods and models for each application are generated from the OpenAPI
52
+ templates.
53
+
54
+ :param configuration: .Configuration object for this client
55
+ :param header_name: a header to pass when making calls to the API.
56
+ :param header_value: a header value to pass when making calls to
57
+ the API.
58
+ :param cookie: a cookie to include in the header when making calls
59
+ to the API
60
+ """
61
+
62
+ PRIMITIVE_TYPES = (float, bool, bytes, str, int)
63
+ NATIVE_TYPES_MAPPING = {
64
+ 'int': int,
65
+ 'long': int, # TODO remove as only py3 is supported?
66
+ 'float': float,
67
+ 'str': str,
68
+ 'bool': bool,
69
+ 'date': datetime.date,
70
+ 'datetime': datetime.datetime,
71
+ 'decimal': decimal.Decimal,
72
+ 'object': object,
73
+ }
74
+ _pool = None
75
+
76
+ def __init__(
77
+ self,
78
+ configuration=None,
79
+ header_name=None,
80
+ header_value=None,
81
+ cookie=None
82
+ ) -> None:
83
+ # use default configuration if none is provided
84
+ if configuration is None:
85
+ configuration = Configuration.get_default()
86
+ self.configuration = configuration
87
+
88
+ self.rest_client = rest.RESTClientObject(configuration)
89
+ self.default_headers = {}
90
+ if header_name is not None:
91
+ self.default_headers[header_name] = header_value
92
+ self.cookie = cookie
93
+ # Set default User-Agent.
94
+ self.user_agent = 'OpenAPI-Generator/1.0.0/python'
95
+ self.client_side_validation = configuration.client_side_validation
96
+
97
+ def __enter__(self):
98
+ return self
99
+
100
+ def __exit__(self, exc_type, exc_value, traceback):
101
+ pass
102
+
103
+ @property
104
+ def user_agent(self):
105
+ """User agent for this API client"""
106
+ return self.default_headers['User-Agent']
107
+
108
+ @user_agent.setter
109
+ def user_agent(self, value):
110
+ self.default_headers['User-Agent'] = value
111
+
112
+ def set_default_header(self, header_name, header_value):
113
+ self.default_headers[header_name] = header_value
114
+
115
+
116
+ _default = None
117
+
118
+ @classmethod
119
+ def get_default(cls):
120
+ """Return new instance of ApiClient.
121
+
122
+ This method returns newly created, based on default constructor,
123
+ object of ApiClient class or returns a copy of default
124
+ ApiClient.
125
+
126
+ :return: The ApiClient object.
127
+ """
128
+ if cls._default is None:
129
+ cls._default = ApiClient()
130
+ return cls._default
131
+
132
+ @classmethod
133
+ def set_default(cls, default):
134
+ """Set default instance of ApiClient.
135
+
136
+ It stores default ApiClient.
137
+
138
+ :param default: object of ApiClient.
139
+ """
140
+ cls._default = default
141
+
142
+ def param_serialize(
143
+ self,
144
+ method,
145
+ resource_path,
146
+ path_params=None,
147
+ query_params=None,
148
+ header_params=None,
149
+ body=None,
150
+ post_params=None,
151
+ files=None, auth_settings=None,
152
+ collection_formats=None,
153
+ _host=None,
154
+ _request_auth=None
155
+ ) -> RequestSerialized:
156
+
157
+ """Builds the HTTP request params needed by the request.
158
+ :param method: Method to call.
159
+ :param resource_path: Path to method endpoint.
160
+ :param path_params: Path parameters in the url.
161
+ :param query_params: Query parameters in the url.
162
+ :param header_params: Header parameters to be
163
+ placed in the request header.
164
+ :param body: Request body.
165
+ :param post_params dict: Request post form parameters,
166
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
167
+ :param auth_settings list: Auth Settings names for the request.
168
+ :param files dict: key -> filename, value -> filepath,
169
+ for `multipart/form-data`.
170
+ :param collection_formats: dict of collection formats for path, query,
171
+ header, and post parameters.
172
+ :param _request_auth: set to override the auth_settings for an a single
173
+ request; this effectively ignores the authentication
174
+ in the spec for a single request.
175
+ :return: tuple of form (path, http_method, query_params, header_params,
176
+ body, post_params, files)
177
+ """
178
+
179
+ config = self.configuration
180
+
181
+ # header parameters
182
+ header_params = header_params or {}
183
+ header_params.update(self.default_headers)
184
+ if self.cookie:
185
+ header_params['Cookie'] = self.cookie
186
+ if header_params:
187
+ header_params = self.sanitize_for_serialization(header_params)
188
+ header_params = dict(
189
+ self.parameters_to_tuples(header_params,collection_formats)
190
+ )
191
+
192
+ # path parameters
193
+ if path_params:
194
+ path_params = self.sanitize_for_serialization(path_params)
195
+ path_params = self.parameters_to_tuples(
196
+ path_params,
197
+ collection_formats
198
+ )
199
+ for k, v in path_params:
200
+ # specified safe chars, encode everything
201
+ resource_path = resource_path.replace(
202
+ '{%s}' % k,
203
+ quote(str(v), safe=config.safe_chars_for_path_param)
204
+ )
205
+
206
+ # post parameters
207
+ if post_params or files:
208
+ post_params = post_params if post_params else []
209
+ post_params = self.sanitize_for_serialization(post_params)
210
+ post_params = self.parameters_to_tuples(
211
+ post_params,
212
+ collection_formats
213
+ )
214
+ if files:
215
+ post_params.extend(self.files_parameters(files))
216
+
217
+ # auth setting
218
+ self.update_params_for_auth(
219
+ header_params,
220
+ query_params,
221
+ auth_settings,
222
+ resource_path,
223
+ method,
224
+ body,
225
+ request_auth=_request_auth
226
+ )
227
+
228
+ # body
229
+ if body:
230
+ body = self.sanitize_for_serialization(body)
231
+
232
+ # request url
233
+ if _host is None or self.configuration.ignore_operation_servers:
234
+ url = self.configuration.host + resource_path
235
+ else:
236
+ # use server/host defined in path or operation instead
237
+ url = _host + resource_path
238
+
239
+ # query parameters
240
+ if query_params:
241
+ query_params = self.sanitize_for_serialization(query_params)
242
+ url_query = self.parameters_to_url_query(
243
+ query_params,
244
+ collection_formats
245
+ )
246
+ url += "?" + url_query
247
+
248
+ return method, url, header_params, body, post_params
249
+
250
+
251
+ def call_api(
252
+ self,
253
+ method,
254
+ url,
255
+ header_params=None,
256
+ body=None,
257
+ post_params=None,
258
+ _request_timeout=None
259
+ ) -> rest.RESTResponse:
260
+ """Makes the HTTP request (synchronous)
261
+ :param method: Method to call.
262
+ :param url: Path to method endpoint.
263
+ :param header_params: Header parameters to be
264
+ placed in the request header.
265
+ :param body: Request body.
266
+ :param post_params dict: Request post form parameters,
267
+ for `application/x-www-form-urlencoded`, `multipart/form-data`.
268
+ :param _request_timeout: timeout setting for this request.
269
+ :return: RESTResponse
270
+ """
271
+
272
+ try:
273
+ # perform request and return response
274
+ response_data = self.rest_client.request(
275
+ method, url,
276
+ headers=header_params,
277
+ body=body, post_params=post_params,
278
+ _request_timeout=_request_timeout
279
+ )
280
+
281
+ except ApiException as e:
282
+ raise e
283
+
284
+ return response_data
285
+
286
+ def response_deserialize(
287
+ self,
288
+ response_data: rest.RESTResponse,
289
+ response_types_map: Optional[Dict[str, ApiResponseT]]=None
290
+ ) -> ApiResponse[ApiResponseT]:
291
+ """Deserializes response into an object.
292
+ :param response_data: RESTResponse object to be deserialized.
293
+ :param response_types_map: dict of response types.
294
+ :return: ApiResponse
295
+ """
296
+
297
+ msg = "RESTResponse.read() must be called before passing it to response_deserialize()"
298
+ assert response_data.data is not None, msg
299
+
300
+ response_type = response_types_map.get(str(response_data.status), None)
301
+ if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:
302
+ # if not found, look for '1XX', '2XX', etc.
303
+ response_type = response_types_map.get(str(response_data.status)[0] + "XX", None)
304
+
305
+ # deserialize response data
306
+ response_text = None
307
+ return_data = None
308
+ try:
309
+ if response_type == "bytearray":
310
+ return_data = response_data.data
311
+ elif response_type == "file":
312
+ return_data = self.__deserialize_file(response_data)
313
+ elif response_type is not None:
314
+ match = None
315
+ content_type = response_data.getheader('content-type')
316
+ if content_type is not None:
317
+ match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type)
318
+ encoding = match.group(1) if match else "utf-8"
319
+ response_text = response_data.data.decode(encoding)
320
+ return_data = self.deserialize(response_text, response_type, content_type)
321
+ finally:
322
+ if not 200 <= response_data.status <= 299:
323
+ raise ApiException.from_response(
324
+ http_resp=response_data,
325
+ body=response_text,
326
+ data=return_data,
327
+ )
328
+
329
+ return ApiResponse(
330
+ status_code = response_data.status,
331
+ data = return_data,
332
+ headers = response_data.getheaders(),
333
+ raw_data = response_data.data
334
+ )
335
+
336
+ def sanitize_for_serialization(self, obj):
337
+ """Builds a JSON POST object.
338
+
339
+ If obj is None, return None.
340
+ If obj is SecretStr, return obj.get_secret_value()
341
+ If obj is str, int, long, float, bool, return directly.
342
+ If obj is datetime.datetime, datetime.date
343
+ convert to string in iso8601 format.
344
+ If obj is decimal.Decimal return string representation.
345
+ If obj is list, sanitize each element in the list.
346
+ If obj is dict, return the dict.
347
+ If obj is OpenAPI model, return the properties dict.
348
+
349
+ :param obj: The data to serialize.
350
+ :return: The serialized form of data.
351
+ """
352
+ if obj is None:
353
+ return None
354
+ elif isinstance(obj, Enum):
355
+ return obj.value
356
+ elif isinstance(obj, SecretStr):
357
+ return obj.get_secret_value()
358
+ elif isinstance(obj, self.PRIMITIVE_TYPES):
359
+ return obj
360
+ elif isinstance(obj, list):
361
+ return [
362
+ self.sanitize_for_serialization(sub_obj) for sub_obj in obj
363
+ ]
364
+ elif isinstance(obj, tuple):
365
+ return tuple(
366
+ self.sanitize_for_serialization(sub_obj) for sub_obj in obj
367
+ )
368
+ elif isinstance(obj, (datetime.datetime, datetime.date)):
369
+ return obj.isoformat()
370
+ elif isinstance(obj, decimal.Decimal):
371
+ return str(obj)
372
+
373
+ elif isinstance(obj, dict):
374
+ obj_dict = obj
375
+ else:
376
+ # Convert model obj to dict except
377
+ # attributes `openapi_types`, `attribute_map`
378
+ # and attributes which value is not None.
379
+ # Convert attribute name to json key in
380
+ # model definition for request.
381
+ if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')):
382
+ obj_dict = obj.to_dict()
383
+ else:
384
+ obj_dict = obj.__dict__
385
+
386
+ return {
387
+ key: self.sanitize_for_serialization(val)
388
+ for key, val in obj_dict.items()
389
+ }
390
+
391
+ def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]):
392
+ """Deserializes response into an object.
393
+
394
+ :param response: RESTResponse object to be deserialized.
395
+ :param response_type: class literal for
396
+ deserialized object, or string of class name.
397
+ :param content_type: content type of response.
398
+
399
+ :return: deserialized object.
400
+ """
401
+
402
+ # fetch data from response object
403
+ if content_type is None:
404
+ try:
405
+ data = json.loads(response_text)
406
+ except ValueError:
407
+ data = response_text
408
+ elif content_type.startswith("application/json"):
409
+ if response_text == "":
410
+ data = ""
411
+ else:
412
+ data = json.loads(response_text)
413
+ elif content_type.startswith("text/plain"):
414
+ data = response_text
415
+ else:
416
+ raise ApiException(
417
+ status=0,
418
+ reason="Unsupported content type: {0}".format(content_type)
419
+ )
420
+
421
+ return self.__deserialize(data, response_type)
422
+
423
+ def __deserialize(self, data, klass):
424
+ """Deserializes dict, list, str into an object.
425
+
426
+ :param data: dict, list or str.
427
+ :param klass: class literal, or string of class name.
428
+
429
+ :return: object.
430
+ """
431
+ if data is None:
432
+ return None
433
+
434
+ if isinstance(klass, str):
435
+ if klass.startswith('List['):
436
+ m = re.match(r'List\[(.*)]', klass)
437
+ assert m is not None, "Malformed List type definition"
438
+ sub_kls = m.group(1)
439
+ return [self.__deserialize(sub_data, sub_kls)
440
+ for sub_data in data]
441
+
442
+ if klass.startswith('Dict['):
443
+ m = re.match(r'Dict\[([^,]*), (.*)]', klass)
444
+ assert m is not None, "Malformed Dict type definition"
445
+ sub_kls = m.group(2)
446
+ return {k: self.__deserialize(v, sub_kls)
447
+ for k, v in data.items()}
448
+
449
+ # convert str to class
450
+ if klass in self.NATIVE_TYPES_MAPPING:
451
+ klass = self.NATIVE_TYPES_MAPPING[klass]
452
+ else:
453
+ klass = getattr(graphscope.flex.rest.models, klass)
454
+
455
+ if klass in self.PRIMITIVE_TYPES:
456
+ return self.__deserialize_primitive(data, klass)
457
+ elif klass == object:
458
+ return self.__deserialize_object(data)
459
+ elif klass == datetime.date:
460
+ return self.__deserialize_date(data)
461
+ elif klass == datetime.datetime:
462
+ return self.__deserialize_datetime(data)
463
+ elif klass == decimal.Decimal:
464
+ return decimal.Decimal(data)
465
+ elif issubclass(klass, Enum):
466
+ return self.__deserialize_enum(data, klass)
467
+ else:
468
+ return self.__deserialize_model(data, klass)
469
+
470
+ def parameters_to_tuples(self, params, collection_formats):
471
+ """Get parameters as list of tuples, formatting collections.
472
+
473
+ :param params: Parameters as dict or list of two-tuples
474
+ :param dict collection_formats: Parameter collection formats
475
+ :return: Parameters as list of tuples, collections formatted
476
+ """
477
+ new_params: List[Tuple[str, str]] = []
478
+ if collection_formats is None:
479
+ collection_formats = {}
480
+ for k, v in params.items() if isinstance(params, dict) else params:
481
+ if k in collection_formats:
482
+ collection_format = collection_formats[k]
483
+ if collection_format == 'multi':
484
+ new_params.extend((k, value) for value in v)
485
+ else:
486
+ if collection_format == 'ssv':
487
+ delimiter = ' '
488
+ elif collection_format == 'tsv':
489
+ delimiter = '\t'
490
+ elif collection_format == 'pipes':
491
+ delimiter = '|'
492
+ else: # csv is the default
493
+ delimiter = ','
494
+ new_params.append(
495
+ (k, delimiter.join(str(value) for value in v)))
496
+ else:
497
+ new_params.append((k, v))
498
+ return new_params
499
+
500
+ def parameters_to_url_query(self, params, collection_formats):
501
+ """Get parameters as list of tuples, formatting collections.
502
+
503
+ :param params: Parameters as dict or list of two-tuples
504
+ :param dict collection_formats: Parameter collection formats
505
+ :return: URL query string (e.g. a=Hello%20World&b=123)
506
+ """
507
+ new_params: List[Tuple[str, str]] = []
508
+ if collection_formats is None:
509
+ collection_formats = {}
510
+ for k, v in params.items() if isinstance(params, dict) else params:
511
+ if isinstance(v, bool):
512
+ v = str(v).lower()
513
+ if isinstance(v, (int, float)):
514
+ v = str(v)
515
+ if isinstance(v, dict):
516
+ v = json.dumps(v)
517
+
518
+ if k in collection_formats:
519
+ collection_format = collection_formats[k]
520
+ if collection_format == 'multi':
521
+ new_params.extend((k, str(value)) for value in v)
522
+ else:
523
+ if collection_format == 'ssv':
524
+ delimiter = ' '
525
+ elif collection_format == 'tsv':
526
+ delimiter = '\t'
527
+ elif collection_format == 'pipes':
528
+ delimiter = '|'
529
+ else: # csv is the default
530
+ delimiter = ','
531
+ new_params.append(
532
+ (k, delimiter.join(quote(str(value)) for value in v))
533
+ )
534
+ else:
535
+ new_params.append((k, quote(str(v))))
536
+
537
+ return "&".join(["=".join(map(str, item)) for item in new_params])
538
+
539
+ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
540
+ """Builds form parameters.
541
+
542
+ :param files: File parameters.
543
+ :return: Form parameters with files.
544
+ """
545
+ params = []
546
+ for k, v in files.items():
547
+ if isinstance(v, str):
548
+ with open(v, 'rb') as f:
549
+ filename = os.path.basename(f.name)
550
+ filedata = f.read()
551
+ elif isinstance(v, bytes):
552
+ filename = k
553
+ filedata = v
554
+ else:
555
+ raise ValueError("Unsupported file value")
556
+ mimetype = (
557
+ mimetypes.guess_type(filename)[0]
558
+ or 'application/octet-stream'
559
+ )
560
+ params.append(
561
+ tuple([k, tuple([filename, filedata, mimetype])])
562
+ )
563
+ return params
564
+
565
+ def select_header_accept(self, accepts: List[str]) -> Optional[str]:
566
+ """Returns `Accept` based on an array of accepts provided.
567
+
568
+ :param accepts: List of headers.
569
+ :return: Accept (e.g. application/json).
570
+ """
571
+ if not accepts:
572
+ return None
573
+
574
+ for accept in accepts:
575
+ if re.search('json', accept, re.IGNORECASE):
576
+ return accept
577
+
578
+ return accepts[0]
579
+
580
+ def select_header_content_type(self, content_types):
581
+ """Returns `Content-Type` based on an array of content_types provided.
582
+
583
+ :param content_types: List of content-types.
584
+ :return: Content-Type (e.g. application/json).
585
+ """
586
+ if not content_types:
587
+ return None
588
+
589
+ for content_type in content_types:
590
+ if re.search('json', content_type, re.IGNORECASE):
591
+ return content_type
592
+
593
+ return content_types[0]
594
+
595
+ def update_params_for_auth(
596
+ self,
597
+ headers,
598
+ queries,
599
+ auth_settings,
600
+ resource_path,
601
+ method,
602
+ body,
603
+ request_auth=None
604
+ ) -> None:
605
+ """Updates header and query params based on authentication setting.
606
+
607
+ :param headers: Header parameters dict to be updated.
608
+ :param queries: Query parameters tuple list to be updated.
609
+ :param auth_settings: Authentication setting identifiers list.
610
+ :resource_path: A string representation of the HTTP request resource path.
611
+ :method: A string representation of the HTTP request method.
612
+ :body: A object representing the body of the HTTP request.
613
+ The object type is the return value of sanitize_for_serialization().
614
+ :param request_auth: if set, the provided settings will
615
+ override the token in the configuration.
616
+ """
617
+ if not auth_settings:
618
+ return
619
+
620
+ if request_auth:
621
+ self._apply_auth_params(
622
+ headers,
623
+ queries,
624
+ resource_path,
625
+ method,
626
+ body,
627
+ request_auth
628
+ )
629
+ else:
630
+ for auth in auth_settings:
631
+ auth_setting = self.configuration.auth_settings().get(auth)
632
+ if auth_setting:
633
+ self._apply_auth_params(
634
+ headers,
635
+ queries,
636
+ resource_path,
637
+ method,
638
+ body,
639
+ auth_setting
640
+ )
641
+
642
+ def _apply_auth_params(
643
+ self,
644
+ headers,
645
+ queries,
646
+ resource_path,
647
+ method,
648
+ body,
649
+ auth_setting
650
+ ) -> None:
651
+ """Updates the request parameters based on a single auth_setting
652
+
653
+ :param headers: Header parameters dict to be updated.
654
+ :param queries: Query parameters tuple list to be updated.
655
+ :resource_path: A string representation of the HTTP request resource path.
656
+ :method: A string representation of the HTTP request method.
657
+ :body: A object representing the body of the HTTP request.
658
+ The object type is the return value of sanitize_for_serialization().
659
+ :param auth_setting: auth settings for the endpoint
660
+ """
661
+ if auth_setting['in'] == 'cookie':
662
+ headers['Cookie'] = auth_setting['value']
663
+ elif auth_setting['in'] == 'header':
664
+ if auth_setting['type'] != 'http-signature':
665
+ headers[auth_setting['key']] = auth_setting['value']
666
+ elif auth_setting['in'] == 'query':
667
+ queries.append((auth_setting['key'], auth_setting['value']))
668
+ else:
669
+ raise ApiValueError(
670
+ 'Authentication token must be in `query` or `header`'
671
+ )
672
+
673
+ def __deserialize_file(self, response):
674
+ """Deserializes body to file
675
+
676
+ Saves response body into a file in a temporary folder,
677
+ using the filename from the `Content-Disposition` header if provided.
678
+
679
+ handle file downloading
680
+ save response body into a tmp file and return the instance
681
+
682
+ :param response: RESTResponse.
683
+ :return: file path.
684
+ """
685
+ fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
686
+ os.close(fd)
687
+ os.remove(path)
688
+
689
+ content_disposition = response.getheader("Content-Disposition")
690
+ if content_disposition:
691
+ m = re.search(
692
+ r'filename=[\'"]?([^\'"\s]+)[\'"]?',
693
+ content_disposition
694
+ )
695
+ assert m is not None, "Unexpected 'content-disposition' header value"
696
+ filename = m.group(1)
697
+ path = os.path.join(os.path.dirname(path), filename)
698
+
699
+ with open(path, "wb") as f:
700
+ f.write(response.data)
701
+
702
+ return path
703
+
704
+ def __deserialize_primitive(self, data, klass):
705
+ """Deserializes string to primitive type.
706
+
707
+ :param data: str.
708
+ :param klass: class literal.
709
+
710
+ :return: int, long, float, str, bool.
711
+ """
712
+ try:
713
+ return klass(data)
714
+ except UnicodeEncodeError:
715
+ return str(data)
716
+ except TypeError:
717
+ return data
718
+
719
+ def __deserialize_object(self, value):
720
+ """Return an original value.
721
+
722
+ :return: object.
723
+ """
724
+ return value
725
+
726
+ def __deserialize_date(self, string):
727
+ """Deserializes string to date.
728
+
729
+ :param string: str.
730
+ :return: date.
731
+ """
732
+ try:
733
+ return parse(string).date()
734
+ except ImportError:
735
+ return string
736
+ except ValueError:
737
+ raise rest.ApiException(
738
+ status=0,
739
+ reason="Failed to parse `{0}` as date object".format(string)
740
+ )
741
+
742
+ def __deserialize_datetime(self, string):
743
+ """Deserializes string to datetime.
744
+
745
+ The string should be in iso8601 datetime format.
746
+
747
+ :param string: str.
748
+ :return: datetime.
749
+ """
750
+ try:
751
+ return parse(string)
752
+ except ImportError:
753
+ return string
754
+ except ValueError:
755
+ raise rest.ApiException(
756
+ status=0,
757
+ reason=(
758
+ "Failed to parse `{0}` as datetime object"
759
+ .format(string)
760
+ )
761
+ )
762
+
763
+ def __deserialize_enum(self, data, klass):
764
+ """Deserializes primitive type to enum.
765
+
766
+ :param data: primitive type.
767
+ :param klass: class literal.
768
+ :return: enum value.
769
+ """
770
+ try:
771
+ return klass(data)
772
+ except ValueError:
773
+ raise rest.ApiException(
774
+ status=0,
775
+ reason=(
776
+ "Failed to parse `{0}` as `{1}`"
777
+ .format(data, klass)
778
+ )
779
+ )
780
+
781
+ def __deserialize_model(self, data, klass):
782
+ """Deserializes list or dict to model.
783
+
784
+ :param data: dict, list.
785
+ :param klass: class literal.
786
+ :return: model object.
787
+ """
788
+
789
+ return klass.from_dict(data)