ibm-cloud-sdk-core 3.16.0__py3-none-any.whl → 3.20.6__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.
- ibm_cloud_sdk_core/__init__.py +1 -0
- ibm_cloud_sdk_core/api_exception.py +18 -4
- ibm_cloud_sdk_core/authenticators/__init__.py +1 -0
- ibm_cloud_sdk_core/authenticators/authenticator.py +2 -1
- ibm_cloud_sdk_core/authenticators/basic_authenticator.py +5 -6
- ibm_cloud_sdk_core/authenticators/bearer_token_authenticator.py +1 -1
- ibm_cloud_sdk_core/authenticators/container_authenticator.py +25 -16
- ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py +33 -21
- ibm_cloud_sdk_core/authenticators/iam_authenticator.py +22 -13
- ibm_cloud_sdk_core/authenticators/iam_request_based_authenticator.py +5 -7
- ibm_cloud_sdk_core/authenticators/mcsp_authenticator.py +130 -0
- ibm_cloud_sdk_core/authenticators/vpc_instance_authenticator.py +7 -10
- ibm_cloud_sdk_core/base_service.py +107 -91
- ibm_cloud_sdk_core/detailed_response.py +21 -15
- ibm_cloud_sdk_core/get_authenticator.py +28 -16
- ibm_cloud_sdk_core/http_adapter.py +28 -0
- ibm_cloud_sdk_core/private_helpers.py +34 -0
- ibm_cloud_sdk_core/token_managers/container_token_manager.py +61 -30
- ibm_cloud_sdk_core/token_managers/cp4d_token_manager.py +30 -22
- ibm_cloud_sdk_core/token_managers/iam_request_based_token_manager.py +43 -20
- ibm_cloud_sdk_core/token_managers/iam_token_manager.py +24 -13
- ibm_cloud_sdk_core/token_managers/jwt_token_manager.py +3 -16
- ibm_cloud_sdk_core/token_managers/mcsp_token_manager.py +102 -0
- ibm_cloud_sdk_core/token_managers/token_manager.py +13 -23
- ibm_cloud_sdk_core/token_managers/vpc_instance_token_manager.py +33 -13
- ibm_cloud_sdk_core/utils.py +121 -46
- ibm_cloud_sdk_core/version.py +1 -1
- {ibm_cloud_sdk_core-3.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/METADATA +40 -28
- ibm_cloud_sdk_core-3.20.6.dist-info/RECORD +34 -0
- {ibm_cloud_sdk_core-3.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/WHEEL +1 -1
- ibm_cloud_sdk_core-3.20.6.dist-info/top_level.txt +1 -0
- ibm_cloud_sdk_core-3.16.0.dist-info/RECORD +0 -52
- ibm_cloud_sdk_core-3.16.0.dist-info/top_level.txt +0 -3
- ibm_cloud_sdk_core-3.16.0.dist-info/zip-safe +0 -1
- test/__init__.py +0 -0
- test/test_api_exception.py +0 -73
- test/test_authenticator.py +0 -21
- test/test_base_service.py +0 -933
- test/test_basic_authenticator.py +0 -36
- test/test_bearer_authenticator.py +0 -28
- test/test_container_authenticator.py +0 -105
- test/test_container_token_manager.py +0 -283
- test/test_cp4d_authenticator.py +0 -171
- test/test_cp4d_token_manager.py +0 -56
- test/test_detailed_response.py +0 -57
- test/test_iam_authenticator.py +0 -157
- test/test_iam_token_manager.py +0 -362
- test/test_jwt_token_manager.py +0 -109
- test/test_no_auth_authenticator.py +0 -15
- test/test_token_manager.py +0 -84
- test/test_utils.py +0 -634
- test/test_vpc_instance_authenticator.py +0 -66
- test/test_vpc_instance_token_manager.py +0 -266
- test_integration/__init__.py +0 -0
- test_integration/test_cp4d_authenticator_integration.py +0 -45
- {ibm_cloud_sdk_core-3.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
|
|
3
|
-
# Copyright 2021 IBM All Rights Reserved.
|
|
3
|
+
# Copyright 2021, 2024 IBM All Rights Reserved.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -18,6 +18,7 @@ import json
|
|
|
18
18
|
import logging
|
|
19
19
|
from typing import Optional
|
|
20
20
|
|
|
21
|
+
from ..private_helpers import _build_user_agent
|
|
21
22
|
from .jwt_token_manager import JWTTokenManager
|
|
22
23
|
|
|
23
24
|
|
|
@@ -52,18 +53,19 @@ class VPCInstanceTokenManager(JWTTokenManager):
|
|
|
52
53
|
url (str, optional): The VPC Instance Metadata Service's base endpoint URL.
|
|
53
54
|
"""
|
|
54
55
|
|
|
55
|
-
METADATA_SERVICE_VERSION = '
|
|
56
|
+
METADATA_SERVICE_VERSION = '2022-03-01'
|
|
56
57
|
DEFAULT_IMS_ENDPOINT = 'http://169.254.169.254'
|
|
57
58
|
TOKEN_NAME = 'access_token'
|
|
59
|
+
IAM_EXPIRATION_WINDOW = 10
|
|
58
60
|
|
|
59
|
-
def __init__(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
url: Optional[str] = None) -> None:
|
|
61
|
+
def __init__(
|
|
62
|
+
self, iam_profile_crn: Optional[str] = None, iam_profile_id: Optional[str] = None, url: Optional[str] = None
|
|
63
|
+
) -> None:
|
|
63
64
|
if not url:
|
|
64
65
|
url = self.DEFAULT_IMS_ENDPOINT
|
|
65
66
|
|
|
66
67
|
super().__init__(url, token_name=self.TOKEN_NAME)
|
|
68
|
+
self._set_user_agent(_build_user_agent('vpc-instance-authenticator'))
|
|
67
69
|
|
|
68
70
|
self.iam_profile_crn = iam_profile_crn
|
|
69
71
|
self.iam_profile_id = iam_profile_id
|
|
@@ -91,17 +93,18 @@ class VPCInstanceTokenManager(JWTTokenManager):
|
|
|
91
93
|
headers = {
|
|
92
94
|
'Content-Type': 'application/json',
|
|
93
95
|
'Accept': 'application/json',
|
|
94
|
-
'Authorization': 'Bearer ' + instance_identity_token
|
|
96
|
+
'Authorization': 'Bearer ' + instance_identity_token,
|
|
97
|
+
'User-Agent': self._get_user_agent(),
|
|
95
98
|
}
|
|
96
99
|
|
|
97
|
-
logger.debug(
|
|
98
|
-
'Invoking VPC \'create_iam_token\' operation: %s', url)
|
|
100
|
+
logger.debug('Invoking VPC \'create_iam_token\' operation: %s', url)
|
|
99
101
|
response = self._request(
|
|
100
102
|
method='POST',
|
|
101
103
|
url=url,
|
|
102
104
|
headers=headers,
|
|
103
105
|
params={'version': self.METADATA_SERVICE_VERSION},
|
|
104
|
-
data=json.dumps(request_payload) if request_payload else None
|
|
106
|
+
data=json.dumps(request_payload) if request_payload else None,
|
|
107
|
+
)
|
|
105
108
|
logger.debug('Returned from VPC \'create_iam_token\' operation."')
|
|
106
109
|
|
|
107
110
|
return response
|
|
@@ -138,18 +141,35 @@ class VPCInstanceTokenManager(JWTTokenManager):
|
|
|
138
141
|
'Content-type': 'application/json',
|
|
139
142
|
'Accept': 'application/json',
|
|
140
143
|
'Metadata-Flavor': 'ibm',
|
|
144
|
+
'User-Agent': self._get_user_agent(),
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
request_body = {'expires_in': 300}
|
|
144
148
|
|
|
145
|
-
logger.debug(
|
|
146
|
-
'Invoking VPC \'create_access_token\' operation: %s', url)
|
|
149
|
+
logger.debug('Invoking VPC \'create_access_token\' operation: %s', url)
|
|
147
150
|
response = self._request(
|
|
148
151
|
method='PUT',
|
|
149
152
|
url=url,
|
|
150
153
|
headers=headers,
|
|
151
154
|
params={'version': self.METADATA_SERVICE_VERSION},
|
|
152
|
-
data=json.dumps(request_body)
|
|
155
|
+
data=json.dumps(request_body),
|
|
156
|
+
)
|
|
153
157
|
logger.debug('Returned from VPC \'create_access_token\' operation."')
|
|
154
158
|
|
|
155
159
|
return response['access_token']
|
|
160
|
+
|
|
161
|
+
def _is_token_expired(self) -> bool:
|
|
162
|
+
"""
|
|
163
|
+
Returns true iff the current cached token is expired.
|
|
164
|
+
We'll consider an access token as expired when we reach its IAM server-reported expiration time
|
|
165
|
+
minus our expiration window (10 secs).
|
|
166
|
+
We do this to avoid using an access token that might expire in the middle of a long-running transaction
|
|
167
|
+
within an IBM Cloud service.
|
|
168
|
+
|
|
169
|
+
Returns
|
|
170
|
+
-------
|
|
171
|
+
bool
|
|
172
|
+
True if token is expired; False otherwise
|
|
173
|
+
"""
|
|
174
|
+
current_time = self._get_current_time()
|
|
175
|
+
return current_time >= (self.expire_time - self.IAM_EXPIRATION_WINDOW)
|
ibm_cloud_sdk_core/utils.py
CHANGED
|
@@ -15,32 +15,101 @@
|
|
|
15
15
|
# limitations under the License.
|
|
16
16
|
# from ibm_cloud_sdk_core.authenticators import Authenticator
|
|
17
17
|
import datetime
|
|
18
|
+
import gzip
|
|
19
|
+
import io
|
|
18
20
|
import json as json_import
|
|
19
|
-
import
|
|
21
|
+
import re
|
|
20
22
|
from os import getenv, environ, getcwd
|
|
21
23
|
from os.path import isfile, join, expanduser
|
|
22
24
|
from typing import List, Union
|
|
23
25
|
from urllib.parse import urlparse, parse_qs
|
|
24
26
|
|
|
25
|
-
from requests.adapters import HTTPAdapter
|
|
26
|
-
from urllib3.util.ssl_ import create_urllib3_context
|
|
27
|
-
|
|
28
27
|
import dateutil.parser as date_parser
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
class
|
|
32
|
-
"""
|
|
30
|
+
class GzipStream(io.RawIOBase):
|
|
31
|
+
"""Compress files on the fly.
|
|
32
|
+
|
|
33
|
+
GzipStream is a helper class around the gzip library. It helps to
|
|
34
|
+
compress already opened files (file-like objects) on the fly, so
|
|
35
|
+
there is no need to read everything into the memory and call the
|
|
36
|
+
`compress` function on it.
|
|
37
|
+
The GzipFile is opened on the instance itself so it needs to act
|
|
38
|
+
as a file-like object.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
input: the source of the data to be compressed.
|
|
42
|
+
It can be a file-like object, bytes or string.
|
|
33
43
|
"""
|
|
34
|
-
def __init__(self, *args, **kwargs):
|
|
35
|
-
super().__init__(*args, **kwargs)
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
def __init__(self, source: Union[io.IOBase, bytes, str]):
|
|
46
|
+
self.buffer = b''
|
|
47
|
+
|
|
48
|
+
if isinstance(source, io.IOBase):
|
|
49
|
+
# The input is already a file-like object, use it as-is.
|
|
50
|
+
self.uncompressed = source
|
|
51
|
+
elif isinstance(source, str):
|
|
52
|
+
# Strings must be handled with StringIO.
|
|
53
|
+
self.uncompressed = io.StringIO(source)
|
|
54
|
+
else:
|
|
55
|
+
# Handle the rest as raw bytes.
|
|
56
|
+
self.uncompressed = io.BytesIO(source)
|
|
57
|
+
|
|
58
|
+
self.compressor = gzip.GzipFile(fileobj=self, mode='wb')
|
|
59
|
+
|
|
60
|
+
def read(self, size: int = -1) -> bytes:
|
|
61
|
+
"""Compresses and returns the requested size of data.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
size: how many bytes to return. -1 to read and compress the whole file
|
|
40
65
|
"""
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
66
|
+
compressed = b''
|
|
67
|
+
|
|
68
|
+
if (size < 0) or (len(self.buffer) < size):
|
|
69
|
+
for raw in self.uncompressed:
|
|
70
|
+
# We need to encode text like streams (e.g. TextIOWrapper) to bytes.
|
|
71
|
+
if isinstance(raw, str):
|
|
72
|
+
raw = raw.encode()
|
|
73
|
+
|
|
74
|
+
self.compressor.write(raw)
|
|
75
|
+
|
|
76
|
+
# Stop compressing if we reached the max allowed size.
|
|
77
|
+
if 0 < size < len(self.buffer):
|
|
78
|
+
self.compressor.flush()
|
|
79
|
+
break
|
|
80
|
+
else:
|
|
81
|
+
self.compressor.close()
|
|
82
|
+
|
|
83
|
+
if size < 0:
|
|
84
|
+
# Return all data from the buffer.
|
|
85
|
+
compressed = self.buffer
|
|
86
|
+
self.buffer = b''
|
|
87
|
+
else:
|
|
88
|
+
# If we already have enough data in our buffer
|
|
89
|
+
# return the desired chunk of bytes
|
|
90
|
+
compressed = self.buffer[:size]
|
|
91
|
+
# then remove them from the buffer.
|
|
92
|
+
self.buffer = self.buffer[size:]
|
|
93
|
+
|
|
94
|
+
return compressed
|
|
95
|
+
|
|
96
|
+
def flush(self) -> None:
|
|
97
|
+
"""Not implemented."""
|
|
98
|
+
# Since this "pipe" sits between 2 other stream (source/read -> target/write)
|
|
99
|
+
# it wouldn't be worth to implemet flushing.
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
def write(self, compressed: bytes) -> None:
|
|
103
|
+
"""Append the compressed data to the buffer
|
|
104
|
+
|
|
105
|
+
This happens when the target stream calls the `read` method and
|
|
106
|
+
that triggers the gzip "compressor".
|
|
107
|
+
"""
|
|
108
|
+
self.buffer += compressed
|
|
109
|
+
|
|
110
|
+
def close(self) -> None:
|
|
111
|
+
"""Closes the underlying file-like object."""
|
|
112
|
+
self.uncompressed.close()
|
|
44
113
|
|
|
45
114
|
|
|
46
115
|
def has_bad_first_or_last_char(val: str) -> bool:
|
|
@@ -52,8 +121,7 @@ def has_bad_first_or_last_char(val: str) -> bool:
|
|
|
52
121
|
Returns:
|
|
53
122
|
Whether or not the string starts or ends with bad characters.
|
|
54
123
|
"""
|
|
55
|
-
return val is not None and (val.startswith('{') or val.startswith('"')
|
|
56
|
-
or val.endswith('}') or val.endswith('"'))
|
|
124
|
+
return val is not None and (val.startswith('{') or val.startswith('"') or val.endswith('}') or val.endswith('"'))
|
|
57
125
|
|
|
58
126
|
|
|
59
127
|
def remove_null_values(dictionary: dict) -> dict:
|
|
@@ -146,8 +214,9 @@ def string_to_datetime_list(string_list: List[str]) -> List[datetime.datetime]:
|
|
|
146
214
|
the de-serialized list of strings as a list of datetime objects.
|
|
147
215
|
"""
|
|
148
216
|
if not isinstance(string_list, list):
|
|
149
|
-
raise ValueError(
|
|
150
|
-
+ ". Argument string_list must be of type List[str]"
|
|
217
|
+
raise ValueError(
|
|
218
|
+
"Invalid argument type: " + str(type(string_list)) + ". Argument string_list must be of type List[str]"
|
|
219
|
+
)
|
|
151
220
|
datetime_list = []
|
|
152
221
|
for string_val in string_list:
|
|
153
222
|
datetime_list.append(string_to_datetime(string_val))
|
|
@@ -164,8 +233,11 @@ def datetime_to_string_list(datetime_list: List[datetime.datetime]) -> List[str]
|
|
|
164
233
|
list of datetimes serialized as strings in iso8601 format.
|
|
165
234
|
"""
|
|
166
235
|
if not isinstance(datetime_list, list):
|
|
167
|
-
raise ValueError(
|
|
168
|
-
|
|
236
|
+
raise ValueError(
|
|
237
|
+
"Invalid argument type: "
|
|
238
|
+
+ str(type(datetime_list))
|
|
239
|
+
+ ". Argument datetime_list must be of type List[datetime.datetime]"
|
|
240
|
+
)
|
|
169
241
|
string_list = []
|
|
170
242
|
for datetime_val in datetime_list:
|
|
171
243
|
string_list.append(datetime_to_string(datetime_val))
|
|
@@ -299,9 +371,7 @@ def __read_from_env_variables(service_name: str) -> dict:
|
|
|
299
371
|
return config
|
|
300
372
|
|
|
301
373
|
|
|
302
|
-
def __read_from_credential_file(service_name: str,
|
|
303
|
-
*,
|
|
304
|
-
separator: str = '=') -> dict:
|
|
374
|
+
def __read_from_credential_file(service_name: str, *, separator: str = '=') -> dict:
|
|
305
375
|
"""Return a config object based on credentials file for a service.
|
|
306
376
|
|
|
307
377
|
Args:
|
|
@@ -339,8 +409,7 @@ def __read_from_credential_file(service_name: str,
|
|
|
339
409
|
if len(key_val) == 2:
|
|
340
410
|
key = key_val[0]
|
|
341
411
|
value = key_val[1]
|
|
342
|
-
_parse_key_and_update_config(config, service_name, key,
|
|
343
|
-
value)
|
|
412
|
+
_parse_key_and_update_config(config, service_name, key, value)
|
|
344
413
|
except OSError:
|
|
345
414
|
# just absorb the exception and make sure we return an empty response
|
|
346
415
|
config = {}
|
|
@@ -348,11 +417,10 @@ def __read_from_credential_file(service_name: str,
|
|
|
348
417
|
return config
|
|
349
418
|
|
|
350
419
|
|
|
351
|
-
def _parse_key_and_update_config(config: dict, service_name: str, key: str,
|
|
352
|
-
value: str) -> None:
|
|
420
|
+
def _parse_key_and_update_config(config: dict, service_name: str, key: str, value: str) -> None:
|
|
353
421
|
service_name = service_name.replace(' ', '_').replace('-', '_').upper()
|
|
354
422
|
if key.startswith(service_name):
|
|
355
|
-
config[key[len(service_name) + 1:]] = value
|
|
423
|
+
config[key[len(service_name) + 1 :]] = value
|
|
356
424
|
|
|
357
425
|
|
|
358
426
|
def __read_from_vcap_services(service_name: str) -> dict:
|
|
@@ -370,39 +438,46 @@ def __read_from_vcap_services(service_name: str) -> dict:
|
|
|
370
438
|
services = json_import.loads(vcap_services)
|
|
371
439
|
for key in services.keys():
|
|
372
440
|
for i in range(len(services[key])):
|
|
373
|
-
if vcap_service_credentials and isinstance(
|
|
374
|
-
vcap_service_credentials, dict):
|
|
441
|
+
if vcap_service_credentials and isinstance(vcap_service_credentials, dict):
|
|
375
442
|
break
|
|
376
443
|
if services[key][i].get('name') == service_name:
|
|
377
|
-
vcap_service_credentials = services[key][i].get(
|
|
378
|
-
'credentials', {})
|
|
444
|
+
vcap_service_credentials = services[key][i].get('credentials', {})
|
|
379
445
|
if not vcap_service_credentials:
|
|
380
446
|
if service_name in services.keys():
|
|
381
447
|
service = services.get(service_name)
|
|
382
448
|
if service:
|
|
383
|
-
vcap_service_credentials = service[0].get(
|
|
384
|
-
'credentials', {})
|
|
449
|
+
vcap_service_credentials = service[0].get('credentials', {})
|
|
385
450
|
|
|
386
|
-
if vcap_service_credentials and isinstance(vcap_service_credentials,
|
|
387
|
-
dict):
|
|
451
|
+
if vcap_service_credentials and isinstance(vcap_service_credentials, dict):
|
|
388
452
|
new_vcap_creds = {}
|
|
389
453
|
# cf
|
|
390
|
-
if vcap_service_credentials.get(
|
|
391
|
-
'username') and vcap_service_credentials.get('password'):
|
|
454
|
+
if vcap_service_credentials.get('username') and vcap_service_credentials.get('password'):
|
|
392
455
|
new_vcap_creds['AUTH_TYPE'] = 'basic'
|
|
393
|
-
new_vcap_creds['USERNAME'] = vcap_service_credentials.get(
|
|
394
|
-
|
|
395
|
-
new_vcap_creds['PASSWORD'] = vcap_service_credentials.get(
|
|
396
|
-
'password')
|
|
456
|
+
new_vcap_creds['USERNAME'] = vcap_service_credentials.get('username')
|
|
457
|
+
new_vcap_creds['PASSWORD'] = vcap_service_credentials.get('password')
|
|
397
458
|
vcap_service_credentials = new_vcap_creds
|
|
398
459
|
elif vcap_service_credentials.get('iam_apikey'):
|
|
399
460
|
new_vcap_creds['AUTH_TYPE'] = 'iam'
|
|
400
|
-
new_vcap_creds['APIKEY'] = vcap_service_credentials.get(
|
|
401
|
-
'iam_apikey')
|
|
461
|
+
new_vcap_creds['APIKEY'] = vcap_service_credentials.get('iam_apikey')
|
|
402
462
|
vcap_service_credentials = new_vcap_creds
|
|
403
463
|
elif vcap_service_credentials.get('apikey'):
|
|
404
464
|
new_vcap_creds['AUTH_TYPE'] = 'iam'
|
|
405
|
-
new_vcap_creds['APIKEY'] = vcap_service_credentials.get(
|
|
406
|
-
'apikey')
|
|
465
|
+
new_vcap_creds['APIKEY'] = vcap_service_credentials.get('apikey')
|
|
407
466
|
vcap_service_credentials = new_vcap_creds
|
|
408
467
|
return vcap_service_credentials
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
# A regex that matches an "application/json" mimetype.
|
|
471
|
+
json_mimetype_pattern = re.compile('^application/json(\\s*;.*)?$')
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
def is_json_mimetype(mimetype: str) -> bool:
|
|
475
|
+
"""Returns true if 'mimetype' is a JSON-like mimetype, false otherwise.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
mimetype: The mimetype to check.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
true if mimetype is a JSON-line mimetype, false otherwise.
|
|
482
|
+
"""
|
|
483
|
+
return mimetype is not None and json_mimetype_pattern.match(mimetype) is not None
|
ibm_cloud_sdk_core/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '3.
|
|
1
|
+
__version__ = '3.20.6'
|
|
@@ -1,30 +1,47 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ibm-cloud-sdk-core
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.20.6
|
|
4
4
|
Summary: Core library used by SDKs for IBM Cloud Services
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
Author-email: IBM <devxsdk@us.ibm.com>
|
|
6
|
+
Project-URL: Repository, https://github.com/IBM/python-sdk-core
|
|
7
|
+
Project-URL: Documentation, https://github.com/IBM/python-sdk-core/blob/main/README.md
|
|
8
|
+
Project-URL: Issues, https://github.com/IBM/python-sdk-core/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/IBM/python-sdk-core/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Contributing, https://github.com/IBM/python-sdk-core/blob/main/CONTRIBUTING.md
|
|
11
|
+
Project-URL: License, https://github.com/IBM/python-sdk-core/blob/main/LICENSE
|
|
12
|
+
Keywords: ibm,cloud,ibm cloud services
|
|
10
13
|
Classifier: Programming Language :: Python
|
|
11
14
|
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
13
15
|
Classifier: Programming Language :: Python :: 3.8
|
|
14
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
15
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
20
|
Classifier: Development Status :: 5 - Production/Stable
|
|
21
|
+
Classifier: Environment :: Console
|
|
17
22
|
Classifier: Intended Audience :: Developers
|
|
18
23
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
19
24
|
Classifier: Operating System :: OS Independent
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
27
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
28
|
+
Requires-Python: >=3.8
|
|
22
29
|
Description-Content-Type: text/markdown
|
|
23
30
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: requests
|
|
25
|
-
Requires-Dist: urllib3
|
|
26
|
-
Requires-Dist: python-dateutil
|
|
27
|
-
Requires-Dist: PyJWT
|
|
31
|
+
Requires-Dist: requests <3.0.0,>=2.31.0
|
|
32
|
+
Requires-Dist: urllib3 <3.0.0,>=2.1.0
|
|
33
|
+
Requires-Dist: python-dateutil <3.0.0,>=2.8.2
|
|
34
|
+
Requires-Dist: PyJWT <3.0.0,>=2.8.0
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: coverage <8.0.0,>=7.3.2 ; extra == 'dev'
|
|
37
|
+
Requires-Dist: pylint <4.0.0,>=3.0.0 ; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest <8.0.0,>=7.4.2 ; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-cov <5.0.0,>=4.1.0 ; extra == 'dev'
|
|
40
|
+
Requires-Dist: responses <1.0.0,>=0.23.3 ; extra == 'dev'
|
|
41
|
+
Requires-Dist: black <25.0.0,>=24.0.0 ; extra == 'dev'
|
|
42
|
+
Provides-Extra: publish
|
|
43
|
+
Requires-Dist: build ; extra == 'publish'
|
|
44
|
+
Requires-Dist: twine ; extra == 'publish'
|
|
28
45
|
|
|
29
46
|
[](https://app.travis-ci.com/IBM/python-sdk-core)
|
|
30
47
|
[](https://pypi.org/project/ibm-cloud-sdk-core/)
|
|
@@ -32,37 +49,32 @@ Requires-Dist: PyJWT (<3.0.0,>=2.4.0)
|
|
|
32
49
|
[](https://cla-assistant.io/ibm/python-sdk-core)
|
|
33
50
|
[](https://github.com/semantic-release/semantic-release)
|
|
34
51
|
|
|
35
|
-
# IBM Python SDK Core Version 3.
|
|
52
|
+
# IBM Python SDK Core Version 3.20.6
|
|
36
53
|
This project contains core functionality required by Python code generated by the IBM Cloud OpenAPI SDK Generator
|
|
37
54
|
(openapi-sdkgen).
|
|
38
55
|
|
|
39
56
|
# Python Version
|
|
40
|
-
The current minimum Python version supported is 3.
|
|
57
|
+
The current minimum Python version supported is 3.8.
|
|
41
58
|
|
|
42
59
|
## Installation
|
|
43
60
|
|
|
44
|
-
To install, use `pip
|
|
61
|
+
To install, use `pip`:
|
|
45
62
|
|
|
46
63
|
```bash
|
|
47
|
-
pip install --upgrade ibm-cloud-sdk-core
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
or
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
easy_install --upgrade ibm-cloud-sdk-core
|
|
64
|
+
python -m pip install --upgrade ibm-cloud-sdk-core
|
|
54
65
|
```
|
|
55
66
|
|
|
56
67
|
## Authentication
|
|
57
68
|
The python-sdk-core project supports the following types of authentication:
|
|
58
69
|
- Basic Authentication
|
|
59
|
-
- Bearer Token
|
|
60
|
-
- Identity and Access Management (IAM)
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
- Bearer Token Authentication
|
|
71
|
+
- Identity and Access Management (IAM) Authentication
|
|
72
|
+
- Container Authentication
|
|
73
|
+
- VPC Instance Authentication
|
|
74
|
+
- Cloud Pak for Data Authentication
|
|
75
|
+
- No Authentication (for testing)
|
|
76
|
+
|
|
77
|
+
For more information about the various authentication types and how to use them with your services, click [here](Authentication.md).
|
|
66
78
|
|
|
67
79
|
## Issues
|
|
68
80
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
ibm_cloud_sdk_core/__init__.py,sha256=Ef7P3r-KmVwoYQV9bP0zvaDSlgJtjaTcDYQXmVvm0Zs,2853
|
|
2
|
+
ibm_cloud_sdk_core/api_exception.py,sha256=YNd7Dg_yiwcHk-AA-suNlivgyrA9A32Do1qtYeKzuWc,3654
|
|
3
|
+
ibm_cloud_sdk_core/base_service.py,sha256=GmvE4yCGHP1LXLsOnj1Q_GoizIsLrHU2YJPShZNbMRM,21056
|
|
4
|
+
ibm_cloud_sdk_core/detailed_response.py,sha256=agLMQ-Mh3bU_lLnSnSO1SwjuNBPQj8plO8ew2xXWL6I,3101
|
|
5
|
+
ibm_cloud_sdk_core/get_authenticator.py,sha256=GcKk8LI1xX1AC0S5x3SQxoaQJne4K0ae_KPf8bNgi50,4577
|
|
6
|
+
ibm_cloud_sdk_core/http_adapter.py,sha256=nRUvt7hbSC8Vyhqe_oA5k_NKoRMM-S4VCSAZVQ-AHQU,1075
|
|
7
|
+
ibm_cloud_sdk_core/private_helpers.py,sha256=5ei9gNwuN-inNJ2WqMXcXEPfLM1NALOLi4ucLMcYohY,1181
|
|
8
|
+
ibm_cloud_sdk_core/utils.py,sha256=caUFQWS06nzVW9ooU7ZG2pEJol-jjZ53JiLnLkQT_6k,15636
|
|
9
|
+
ibm_cloud_sdk_core/version.py,sha256=rHqvR40CBAKEsUqfGKCi0eEi3aO5lGioNtRWEfFuylY,23
|
|
10
|
+
ibm_cloud_sdk_core/authenticators/__init__.py,sha256=Ze_ArDqMWk1Xr311dXpHTtJUJYN2u8jCphoGTLBow9M,2133
|
|
11
|
+
ibm_cloud_sdk_core/authenticators/authenticator.py,sha256=dyTQDEAhlcN4y-wybTgMycSO5dC2pLntx3KCJTJGHdQ,1979
|
|
12
|
+
ibm_cloud_sdk_core/authenticators/basic_authenticator.py,sha256=moHfqmI0Lekgsrl0kjLvhyUbcMhh7tPPZArKn9OW_gQ,3129
|
|
13
|
+
ibm_cloud_sdk_core/authenticators/bearer_token_authenticator.py,sha256=KtoN4lgEIIbRiWLJHftPjK_CLQj_sx5lmrc2xm1E7mk,2623
|
|
14
|
+
ibm_cloud_sdk_core/authenticators/container_authenticator.py,sha256=GKYHTflLiKhm9xF5KZAcjYXPN3yE2PztdEr2bOZUwKE,7042
|
|
15
|
+
ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py,sha256=9xaoEbqQqFVO1DdYDPMTMyIlrAAS8TrTSKxqOh4hHfI,6752
|
|
16
|
+
ibm_cloud_sdk_core/authenticators/iam_authenticator.py,sha256=ozrFBdVah1y8gcLL68fmReXCFEAltOGLCIuA6PuWLSY,4597
|
|
17
|
+
ibm_cloud_sdk_core/authenticators/iam_request_based_authenticator.py,sha256=JUUZF_UgWQmA9U6WxsdSHzuL3R6fxEDdC0VgHHt1Ygk,4515
|
|
18
|
+
ibm_cloud_sdk_core/authenticators/mcsp_authenticator.py,sha256=F6b4s7QXkqWP_5ls21jZPquxIz7HfFm7MTotVtVY3fA,5179
|
|
19
|
+
ibm_cloud_sdk_core/authenticators/no_auth_authenticator.py,sha256=dzuU6IJC19SocVHy7Fyln6xrfGvlqnXGeUNR9llspYo,979
|
|
20
|
+
ibm_cloud_sdk_core/authenticators/vpc_instance_authenticator.py,sha256=xdWHjGWFoSzf0bB0fnnT9fTs-N708cnUxRJ2I-kUQME,5243
|
|
21
|
+
ibm_cloud_sdk_core/token_managers/__init__.py,sha256=NEiims6qB8doxq6wtlTBYCIdwf2wRiMTrV0bgfv7WAg,606
|
|
22
|
+
ibm_cloud_sdk_core/token_managers/container_token_manager.py,sha256=jkOJoy9SutIvYrwoQfm9OQ4lfn0lI4jJNfcIFiAqh9M,9505
|
|
23
|
+
ibm_cloud_sdk_core/token_managers/cp4d_token_manager.py,sha256=EeE7EZtwAIVYCcnlTdbWU1U77PFbmZLgHL9LuCDJy_Q,4948
|
|
24
|
+
ibm_cloud_sdk_core/token_managers/iam_request_based_token_manager.py,sha256=KOz5aXjHfYWCQWqSpvf7vNLEzZq0ZKLAHVtHzcnQKfY,8314
|
|
25
|
+
ibm_cloud_sdk_core/token_managers/iam_token_manager.py,sha256=bG94h0Io6XaneLUcSuJzLlKSpFLdKH49TieRNAY7fvA,4358
|
|
26
|
+
ibm_cloud_sdk_core/token_managers/jwt_token_manager.py,sha256=FDBdvirmUcJu5vIb5pdhqoQeFS6j0GBSDsF0HtLjg48,3785
|
|
27
|
+
ibm_cloud_sdk_core/token_managers/mcsp_token_manager.py,sha256=qo2slOLUfxZ296iO6flQEbJZtYKTD9XXhuHKCvBesJM,3992
|
|
28
|
+
ibm_cloud_sdk_core/token_managers/token_manager.py,sha256=ve83zlER6TiflGha6qo_DXyku6b2xoeMT4PBpENBeco,7715
|
|
29
|
+
ibm_cloud_sdk_core/token_managers/vpc_instance_token_manager.py,sha256=hZP-0H9YPoB6R4mTJZ0zZBxMCJhMUSrvVfzVZXVdti8,6998
|
|
30
|
+
ibm_cloud_sdk_core-3.20.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
31
|
+
ibm_cloud_sdk_core-3.20.6.dist-info/METADATA,sha256=tK0mVDJDcPS37D1ILTH-qH5kSdRDqh7ZqTLwDyfGFH4,5509
|
|
32
|
+
ibm_cloud_sdk_core-3.20.6.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
33
|
+
ibm_cloud_sdk_core-3.20.6.dist-info/top_level.txt,sha256=otLtvxe-8ugPRmPqeSnbaOjnAl0qjDRZ1HSkC3aeLpI,19
|
|
34
|
+
ibm_cloud_sdk_core-3.20.6.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ibm_cloud_sdk_core
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
ibm_cloud_sdk_core/__init__.py,sha256=uVj5a2fM1X6OQ1ivAMf1BNUViJGex8RBOAMF4bhOUeA,2789
|
|
2
|
-
ibm_cloud_sdk_core/api_exception.py,sha256=OvY5-ACudE04O6heN8WwiTpEvNPEMjHx8iifC09IqjI,3180
|
|
3
|
-
ibm_cloud_sdk_core/base_service.py,sha256=XA1rPZczIEwvF41KXQlXFkOMmk3MPv7mYk1U1MdmhQk,20326
|
|
4
|
-
ibm_cloud_sdk_core/detailed_response.py,sha256=JJ0QErbtQn0IWBfqclHhsugktgDQ6m26D6uMIH9jxhw,2739
|
|
5
|
-
ibm_cloud_sdk_core/get_authenticator.py,sha256=jQV2PJGUzPCgVh15t9LG_Towkm7rPwAmIVJhfmoQUUk,4416
|
|
6
|
-
ibm_cloud_sdk_core/utils.py,sha256=NxYaU45OoIbiBmI0NUcHH7bI5PEiVgx_FMTbchTFE1c,13267
|
|
7
|
-
ibm_cloud_sdk_core/version.py,sha256=QvIdF5iFXpxlDqlLo7VlyHafPD55za59ZtMi1jF2kSo,23
|
|
8
|
-
ibm_cloud_sdk_core/authenticators/__init__.py,sha256=HLrbQMlA15-SKSgB2rW0qAjWDjnWNKWcqv2-Aet6iuQ,2083
|
|
9
|
-
ibm_cloud_sdk_core/authenticators/authenticator.py,sha256=WVVojlEPA8WMxWUSvFx7tCamU6fpDx5EwvZ0WYRqAJg,1946
|
|
10
|
-
ibm_cloud_sdk_core/authenticators/basic_authenticator.py,sha256=l-q55Xdv5ULhT_tF3lJgQPaFt_N0psAMolPzcERF-FE,3147
|
|
11
|
-
ibm_cloud_sdk_core/authenticators/bearer_token_authenticator.py,sha256=fHRSCGb8OQa6Rt6UIwO3fWmQMfNCGQDeq7ZBa_CPgIk,2624
|
|
12
|
-
ibm_cloud_sdk_core/authenticators/container_authenticator.py,sha256=jIssE6O0XoghQySqJUAC_Z5E-pM3umvrEHbo0Poh7R0,7040
|
|
13
|
-
ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py,sha256=iUnmkmP8DAjX8LCm-eB6d-S_IPRlzoYonIR7zdj0yn8,6719
|
|
14
|
-
ibm_cloud_sdk_core/authenticators/iam_authenticator.py,sha256=E62Lzl8TJ448RzI8Iz7kz0t2iysuaY9S1T0Q95H3b2A,4580
|
|
15
|
-
ibm_cloud_sdk_core/authenticators/iam_request_based_authenticator.py,sha256=USEid25ZZc4dw8syjN0dXynIlBsOhoxx_u7tDTok9Mc,4568
|
|
16
|
-
ibm_cloud_sdk_core/authenticators/no_auth_authenticator.py,sha256=dzuU6IJC19SocVHy7Fyln6xrfGvlqnXGeUNR9llspYo,979
|
|
17
|
-
ibm_cloud_sdk_core/authenticators/vpc_instance_authenticator.py,sha256=p5jfxR1Vwau7alnJ-mGYOZbqPJmp6mp0c1NviZtSpvs,5291
|
|
18
|
-
ibm_cloud_sdk_core/token_managers/__init__.py,sha256=NEiims6qB8doxq6wtlTBYCIdwf2wRiMTrV0bgfv7WAg,606
|
|
19
|
-
ibm_cloud_sdk_core/token_managers/container_token_manager.py,sha256=fz0FRk-vQQcDehUXwPFgI0eSXWPn41Xtb2dNsQP8uOE,8441
|
|
20
|
-
ibm_cloud_sdk_core/token_managers/cp4d_token_manager.py,sha256=cjC24U8kud_j_DKec1vFZO-eP2qZbsV70VOdd9pvXZ4,4690
|
|
21
|
-
ibm_cloud_sdk_core/token_managers/iam_request_based_token_manager.py,sha256=f8DVYksQWHuJp_OAstaAFO1xvDO2ufMZvq7ikC6zk1E,7516
|
|
22
|
-
ibm_cloud_sdk_core/token_managers/iam_token_manager.py,sha256=RNGLAFW5z-9zarR6g_Ry7FKU4LxxzTESux3cBICZh3s,4230
|
|
23
|
-
ibm_cloud_sdk_core/token_managers/jwt_token_manager.py,sha256=OaqICSRrnJ0C322IqlhkjyT_cOEy3ZmH_DKWVXkHoCU,3984
|
|
24
|
-
ibm_cloud_sdk_core/token_managers/token_manager.py,sha256=_DULCGRmerMEkW4Tgi8HntXs0bu8-mgNQoSKLstpJQc,7660
|
|
25
|
-
ibm_cloud_sdk_core/token_managers/vpc_instance_token_manager.py,sha256=J-wJWh95MXsNjbTnY-VAY5dRJ4W79yJ0e3y4ZhbvHjU,6122
|
|
26
|
-
test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
-
test/test_api_exception.py,sha256=zBdMGwXHlM4LBRgipadPPcmKb8TIDnZIsE07iH49tGk,2850
|
|
28
|
-
test/test_authenticator.py,sha256=yL4ZM5aPS5WDcekq28IxPeaxAgc_ujz64XUVwUhVv1o,592
|
|
29
|
-
test/test_base_service.py,sha256=l-7LDCBjBJW4-Vs459NsNpTcumCBMDikqbvphFVRHsQ,34363
|
|
30
|
-
test/test_basic_authenticator.py,sha256=FeGXWiY8xj8i6J2X5Q--qb6B-SAOvQzjg5eExpYVzPE,1605
|
|
31
|
-
test/test_bearer_authenticator.py,sha256=KFssfBZM109_1jWlYzPlZr3oo3vVYUkLVfIWfZZI9Us,1069
|
|
32
|
-
test/test_container_authenticator.py,sha256=a2iZO5qc0oMl7i6Y0KJiE-IYnTuAuRFe_r-ht1d4XVc,4422
|
|
33
|
-
test/test_container_token_manager.py,sha256=oZqmlVYF1HtkzOp0Ti1qS9CeGAoADhwqoO-FZW3D8rM,10644
|
|
34
|
-
test/test_cp4d_authenticator.py,sha256=GJVYRVwkPsyfWku8btjnrQCH-D3JHX8PBMA_3DdwYrM,6844
|
|
35
|
-
test/test_cp4d_token_manager.py,sha256=AJAB3fiu-3D1N3e28T7eYVCLd5G6xwx6ts8nc_gw7Hk,1735
|
|
36
|
-
test/test_detailed_response.py,sha256=iJWPzl-ZjghHc08O3BK3-bgLHfq8B8drotvxY68B0tw,2329
|
|
37
|
-
test/test_iam_authenticator.py,sha256=BbrnZAM2B9FZFxsfddsqQ8dJKuiMbEkrs6svdCdGCx4,5729
|
|
38
|
-
test/test_iam_token_manager.py,sha256=b6xsOaJCYDQ8FYqqqyTB4tWI4lSGsQ6Jqz5iuWCEjHE,12569
|
|
39
|
-
test/test_jwt_token_manager.py,sha256=b692b6Nnw_w0kBy7mslwVdhcImXg2uhSf9e7iaXfBkg,3820
|
|
40
|
-
test/test_no_auth_authenticator.py,sha256=LVytWa77ilm7Yhcc9qtG0WhsvYJpAUgPulbnwpvsLJc,448
|
|
41
|
-
test/test_token_manager.py,sha256=33OqwucCce9uoQWRHIjWFVH4EdBYmp1Y9gPJ2gueGvI,3031
|
|
42
|
-
test/test_utils.py,sha256=-6_D6N14ljUNUs-HzTTy5DgjGIaYirgwK8OZI-acnl8,28577
|
|
43
|
-
test/test_vpc_instance_authenticator.py,sha256=bdxWF6FTKR-GxJKo0vV8MhdBYAbsmD9OxHD0iooXTfo,2629
|
|
44
|
-
test/test_vpc_instance_token_manager.py,sha256=zhoL0MFcm3xFs-rbYiBLbOAfH8N_ZNj_t1o74oNaD8A,10103
|
|
45
|
-
test_integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
-
test_integration/test_cp4d_authenticator_integration.py,sha256=1CDn5Hi5_mYTzPOGH0AN5thyN4PfbG6pR3XRgs2gsZA,1650
|
|
47
|
-
ibm_cloud_sdk_core-3.16.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
48
|
-
ibm_cloud_sdk_core-3.16.0.dist-info/METADATA,sha256=z9H_fTF0lvP2h7hw3UM1P39cet0dbR_WQXn7y_XhIds,4460
|
|
49
|
-
ibm_cloud_sdk_core-3.16.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
50
|
-
ibm_cloud_sdk_core-3.16.0.dist-info/top_level.txt,sha256=16lTiCOoJ5PUYTGw9ROgE93YWrwqgR1sRU6fJcU7h0U,41
|
|
51
|
-
ibm_cloud_sdk_core-3.16.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
52
|
-
ibm_cloud_sdk_core-3.16.0.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
test/__init__.py
DELETED
|
File without changes
|
test/test_api_exception.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# coding=utf-8
|
|
2
|
-
import json
|
|
3
|
-
|
|
4
|
-
import requests
|
|
5
|
-
import responses
|
|
6
|
-
|
|
7
|
-
from ibm_cloud_sdk_core import ApiException
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@responses.activate
|
|
11
|
-
def test_api_exception():
|
|
12
|
-
"""Test APIException class"""
|
|
13
|
-
responses.add(responses.GET,
|
|
14
|
-
'https://test.com',
|
|
15
|
-
status=500,
|
|
16
|
-
body=json.dumps({'error': 'sorry', 'msg': 'serious error'}),
|
|
17
|
-
content_type='application/json')
|
|
18
|
-
|
|
19
|
-
mock_response = requests.get('https://test.com')
|
|
20
|
-
exception = ApiException(500, http_response=mock_response)
|
|
21
|
-
assert exception is not None
|
|
22
|
-
assert exception.message == 'sorry'
|
|
23
|
-
|
|
24
|
-
responses.add(responses.GET,
|
|
25
|
-
'https://test-again.com',
|
|
26
|
-
status=500,
|
|
27
|
-
body=json.dumps({
|
|
28
|
-
"errors": [
|
|
29
|
-
{
|
|
30
|
-
"message": "sorry again",
|
|
31
|
-
}],
|
|
32
|
-
}),
|
|
33
|
-
content_type='application/json')
|
|
34
|
-
mock_response = requests.get('https://test-again.com')
|
|
35
|
-
exception = ApiException(500, http_response=mock_response)
|
|
36
|
-
assert exception.message == 'sorry again'
|
|
37
|
-
|
|
38
|
-
responses.add(responses.GET,
|
|
39
|
-
'https://test-once-more.com',
|
|
40
|
-
status=500,
|
|
41
|
-
body=json.dumps({'message': 'sorry once more'}),
|
|
42
|
-
content_type='application/json')
|
|
43
|
-
mock_response = requests.get('https://test-once-more.com')
|
|
44
|
-
exception = ApiException(500, http_response=mock_response)
|
|
45
|
-
assert exception.message == 'sorry once more'
|
|
46
|
-
|
|
47
|
-
responses.add(responses.GET,
|
|
48
|
-
'https://test-msg.com',
|
|
49
|
-
status=500,
|
|
50
|
-
body=json.dumps({'msg': 'serious error'}),
|
|
51
|
-
content_type='application/json')
|
|
52
|
-
mock_response = requests.get('https://test-msg.com')
|
|
53
|
-
exception = ApiException(500, http_response=mock_response)
|
|
54
|
-
assert exception.message == 'Internal Server Error'
|
|
55
|
-
|
|
56
|
-
responses.add(responses.GET,
|
|
57
|
-
'https://test-errormessage.com',
|
|
58
|
-
status=500,
|
|
59
|
-
body=json.dumps({'errorMessage': 'IAM error message'}),
|
|
60
|
-
content_type='application/json')
|
|
61
|
-
mock_response = requests.get('https://test-errormessage.com')
|
|
62
|
-
exception = ApiException(500, http_response=mock_response)
|
|
63
|
-
assert exception.message == 'IAM error message'
|
|
64
|
-
|
|
65
|
-
responses.add(responses.GET,
|
|
66
|
-
'https://test-for-text.com',
|
|
67
|
-
status=500,
|
|
68
|
-
headers={'X-Global-Transaction-ID': 'xx'},
|
|
69
|
-
body="plain text error")
|
|
70
|
-
mock_response = requests.get('https://test-for-text.com')
|
|
71
|
-
exception = ApiException(500, http_response=mock_response)
|
|
72
|
-
assert exception.message == 'plain text error'
|
|
73
|
-
assert str(exception) == 'Error: plain text error, Code: 500 , X-global-transaction-id: xx'
|