qi-compute-api-client 0.52.0__py3-none-any.whl → 0.54.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 qi-compute-api-client might be problematic. Click here for more details.
- compute_api_client/__init__.py +194 -95
- compute_api_client/api/algorithms_api.py +75 -81
- compute_api_client/api/auth_config_api.py +16 -24
- compute_api_client/api/backend_api.py +70 -86
- compute_api_client/api/backend_types_api.py +77 -56
- compute_api_client/api/batch_jobs_api.py +102 -120
- compute_api_client/api/commits_api.py +85 -80
- compute_api_client/api/files_api.py +62 -67
- compute_api_client/api/final_results_api.py +42 -53
- compute_api_client/api/health_api.py +16 -25
- compute_api_client/api/jobs_api.py +76 -83
- compute_api_client/api/languages_api.py +30 -42
- compute_api_client/api/members_api.py +62 -67
- compute_api_client/api/permissions_api.py +56 -70
- compute_api_client/api/projects_api.py +89 -97
- compute_api_client/api/reservations_api.py +57 -72
- compute_api_client/api/results_api.py +76 -83
- compute_api_client/api/teams_api.py +30 -42
- compute_api_client/api/transactions_api.py +31 -44
- compute_api_client/api/users_api.py +62 -67
- compute_api_client/api_client.py +135 -75
- compute_api_client/api_response.py +3 -3
- compute_api_client/configuration.py +176 -36
- compute_api_client/docs/Algorithm.md +8 -7
- compute_api_client/docs/AlgorithmIn.md +7 -6
- compute_api_client/docs/AlgorithmType.md +5 -3
- compute_api_client/docs/AlgorithmsApi.md +15 -10
- compute_api_client/docs/AuthConfig.md +3 -2
- compute_api_client/docs/AuthConfigApi.md +3 -2
- compute_api_client/docs/Backend.md +9 -8
- compute_api_client/docs/BackendApi.md +15 -10
- compute_api_client/docs/BackendIn.md +8 -7
- compute_api_client/docs/BackendPatch.md +5 -4
- compute_api_client/docs/BackendStatus.md +9 -3
- compute_api_client/docs/BackendType.md +21 -19
- compute_api_client/docs/BackendTypePatch.md +4 -2
- compute_api_client/docs/BackendTypesApi.md +21 -10
- compute_api_client/docs/BackendWithAuthentication.md +10 -9
- compute_api_client/docs/BatchJob.md +10 -9
- compute_api_client/docs/BatchJobIn.md +4 -3
- compute_api_client/docs/BatchJobStatus.md +11 -3
- compute_api_client/docs/BatchJobsApi.md +23 -16
- compute_api_client/docs/Commit.md +8 -7
- compute_api_client/docs/CommitIn.md +5 -4
- compute_api_client/docs/CommitsApi.md +15 -10
- compute_api_client/docs/CompilePayload.md +4 -3
- compute_api_client/docs/CompileStage.md +11 -3
- compute_api_client/docs/Domain.md +7 -3
- compute_api_client/docs/File.md +10 -9
- compute_api_client/docs/FileIn.md +9 -8
- compute_api_client/docs/FilesApi.md +12 -8
- compute_api_client/docs/FinalResult.md +7 -6
- compute_api_client/docs/FinalResultIn.md +5 -4
- compute_api_client/docs/FinalResultsApi.md +9 -6
- compute_api_client/docs/HTTPBadRequestError.md +3 -2
- compute_api_client/docs/HTTPNotFoundError.md +3 -2
- compute_api_client/docs/HTTPValidationError.md +3 -2
- compute_api_client/docs/HealthApi.md +3 -2
- compute_api_client/docs/Job.md +13 -12
- compute_api_client/docs/Job1.md +28 -0
- compute_api_client/docs/JobIn.md +6 -5
- compute_api_client/docs/JobPatch.md +8 -7
- compute_api_client/docs/JobStatus.md +11 -3
- compute_api_client/docs/JobsApi.md +15 -10
- compute_api_client/docs/Language.md +6 -5
- compute_api_client/docs/LanguagesApi.md +6 -4
- compute_api_client/docs/Member.md +8 -7
- compute_api_client/docs/MemberId.md +28 -0
- compute_api_client/docs/MemberIn.md +7 -6
- compute_api_client/docs/MembersApi.md +12 -8
- compute_api_client/docs/PageAlgorithm.md +3 -2
- compute_api_client/docs/PageBackend.md +3 -2
- compute_api_client/docs/PageBackendType.md +3 -2
- compute_api_client/docs/PageBatchJob.md +3 -2
- compute_api_client/docs/PageCommit.md +3 -2
- compute_api_client/docs/PageFile.md +3 -2
- compute_api_client/docs/PageJob.md +3 -2
- compute_api_client/docs/PageLanguage.md +3 -2
- compute_api_client/docs/PageMember.md +3 -2
- compute_api_client/docs/PagePermission.md +3 -2
- compute_api_client/docs/PagePermissionGroup.md +3 -2
- compute_api_client/docs/PageProject.md +3 -2
- compute_api_client/docs/PageReservation.md +3 -2
- compute_api_client/docs/PageResult.md +3 -2
- compute_api_client/docs/PageTeam.md +3 -2
- compute_api_client/docs/PageTransaction.md +3 -2
- compute_api_client/docs/PageUser.md +3 -2
- compute_api_client/docs/Permission.md +6 -5
- compute_api_client/docs/PermissionGroup.md +5 -4
- compute_api_client/docs/PermissionsApi.md +12 -8
- compute_api_client/docs/Project.md +9 -8
- compute_api_client/docs/ProjectIn.md +7 -6
- compute_api_client/docs/ProjectPatch.md +3 -2
- compute_api_client/docs/ProjectsApi.md +23 -13
- compute_api_client/docs/Reservation.md +9 -8
- compute_api_client/docs/ReservationIn.md +7 -6
- compute_api_client/docs/ReservationsApi.md +12 -8
- compute_api_client/docs/Result.md +7 -6
- compute_api_client/docs/ResultIn.md +5 -4
- compute_api_client/docs/ResultsApi.md +15 -10
- compute_api_client/docs/Role.md +5 -3
- compute_api_client/docs/ShareType.md +7 -3
- compute_api_client/docs/Team.md +7 -6
- compute_api_client/docs/TeamsApi.md +6 -4
- compute_api_client/docs/Transaction.md +6 -5
- compute_api_client/docs/TransactionDomain.md +28 -0
- compute_api_client/docs/TransactionsApi.md +6 -4
- compute_api_client/docs/User.md +11 -10
- compute_api_client/docs/UserIn.md +10 -9
- compute_api_client/docs/UsersApi.md +12 -8
- compute_api_client/docs/ValidationError.md +4 -3
- compute_api_client/docs/ValidationErrorLocInner.md +28 -0
- compute_api_client/exceptions.py +74 -24
- compute_api_client/models/__init__.py +1 -1
- compute_api_client/models/algorithm.py +19 -20
- compute_api_client/models/algorithm_in.py +18 -19
- compute_api_client/models/algorithm_type.py +1 -9
- compute_api_client/models/auth_config.py +14 -14
- compute_api_client/models/backend.py +20 -20
- compute_api_client/models/backend_in.py +19 -19
- compute_api_client/models/backend_patch.py +16 -15
- compute_api_client/models/backend_status.py +1 -9
- compute_api_client/models/backend_type.py +42 -36
- compute_api_client/models/backend_type_patch.py +23 -17
- compute_api_client/models/backend_with_authentication.py +21 -21
- compute_api_client/models/batch_job.py +21 -20
- compute_api_client/models/batch_job_in.py +15 -15
- compute_api_client/models/batch_job_status.py +1 -9
- compute_api_client/models/commit.py +19 -19
- compute_api_client/models/commit_in.py +16 -16
- compute_api_client/models/compile_payload.py +15 -15
- compute_api_client/models/compile_stage.py +1 -9
- compute_api_client/models/domain.py +1 -9
- compute_api_client/models/file.py +21 -22
- compute_api_client/models/file_in.py +20 -21
- compute_api_client/models/final_result.py +18 -17
- compute_api_client/models/final_result_in.py +16 -16
- compute_api_client/models/http_bad_request_error.py +14 -14
- compute_api_client/models/http_not_found_error.py +14 -14
- compute_api_client/models/http_validation_error.py +18 -18
- compute_api_client/models/job.py +24 -24
- compute_api_client/models/job1.py +144 -0
- compute_api_client/models/job_in.py +17 -17
- compute_api_client/models/job_patch.py +19 -20
- compute_api_client/models/job_status.py +1 -9
- compute_api_client/models/language.py +17 -18
- compute_api_client/models/member.py +19 -19
- compute_api_client/models/member_id.py +144 -0
- compute_api_client/models/member_in.py +18 -18
- compute_api_client/models/page_algorithm.py +18 -19
- compute_api_client/models/page_backend.py +18 -19
- compute_api_client/models/page_backend_type.py +18 -19
- compute_api_client/models/page_batch_job.py +18 -19
- compute_api_client/models/page_commit.py +18 -19
- compute_api_client/models/page_file.py +18 -19
- compute_api_client/models/page_job.py +18 -19
- compute_api_client/models/page_language.py +18 -19
- compute_api_client/models/page_member.py +18 -19
- compute_api_client/models/page_permission.py +18 -19
- compute_api_client/models/page_permission_group.py +18 -19
- compute_api_client/models/page_project.py +18 -19
- compute_api_client/models/page_reservation.py +18 -19
- compute_api_client/models/page_result.py +18 -19
- compute_api_client/models/page_team.py +18 -19
- compute_api_client/models/page_transaction.py +18 -19
- compute_api_client/models/page_user.py +18 -19
- compute_api_client/models/permission.py +17 -18
- compute_api_client/models/permission_group.py +16 -17
- compute_api_client/models/project.py +20 -20
- compute_api_client/models/project_in.py +18 -19
- compute_api_client/models/project_patch.py +14 -15
- compute_api_client/models/reservation.py +20 -19
- compute_api_client/models/reservation_in.py +18 -17
- compute_api_client/models/result.py +18 -17
- compute_api_client/models/result_in.py +16 -16
- compute_api_client/models/role.py +1 -9
- compute_api_client/models/share_type.py +1 -9
- compute_api_client/models/team.py +18 -19
- compute_api_client/models/transaction.py +17 -17
- compute_api_client/models/transaction_domain.py +142 -0
- compute_api_client/models/user.py +22 -23
- compute_api_client/models/user_in.py +21 -22
- compute_api_client/models/validation_error.py +20 -20
- compute_api_client/models/validation_error_loc_inner.py +138 -0
- compute_api_client/rest.py +51 -26
- {qi_compute_api_client-0.52.0.dist-info → qi_compute_api_client-0.54.0.dist-info}/METADATA +12 -9
- qi_compute_api_client-0.54.0.dist-info/RECORD +205 -0
- qi_compute_api_client-0.52.0.dist-info/RECORD +0 -197
- {qi_compute_api_client-0.52.0.dist-info → qi_compute_api_client-0.54.0.dist-info}/WHEEL +0 -0
- {qi_compute_api_client-0.52.0.dist-info → qi_compute_api_client-0.54.0.dist-info}/licenses/LICENSE.md +0 -0
compute_api_client/api_client.py
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
""" # noqa: E501
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
import atexit
|
|
16
15
|
import datetime
|
|
17
16
|
from dateutil.parser import parse
|
|
17
|
+
from enum import Enum
|
|
18
|
+
import decimal
|
|
18
19
|
import json
|
|
19
20
|
import mimetypes
|
|
20
21
|
import os
|
|
@@ -22,10 +23,11 @@ import re
|
|
|
22
23
|
import tempfile
|
|
23
24
|
|
|
24
25
|
from urllib.parse import quote
|
|
25
|
-
from typing import Tuple, Optional, List
|
|
26
|
+
from typing import Tuple, Optional, List, Dict, Union
|
|
27
|
+
from pydantic import SecretStr
|
|
26
28
|
|
|
27
29
|
from compute_api_client.configuration import Configuration
|
|
28
|
-
from compute_api_client.api_response import ApiResponse
|
|
30
|
+
from compute_api_client.api_response import ApiResponse, T as ApiResponseT
|
|
29
31
|
import compute_api_client.models
|
|
30
32
|
from compute_api_client import rest
|
|
31
33
|
from compute_api_client.exceptions import (
|
|
@@ -38,6 +40,7 @@ from compute_api_client.exceptions import (
|
|
|
38
40
|
ServiceException
|
|
39
41
|
)
|
|
40
42
|
|
|
43
|
+
RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]]
|
|
41
44
|
|
|
42
45
|
class ApiClient:
|
|
43
46
|
"""Generic API client for OpenAPI client library builds.
|
|
@@ -64,6 +67,7 @@ class ApiClient:
|
|
|
64
67
|
'bool': bool,
|
|
65
68
|
'date': datetime.date,
|
|
66
69
|
'datetime': datetime.datetime,
|
|
70
|
+
'decimal': decimal.Decimal,
|
|
67
71
|
'object': object,
|
|
68
72
|
}
|
|
69
73
|
_pool = None
|
|
@@ -150,7 +154,7 @@ class ApiClient:
|
|
|
150
154
|
collection_formats=None,
|
|
151
155
|
_host=None,
|
|
152
156
|
_request_auth=None
|
|
153
|
-
) ->
|
|
157
|
+
) -> RequestSerialized:
|
|
154
158
|
|
|
155
159
|
"""Builds the HTTP request params needed by the request.
|
|
156
160
|
:param method: Method to call.
|
|
@@ -209,7 +213,8 @@ class ApiClient:
|
|
|
209
213
|
post_params,
|
|
210
214
|
collection_formats
|
|
211
215
|
)
|
|
212
|
-
|
|
216
|
+
if files:
|
|
217
|
+
post_params.extend(self.files_parameters(files))
|
|
213
218
|
|
|
214
219
|
# auth setting
|
|
215
220
|
self.update_params_for_auth(
|
|
@@ -227,7 +232,7 @@ class ApiClient:
|
|
|
227
232
|
body = self.sanitize_for_serialization(body)
|
|
228
233
|
|
|
229
234
|
# request url
|
|
230
|
-
if _host is None:
|
|
235
|
+
if _host is None or self.configuration.ignore_operation_servers:
|
|
231
236
|
url = self.configuration.host + resource_path
|
|
232
237
|
else:
|
|
233
238
|
# use server/host defined in path or operation instead
|
|
@@ -276,62 +281,52 @@ class ApiClient:
|
|
|
276
281
|
)
|
|
277
282
|
|
|
278
283
|
except ApiException as e:
|
|
279
|
-
if e.body:
|
|
280
|
-
e.body = e.body.decode('utf-8')
|
|
281
284
|
raise e
|
|
282
285
|
|
|
283
286
|
return response_data
|
|
284
287
|
|
|
285
288
|
def response_deserialize(
|
|
286
289
|
self,
|
|
287
|
-
response_data
|
|
288
|
-
response_types_map=None
|
|
289
|
-
) -> ApiResponse:
|
|
290
|
+
response_data: rest.RESTResponse,
|
|
291
|
+
response_types_map: Optional[Dict[str, ApiResponseT]]=None
|
|
292
|
+
) -> ApiResponse[ApiResponseT]:
|
|
290
293
|
"""Deserializes response into an object.
|
|
291
294
|
:param response_data: RESTResponse object to be deserialized.
|
|
292
295
|
:param response_types_map: dict of response types.
|
|
293
296
|
:return: ApiResponse
|
|
294
297
|
"""
|
|
295
298
|
|
|
299
|
+
msg = "RESTResponse.read() must be called before passing it to response_deserialize()"
|
|
300
|
+
assert response_data.data is not None, msg
|
|
296
301
|
|
|
297
302
|
response_type = response_types_map.get(str(response_data.status), None)
|
|
298
303
|
if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:
|
|
299
304
|
# if not found, look for '1XX', '2XX', etc.
|
|
300
305
|
response_type = response_types_map.get(str(response_data.status)[0] + "XX", None)
|
|
301
306
|
|
|
302
|
-
if not 200 <= response_data.status <= 299:
|
|
303
|
-
if response_data.status == 400:
|
|
304
|
-
raise BadRequestException(http_resp=response_data)
|
|
305
|
-
|
|
306
|
-
if response_data.status == 401:
|
|
307
|
-
raise UnauthorizedException(http_resp=response_data)
|
|
308
|
-
|
|
309
|
-
if response_data.status == 403:
|
|
310
|
-
raise ForbiddenException(http_resp=response_data)
|
|
311
|
-
|
|
312
|
-
if response_data.status == 404:
|
|
313
|
-
raise NotFoundException(http_resp=response_data)
|
|
314
|
-
|
|
315
|
-
if 500 <= response_data.status <= 599:
|
|
316
|
-
raise ServiceException(http_resp=response_data)
|
|
317
|
-
raise ApiException(http_resp=response_data)
|
|
318
|
-
|
|
319
307
|
# deserialize response data
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
308
|
+
response_text = None
|
|
309
|
+
return_data = None
|
|
310
|
+
try:
|
|
311
|
+
if response_type == "bytearray":
|
|
312
|
+
return_data = response_data.data
|
|
313
|
+
elif response_type == "file":
|
|
314
|
+
return_data = self.__deserialize_file(response_data)
|
|
315
|
+
elif response_type is not None:
|
|
316
|
+
match = None
|
|
317
|
+
content_type = response_data.getheader('content-type')
|
|
318
|
+
if content_type is not None:
|
|
319
|
+
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type)
|
|
320
|
+
encoding = match.group(1) if match else "utf-8"
|
|
321
|
+
response_text = response_data.data.decode(encoding)
|
|
322
|
+
return_data = self.deserialize(response_text, response_type, content_type)
|
|
323
|
+
finally:
|
|
324
|
+
if not 200 <= response_data.status <= 299:
|
|
325
|
+
raise ApiException.from_response(
|
|
326
|
+
http_resp=response_data,
|
|
327
|
+
body=response_text,
|
|
328
|
+
data=return_data,
|
|
329
|
+
)
|
|
335
330
|
|
|
336
331
|
return ApiResponse(
|
|
337
332
|
status_code = response_data.status,
|
|
@@ -344,9 +339,11 @@ class ApiClient:
|
|
|
344
339
|
"""Builds a JSON POST object.
|
|
345
340
|
|
|
346
341
|
If obj is None, return None.
|
|
342
|
+
If obj is SecretStr, return obj.get_secret_value()
|
|
347
343
|
If obj is str, int, long, float, bool, return directly.
|
|
348
344
|
If obj is datetime.datetime, datetime.date
|
|
349
345
|
convert to string in iso8601 format.
|
|
346
|
+
If obj is decimal.Decimal return string representation.
|
|
350
347
|
If obj is list, sanitize each element in the list.
|
|
351
348
|
If obj is dict, return the dict.
|
|
352
349
|
If obj is OpenAPI model, return the properties dict.
|
|
@@ -356,6 +353,10 @@ class ApiClient:
|
|
|
356
353
|
"""
|
|
357
354
|
if obj is None:
|
|
358
355
|
return None
|
|
356
|
+
elif isinstance(obj, Enum):
|
|
357
|
+
return obj.value
|
|
358
|
+
elif isinstance(obj, SecretStr):
|
|
359
|
+
return obj.get_secret_value()
|
|
359
360
|
elif isinstance(obj, self.PRIMITIVE_TYPES):
|
|
360
361
|
return obj
|
|
361
362
|
elif isinstance(obj, list):
|
|
@@ -368,6 +369,8 @@ class ApiClient:
|
|
|
368
369
|
)
|
|
369
370
|
elif isinstance(obj, (datetime.datetime, datetime.date)):
|
|
370
371
|
return obj.isoformat()
|
|
372
|
+
elif isinstance(obj, decimal.Decimal):
|
|
373
|
+
return str(obj)
|
|
371
374
|
|
|
372
375
|
elif isinstance(obj, dict):
|
|
373
376
|
obj_dict = obj
|
|
@@ -377,28 +380,49 @@ class ApiClient:
|
|
|
377
380
|
# and attributes which value is not None.
|
|
378
381
|
# Convert attribute name to json key in
|
|
379
382
|
# model definition for request.
|
|
380
|
-
|
|
383
|
+
if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')):
|
|
384
|
+
obj_dict = obj.to_dict()
|
|
385
|
+
else:
|
|
386
|
+
obj_dict = obj.__dict__
|
|
387
|
+
|
|
388
|
+
if isinstance(obj_dict, list):
|
|
389
|
+
# here we handle instances that can either be a list or something else, and only became a real list by calling to_dict()
|
|
390
|
+
return self.sanitize_for_serialization(obj_dict)
|
|
381
391
|
|
|
382
392
|
return {
|
|
383
393
|
key: self.sanitize_for_serialization(val)
|
|
384
394
|
for key, val in obj_dict.items()
|
|
385
395
|
}
|
|
386
396
|
|
|
387
|
-
def deserialize(self, response_text, response_type):
|
|
397
|
+
def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]):
|
|
388
398
|
"""Deserializes response into an object.
|
|
389
399
|
|
|
390
400
|
:param response: RESTResponse object to be deserialized.
|
|
391
401
|
:param response_type: class literal for
|
|
392
402
|
deserialized object, or string of class name.
|
|
403
|
+
:param content_type: content type of response.
|
|
393
404
|
|
|
394
405
|
:return: deserialized object.
|
|
395
406
|
"""
|
|
396
407
|
|
|
397
408
|
# fetch data from response object
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
409
|
+
if content_type is None:
|
|
410
|
+
try:
|
|
411
|
+
data = json.loads(response_text)
|
|
412
|
+
except ValueError:
|
|
413
|
+
data = response_text
|
|
414
|
+
elif re.match(r'^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE):
|
|
415
|
+
if response_text == "":
|
|
416
|
+
data = ""
|
|
417
|
+
else:
|
|
418
|
+
data = json.loads(response_text)
|
|
419
|
+
elif re.match(r'^text\/[a-z.+-]+\s*(;|$)', content_type, re.IGNORECASE):
|
|
401
420
|
data = response_text
|
|
421
|
+
else:
|
|
422
|
+
raise ApiException(
|
|
423
|
+
status=0,
|
|
424
|
+
reason="Unsupported content type: {0}".format(content_type)
|
|
425
|
+
)
|
|
402
426
|
|
|
403
427
|
return self.__deserialize(data, response_type)
|
|
404
428
|
|
|
@@ -415,12 +439,16 @@ class ApiClient:
|
|
|
415
439
|
|
|
416
440
|
if isinstance(klass, str):
|
|
417
441
|
if klass.startswith('List['):
|
|
418
|
-
|
|
442
|
+
m = re.match(r'List\[(.*)]', klass)
|
|
443
|
+
assert m is not None, "Malformed List type definition"
|
|
444
|
+
sub_kls = m.group(1)
|
|
419
445
|
return [self.__deserialize(sub_data, sub_kls)
|
|
420
446
|
for sub_data in data]
|
|
421
447
|
|
|
422
448
|
if klass.startswith('Dict['):
|
|
423
|
-
|
|
449
|
+
m = re.match(r'Dict\[([^,]*), (.*)]', klass)
|
|
450
|
+
assert m is not None, "Malformed Dict type definition"
|
|
451
|
+
sub_kls = m.group(2)
|
|
424
452
|
return {k: self.__deserialize(v, sub_kls)
|
|
425
453
|
for k, v in data.items()}
|
|
426
454
|
|
|
@@ -438,6 +466,10 @@ class ApiClient:
|
|
|
438
466
|
return self.__deserialize_date(data)
|
|
439
467
|
elif klass == datetime.datetime:
|
|
440
468
|
return self.__deserialize_datetime(data)
|
|
469
|
+
elif klass == decimal.Decimal:
|
|
470
|
+
return decimal.Decimal(data)
|
|
471
|
+
elif issubclass(klass, Enum):
|
|
472
|
+
return self.__deserialize_enum(data, klass)
|
|
441
473
|
else:
|
|
442
474
|
return self.__deserialize_model(data, klass)
|
|
443
475
|
|
|
@@ -448,7 +480,7 @@ class ApiClient:
|
|
|
448
480
|
:param dict collection_formats: Parameter collection formats
|
|
449
481
|
:return: Parameters as list of tuples, collections formatted
|
|
450
482
|
"""
|
|
451
|
-
new_params = []
|
|
483
|
+
new_params: List[Tuple[str, str]] = []
|
|
452
484
|
if collection_formats is None:
|
|
453
485
|
collection_formats = {}
|
|
454
486
|
for k, v in params.items() if isinstance(params, dict) else params:
|
|
@@ -478,7 +510,7 @@ class ApiClient:
|
|
|
478
510
|
:param dict collection_formats: Parameter collection formats
|
|
479
511
|
:return: URL query string (e.g. a=Hello%20World&b=123)
|
|
480
512
|
"""
|
|
481
|
-
new_params = []
|
|
513
|
+
new_params: List[Tuple[str, str]] = []
|
|
482
514
|
if collection_formats is None:
|
|
483
515
|
collection_formats = {}
|
|
484
516
|
for k, v in params.items() if isinstance(params, dict) else params:
|
|
@@ -492,7 +524,7 @@ class ApiClient:
|
|
|
492
524
|
if k in collection_formats:
|
|
493
525
|
collection_format = collection_formats[k]
|
|
494
526
|
if collection_format == 'multi':
|
|
495
|
-
new_params.extend((k, value) for value in v)
|
|
527
|
+
new_params.extend((k, quote(str(value))) for value in v)
|
|
496
528
|
else:
|
|
497
529
|
if collection_format == 'ssv':
|
|
498
530
|
delimiter = ' '
|
|
@@ -508,33 +540,41 @@ class ApiClient:
|
|
|
508
540
|
else:
|
|
509
541
|
new_params.append((k, quote(str(v))))
|
|
510
542
|
|
|
511
|
-
return "&".join(["=".join(item) for item in new_params])
|
|
543
|
+
return "&".join(["=".join(map(str, item)) for item in new_params])
|
|
512
544
|
|
|
513
|
-
def files_parameters(
|
|
545
|
+
def files_parameters(
|
|
546
|
+
self,
|
|
547
|
+
files: Dict[str, Union[str, bytes, List[str], List[bytes], Tuple[str, bytes]]],
|
|
548
|
+
):
|
|
514
549
|
"""Builds form parameters.
|
|
515
550
|
|
|
516
551
|
:param files: File parameters.
|
|
517
552
|
:return: Form parameters with files.
|
|
518
553
|
"""
|
|
519
554
|
params = []
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
555
|
+
for k, v in files.items():
|
|
556
|
+
if isinstance(v, str):
|
|
557
|
+
with open(v, 'rb') as f:
|
|
558
|
+
filename = os.path.basename(f.name)
|
|
559
|
+
filedata = f.read()
|
|
560
|
+
elif isinstance(v, bytes):
|
|
561
|
+
filename = k
|
|
562
|
+
filedata = v
|
|
563
|
+
elif isinstance(v, tuple):
|
|
564
|
+
filename, filedata = v
|
|
565
|
+
elif isinstance(v, list):
|
|
566
|
+
for file_param in v:
|
|
567
|
+
params.extend(self.files_parameters({k: file_param}))
|
|
568
|
+
continue
|
|
569
|
+
else:
|
|
570
|
+
raise ValueError("Unsupported file value")
|
|
571
|
+
mimetype = (
|
|
572
|
+
mimetypes.guess_type(filename)[0]
|
|
573
|
+
or 'application/octet-stream'
|
|
574
|
+
)
|
|
575
|
+
params.append(
|
|
576
|
+
tuple([k, tuple([filename, filedata, mimetype])])
|
|
577
|
+
)
|
|
538
578
|
return params
|
|
539
579
|
|
|
540
580
|
def select_header_accept(self, accepts: List[str]) -> Optional[str]:
|
|
@@ -663,10 +703,12 @@ class ApiClient:
|
|
|
663
703
|
|
|
664
704
|
content_disposition = response.getheader("Content-Disposition")
|
|
665
705
|
if content_disposition:
|
|
666
|
-
|
|
706
|
+
m = re.search(
|
|
667
707
|
r'filename=[\'"]?([^\'"\s]+)[\'"]?',
|
|
668
708
|
content_disposition
|
|
669
|
-
)
|
|
709
|
+
)
|
|
710
|
+
assert m is not None, "Unexpected 'content-disposition' header value"
|
|
711
|
+
filename = m.group(1)
|
|
670
712
|
path = os.path.join(os.path.dirname(path), filename)
|
|
671
713
|
|
|
672
714
|
with open(path, "wb") as f:
|
|
@@ -733,6 +775,24 @@ class ApiClient:
|
|
|
733
775
|
)
|
|
734
776
|
)
|
|
735
777
|
|
|
778
|
+
def __deserialize_enum(self, data, klass):
|
|
779
|
+
"""Deserializes primitive type to enum.
|
|
780
|
+
|
|
781
|
+
:param data: primitive type.
|
|
782
|
+
:param klass: class literal.
|
|
783
|
+
:return: enum value.
|
|
784
|
+
"""
|
|
785
|
+
try:
|
|
786
|
+
return klass(data)
|
|
787
|
+
except ValueError:
|
|
788
|
+
raise rest.ApiException(
|
|
789
|
+
status=0,
|
|
790
|
+
reason=(
|
|
791
|
+
"Failed to parse `{0}` as `{1}`"
|
|
792
|
+
.format(data, klass)
|
|
793
|
+
)
|
|
794
|
+
)
|
|
795
|
+
|
|
736
796
|
def __deserialize_model(self, data, klass):
|
|
737
797
|
"""Deserializes list or dict to model.
|
|
738
798
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""API response object."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from typing import
|
|
5
|
-
from pydantic import Field, StrictInt,
|
|
4
|
+
from typing import Optional, Generic, Mapping, TypeVar
|
|
5
|
+
from pydantic import Field, StrictInt, StrictBytes, BaseModel
|
|
6
6
|
|
|
7
7
|
T = TypeVar("T")
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ class ApiResponse(BaseModel, Generic[T]):
|
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
status_code: StrictInt = Field(description="HTTP status code")
|
|
15
|
-
headers: Optional[
|
|
15
|
+
headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers")
|
|
16
16
|
data: T = Field(description="Deserialized data given the data type")
|
|
17
17
|
raw_data: StrictBytes = Field(description="Raw data (HTTP response body)")
|
|
18
18
|
|