protegrity-ai-developer-python 1.2.1__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.
- appython/__init__.py +12 -0
- appython/protector.py +554 -0
- appython/service/auth_provider.py +273 -0
- appython/service/auth_token_provider.py +45 -0
- appython/service/config.py +209 -0
- appython/service/payload_builder.py +141 -0
- appython/service/request_handler.py +115 -0
- appython/service/response_handler.py +78 -0
- appython/stats/__init__.py +3 -0
- appython/stats/collector.py +90 -0
- appython/stats/writer.py +185 -0
- appython/utils/codec_helper.py +86 -0
- appython/utils/constants.py +246 -0
- appython/utils/exceptions.py +141 -0
- appython/utils/input_preprocessor.py +325 -0
- appython/utils/output_postprocessor.py +99 -0
- protegrity_ai_developer_python-1.2.1.dist-info/METADATA +428 -0
- protegrity_ai_developer_python-1.2.1.dist-info/RECORD +53 -0
- protegrity_ai_developer_python-1.2.1.dist-info/WHEEL +5 -0
- protegrity_ai_developer_python-1.2.1.dist-info/entry_points.txt +2 -0
- protegrity_ai_developer_python-1.2.1.dist-info/licenses/LICENSE +21 -0
- protegrity_ai_developer_python-1.2.1.dist-info/top_level.txt +3 -0
- protegrity_developer_python/__init__.py +4 -0
- protegrity_developer_python/scan.py +37 -0
- protegrity_developer_python/securefind.py +83 -0
- protegrity_developer_python/utils/ccn_processing.py +59 -0
- protegrity_developer_python/utils/config.py +60 -0
- protegrity_developer_python/utils/constants.py +123 -0
- protegrity_developer_python/utils/discover.py +49 -0
- protegrity_developer_python/utils/logger.py +23 -0
- protegrity_developer_python/utils/pii_processing.py +291 -0
- protegrity_developer_python/utils/protector.py +23 -0
- protegrity_developer_python/utils/semantic_guardrails.py +240 -0
- protegrity_developer_python/utils/transform.py +66 -0
- pty_migrate/__init__.py +1 -0
- pty_migrate/check_cmd.py +871 -0
- pty_migrate/cli.py +93 -0
- pty_migrate/config.py +127 -0
- pty_migrate/create_policy_cmd.py +795 -0
- pty_migrate/payloads/__init__.py +51 -0
- pty_migrate/payloads/alphabets.json +42 -0
- pty_migrate/payloads/dataelements.json +342 -0
- pty_migrate/payloads/datastores.json +7 -0
- pty_migrate/payloads/deploy_policy_ta.json +1 -0
- pty_migrate/payloads/masks.json +18 -0
- pty_migrate/payloads/members.json +62 -0
- pty_migrate/payloads/policies.json +13 -0
- pty_migrate/payloads/roles.json +32 -0
- pty_migrate/payloads/rules.json +1639 -0
- pty_migrate/payloads/sources.json +10 -0
- pty_migrate/payloads/trusted_apps.json +8 -0
- pty_migrate/ppc_client.py +371 -0
- pty_migrate/stats_cmd.py +87 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides the InputPreprocessor class, which is responsible for validating and processing
|
|
3
|
+
input parameters for data protection operations such as PROTECT, UNPROTECT, and REPROTECT.
|
|
4
|
+
It ensures that the input data is correctly formatted, handles character sets, and prepares the
|
|
5
|
+
parameters for further processing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from appython.utils.constants import (
|
|
9
|
+
ARGS_PROTECT as args_protect,
|
|
10
|
+
OP_TYPE as op_type,
|
|
11
|
+
ARGS_UNPROTECT as args_unprotect,
|
|
12
|
+
ARGS_REPROTECT as args_reprotect,
|
|
13
|
+
DATATYPES as datatypes,
|
|
14
|
+
ErrorMessage,
|
|
15
|
+
Charset,
|
|
16
|
+
)
|
|
17
|
+
from appython.utils.codec_helper import (
|
|
18
|
+
convert_b64_bytes_b64_string,
|
|
19
|
+
decode_bytes,
|
|
20
|
+
encode_to_base64_string,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def validate_charset(kwargs, response_type):
|
|
25
|
+
"""
|
|
26
|
+
Validates the use of the 'charset' keyword argument based on the expected response type.
|
|
27
|
+
|
|
28
|
+
This function ensures that the 'charset' parameter is only used when the response type is 'bytes'.
|
|
29
|
+
If 'charset' is provided in the kwargs and the response type is not bytes, an exception is raised.
|
|
30
|
+
|
|
31
|
+
Parameters:
|
|
32
|
+
kwargs (dict): Dictionary of keyword arguments that may include 'charset'.
|
|
33
|
+
response_type (type): The expected type of the response (e.g., bytes, str).
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
Exception: If 'charset' is specified in kwargs but the response_type is not bytes.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
if "charset" in kwargs and response_type != bytes:
|
|
40
|
+
raise Exception(ErrorMessage.INVALID_CHARSET_TYPE.value)
|
|
41
|
+
else:
|
|
42
|
+
if "charset" in kwargs and response_type == bytes:
|
|
43
|
+
try:
|
|
44
|
+
if kwargs["charset"].value not in [
|
|
45
|
+
Charset.UTF8.value,
|
|
46
|
+
Charset.UTF16LE.value,
|
|
47
|
+
Charset.UTF16BE.value,
|
|
48
|
+
]:
|
|
49
|
+
raise Exception(ErrorMessage.UNSUPPORTED_CHARSET.value)
|
|
50
|
+
except Exception:
|
|
51
|
+
raise Exception(ErrorMessage.UNSUPPORTED_CHARSET.value)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class InputPreprocessor:
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def validate_parameters(
|
|
58
|
+
kwargs, inp_type, operation_type: str, user: str, de: str, newde: str = None
|
|
59
|
+
) -> dict:
|
|
60
|
+
"""
|
|
61
|
+
Validates and constructs the parameter dictionary for different data protection operations.
|
|
62
|
+
|
|
63
|
+
This method ensures that the required parameters for PROTECT, UNPROTECT, and REPROTECT operations
|
|
64
|
+
are present and correctly typed. It also encodes optional parameters like external IVs and tweaks
|
|
65
|
+
into base64 strings when necessary.
|
|
66
|
+
|
|
67
|
+
Parameters:
|
|
68
|
+
kwargs (dict): Additional keyword arguments specific to the operation.
|
|
69
|
+
inp_type (type): The expected response type (e.g., str, bytes).
|
|
70
|
+
operation_type (str): The type of operation to perform ('PROTECT', 'UNPROTECT', or 'REPROTECT').
|
|
71
|
+
user (str): The user identifier.
|
|
72
|
+
de (str): The data element name.
|
|
73
|
+
newde (str, optional): The new data element name (required for REPROTECT).
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
dict: A dictionary containing validated and formatted parameters for the operation.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
Exception: If any required parameter is missing or of an invalid type, or if unsupported
|
|
80
|
+
keyword arguments are provided.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
argv = {
|
|
84
|
+
"parameters": {
|
|
85
|
+
"user": user,
|
|
86
|
+
"data_element": de,
|
|
87
|
+
"new_data_element": newde,
|
|
88
|
+
"response_type": inp_type,
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if not isinstance(user, str):
|
|
93
|
+
raise Exception(ErrorMessage.INVALID_USER_NAME.value)
|
|
94
|
+
|
|
95
|
+
operation = op_type[operation_type]
|
|
96
|
+
|
|
97
|
+
if operation in ["PROTECT", "UNPROTECT"]:
|
|
98
|
+
|
|
99
|
+
if de is None or de == "":
|
|
100
|
+
raise Exception(ErrorMessage.DATA_ELEMENT_NONE_EMPTY.value)
|
|
101
|
+
if not isinstance(de, str):
|
|
102
|
+
raise Exception(ErrorMessage.DATA_ELEMENT_NOT_STR.value)
|
|
103
|
+
|
|
104
|
+
if "external_iv" in kwargs:
|
|
105
|
+
if not isinstance(kwargs["external_iv"], bytes):
|
|
106
|
+
raise Exception(
|
|
107
|
+
ErrorMessage.INVALID_KEYWORD_EXTERNAL_IV.value
|
|
108
|
+
+ f" Expected: bytes, Actual: {type(kwargs['external_iv'])}"
|
|
109
|
+
)
|
|
110
|
+
argv["parameters"]["external_iv"] = convert_b64_bytes_b64_string(
|
|
111
|
+
kwargs["external_iv"]
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if "external_tweak" in kwargs:
|
|
115
|
+
if not isinstance(kwargs["external_tweak"], bytes):
|
|
116
|
+
raise Exception(
|
|
117
|
+
ErrorMessage.INVALID_KEYWORD_EXTERNAL_TWEAK.value
|
|
118
|
+
+ f" Expected: bytes, Actual: {type(kwargs['external_tweak'])}"
|
|
119
|
+
)
|
|
120
|
+
argv["parameters"]["external_tweak"] = convert_b64_bytes_b64_string(
|
|
121
|
+
kwargs["external_tweak"]
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if operation == "PROTECT":
|
|
125
|
+
if "encrypt_to" in kwargs:
|
|
126
|
+
if kwargs["encrypt_to"] != bytes:
|
|
127
|
+
raise Exception(
|
|
128
|
+
ErrorMessage.INVALID_ENC_TYPE.value
|
|
129
|
+
+ f" - {kwargs['encrypt_to']}"
|
|
130
|
+
)
|
|
131
|
+
argv["parameters"]["response_type"] = bytes
|
|
132
|
+
|
|
133
|
+
validate_charset(kwargs, argv["parameters"]["response_type"])
|
|
134
|
+
|
|
135
|
+
for key in kwargs:
|
|
136
|
+
if key not in args_protect:
|
|
137
|
+
raise Exception(
|
|
138
|
+
f"-1, Invalid Keyword Argument: '{key}'. {ErrorMessage.PROTECT_KEYWORD_EXP.value}"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
elif operation == "UNPROTECT":
|
|
142
|
+
if "decrypt_to" in kwargs:
|
|
143
|
+
if kwargs["decrypt_to"] not in datatypes:
|
|
144
|
+
raise Exception(
|
|
145
|
+
ErrorMessage.INVALID_DEC_TYPE.value
|
|
146
|
+
+ f" - {kwargs['decrypt_to']}"
|
|
147
|
+
)
|
|
148
|
+
argv["parameters"]["response_type"] = kwargs["decrypt_to"]
|
|
149
|
+
|
|
150
|
+
validate_charset(kwargs, argv["parameters"]["response_type"])
|
|
151
|
+
|
|
152
|
+
for key in kwargs:
|
|
153
|
+
if key not in args_unprotect:
|
|
154
|
+
raise Exception(
|
|
155
|
+
f"-1, Invalid Keyword Argument: '{key}'. {ErrorMessage.UNPROTECT_KEYWORD_EXP.value}"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
elif operation == "REPROTECT":
|
|
159
|
+
if de is None or de == "":
|
|
160
|
+
raise Exception(ErrorMessage.DATA_ELEMENT_NONE_EMPTY.value)
|
|
161
|
+
if not isinstance(de, str):
|
|
162
|
+
raise Exception(ErrorMessage.DATA_ELEMENT_NOT_STR.value)
|
|
163
|
+
|
|
164
|
+
if newde is None or newde == "":
|
|
165
|
+
raise Exception(ErrorMessage.NEW_DATA_ELEMENT_NONE_EMPTY.value)
|
|
166
|
+
if not isinstance(newde, str):
|
|
167
|
+
raise Exception(ErrorMessage.NEW_DATA_ELEMENT_NOT_STR.value)
|
|
168
|
+
|
|
169
|
+
if "old_external_iv" in kwargs and "new_external_iv" in kwargs:
|
|
170
|
+
if not isinstance(kwargs["old_external_iv"], bytes):
|
|
171
|
+
raise Exception(
|
|
172
|
+
ErrorMessage.INVALID_KEYWORD_OLD_EXTERNAL_IV.value
|
|
173
|
+
+ f" Expected: bytes, Actual: {type(kwargs['old_external_iv'])}"
|
|
174
|
+
)
|
|
175
|
+
argv["parameters"]["old_external_iv_str"] = (
|
|
176
|
+
convert_b64_bytes_b64_string(kwargs["old_external_iv"])
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
if not isinstance(kwargs["new_external_iv"], bytes):
|
|
180
|
+
raise Exception(
|
|
181
|
+
ErrorMessage.INVALID_KEYWORD_NEW_EXTERNAL_IV.value
|
|
182
|
+
+ f" Expected: bytes, Actual: {type(kwargs['new_external_iv'])}"
|
|
183
|
+
)
|
|
184
|
+
argv["parameters"]["new_external_iv"] = convert_b64_bytes_b64_string(
|
|
185
|
+
kwargs["new_external_iv"]
|
|
186
|
+
)
|
|
187
|
+
elif "old_external_iv" in kwargs or "new_external_iv" in kwargs:
|
|
188
|
+
raise Exception(ErrorMessage.MISSING_OLD_EIV_OR_NEW_EIV.value)
|
|
189
|
+
|
|
190
|
+
if "old_external_tweak" in kwargs and "new_external_tweak" in kwargs:
|
|
191
|
+
if not isinstance(kwargs["old_external_tweak"], bytes):
|
|
192
|
+
raise Exception(
|
|
193
|
+
ErrorMessage.INVALID_KEYWORD_OLD_EXTERNAL_TWEAK.value
|
|
194
|
+
+ f" Expected: bytes, Actual: {type(kwargs['old_external_tweak'])}"
|
|
195
|
+
)
|
|
196
|
+
argv["parameters"]["old_external_tweak"] = convert_b64_bytes_b64_string(
|
|
197
|
+
kwargs["old_external_tweak"]
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
if not isinstance(kwargs["new_external_tweak"], bytes):
|
|
201
|
+
raise Exception(
|
|
202
|
+
ErrorMessage.INVALID_KEYWORD_NEW_EXTERNAL_TWEAK.value
|
|
203
|
+
+ f" Expected: bytes, Actual: {type(kwargs['new_external_tweak'])}"
|
|
204
|
+
)
|
|
205
|
+
argv["parameters"]["new_external_tweak"] = convert_b64_bytes_b64_string(
|
|
206
|
+
kwargs["new_external_tweak"]
|
|
207
|
+
)
|
|
208
|
+
elif "old_external_tweak" in kwargs or "new_external_tweak" in kwargs:
|
|
209
|
+
raise Exception(ErrorMessage.MISSING_OLD_TWEAK_OR_NEW_TWEAK.value)
|
|
210
|
+
|
|
211
|
+
if "encrypt_to" in kwargs:
|
|
212
|
+
if kwargs["encrypt_to"] != bytes:
|
|
213
|
+
raise Exception(
|
|
214
|
+
ErrorMessage.INVALID_ENC_TYPE.value
|
|
215
|
+
+ f" - {kwargs['encrypt_to']}"
|
|
216
|
+
)
|
|
217
|
+
argv["parameters"]["response_type"] = bytes
|
|
218
|
+
|
|
219
|
+
validate_charset(kwargs, argv["parameters"]["response_type"])
|
|
220
|
+
|
|
221
|
+
for key in kwargs:
|
|
222
|
+
if key not in args_reprotect:
|
|
223
|
+
raise Exception(
|
|
224
|
+
f"-1, Invalid Keyword Argument: '{key}'. {ErrorMessage.REPROTECT_KEYWORD_EXP.value}"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
return argv
|
|
228
|
+
|
|
229
|
+
@staticmethod
|
|
230
|
+
def convert_input_to_string(
|
|
231
|
+
input_data, kwargs, data_element, operation_type
|
|
232
|
+
) -> dict:
|
|
233
|
+
"""
|
|
234
|
+
Converts input data into a string or base64-encoded format suitable for protection operations.
|
|
235
|
+
|
|
236
|
+
This method handles both single and bulk inputs, validates data types, and applies encoding
|
|
237
|
+
or decoding based on the data element and operation type. It also respects character set
|
|
238
|
+
preferences provided in kwargs.
|
|
239
|
+
|
|
240
|
+
Parameters:
|
|
241
|
+
input_data (Any): The input data to be processed (can be a single value or a list).
|
|
242
|
+
kwargs (dict): Additional keyword arguments, including optional charset.
|
|
243
|
+
data_element (str): The data element type (used to determine encoding behavior).
|
|
244
|
+
operation_type (str): The operation being performed ('PROTECT', 'UNPROTECT', etc.).
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
dict: A dictionary containing the processed data, its type, original data type,
|
|
248
|
+
charset used, and whether the input was bulk.
|
|
249
|
+
|
|
250
|
+
Raises:
|
|
251
|
+
Exception: If the input data contains unsupported or inconsistent types.
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
curr_input_datatype = None
|
|
255
|
+
is_bulk = False
|
|
256
|
+
input_type = None
|
|
257
|
+
charset = Charset.UTF8
|
|
258
|
+
|
|
259
|
+
if not data_element or not isinstance(data_element, str):
|
|
260
|
+
raise Exception(
|
|
261
|
+
ErrorMessage.DATA_ELEMENT_NONE_EMPTY.value
|
|
262
|
+
if not data_element
|
|
263
|
+
else ErrorMessage.DATA_ELEMENT_NOT_STR.value
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
is_enc = "text" in data_element or "BYTE" in data_element
|
|
267
|
+
|
|
268
|
+
# Preserve charset from kwargs if valid
|
|
269
|
+
if "charset" in kwargs and isinstance(kwargs["charset"], Charset):
|
|
270
|
+
charset = kwargs["charset"]
|
|
271
|
+
|
|
272
|
+
if isinstance(input_data, tuple):
|
|
273
|
+
input_type = type(input_data)
|
|
274
|
+
input_data = list(input_data)
|
|
275
|
+
elif isinstance(input_data, list):
|
|
276
|
+
input_data = input_data.copy()
|
|
277
|
+
input_type = type(input_data)
|
|
278
|
+
|
|
279
|
+
if isinstance(input_data, list):
|
|
280
|
+
is_bulk = True
|
|
281
|
+
for index, data in enumerate(input_data):
|
|
282
|
+
if data is None:
|
|
283
|
+
continue
|
|
284
|
+
type_data = type(data)
|
|
285
|
+
if curr_input_datatype and type_data != curr_input_datatype:
|
|
286
|
+
raise Exception(ErrorMessage.INVALID_BULK_INPUT.value)
|
|
287
|
+
if type_data in datatypes:
|
|
288
|
+
curr_input_datatype = curr_input_datatype or type_data
|
|
289
|
+
if datatypes[type_data] != 5:
|
|
290
|
+
input_data[index] = (
|
|
291
|
+
encode_to_base64_string(data)
|
|
292
|
+
if is_enc and op_type[operation_type] == "PROTECT"
|
|
293
|
+
else str(data)
|
|
294
|
+
)
|
|
295
|
+
else:
|
|
296
|
+
input_data[index] = decode_bytes(
|
|
297
|
+
data, charset, is_enc, operation_type
|
|
298
|
+
)
|
|
299
|
+
else:
|
|
300
|
+
raise Exception(f"-1, Unsupported input data type {type_data} !")
|
|
301
|
+
else:
|
|
302
|
+
type_data = type(input_data)
|
|
303
|
+
input_type = type_data
|
|
304
|
+
if input_data is not None and type_data in datatypes:
|
|
305
|
+
curr_input_datatype = type_data
|
|
306
|
+
if datatypes[type_data] != 5:
|
|
307
|
+
input_data = (
|
|
308
|
+
encode_to_base64_string(input_data)
|
|
309
|
+
if is_enc and op_type[operation_type] == "PROTECT"
|
|
310
|
+
else str(input_data)
|
|
311
|
+
)
|
|
312
|
+
else:
|
|
313
|
+
input_data = decode_bytes(
|
|
314
|
+
input_data, charset, is_enc, operation_type
|
|
315
|
+
)
|
|
316
|
+
elif input_data is not None:
|
|
317
|
+
raise Exception(f"-1, Unsupported input data type {type_data} !")
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
"data": input_data,
|
|
321
|
+
"type": input_type,
|
|
322
|
+
"input_datatype": curr_input_datatype,
|
|
323
|
+
"charset": charset,
|
|
324
|
+
"is_bulk": is_bulk,
|
|
325
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides the OutputProcessor class, which is responsible for restoring the original data types
|
|
3
|
+
of protected or transformed values based on specified metadata. It supports various data types including
|
|
4
|
+
strings, integers, floats, bytes with specific charsets, and dates in multiple formats.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import base64
|
|
8
|
+
from datetime import date, datetime
|
|
9
|
+
from appython.utils.constants import (
|
|
10
|
+
Charset,
|
|
11
|
+
LOG_RETURN_CODE_UNSUPPORTED as log_return_code
|
|
12
|
+
)
|
|
13
|
+
from appython.utils.codec_helper import get_str_from_b64
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OutputProcessor:
|
|
17
|
+
@staticmethod
|
|
18
|
+
def restore_original_type(data: list, return_type: dict):
|
|
19
|
+
"""
|
|
20
|
+
Restores the original data type(s) of protected or transformed values based on the specified return metadata.
|
|
21
|
+
|
|
22
|
+
This method decodes or converts each item in the input list `data` to its intended type as described in
|
|
23
|
+
the `return_type` dictionary. It supports both single and bulk inputs, and handles decoding for base64-encoded
|
|
24
|
+
strings, numeric types, byte strings with specific charsets, and date formats.
|
|
25
|
+
|
|
26
|
+
Parameters:
|
|
27
|
+
data (list): A list of values (usually strings) to be converted back to their original types.
|
|
28
|
+
return_type (dict): Metadata describing the expected output format. Keys include:
|
|
29
|
+
- "is_bulk" (bool): Whether the input is a list of values or a single value.
|
|
30
|
+
- "response_type" (type): The target Python type (e.g., str, int, float, bytes, date).
|
|
31
|
+
- "isENC" (bool): Whether the input values are base64-encoded.
|
|
32
|
+
- "charset" (Charset, optional): Character encoding to use when decoding byte strings.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
The decoded value(s), either as a single item or a list, depending on the `is_bulk` flag.
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
Exception: If decoding fails or the response type is unsupported.
|
|
39
|
+
"""
|
|
40
|
+
try:
|
|
41
|
+
is_bulk = return_type["is_bulk"]
|
|
42
|
+
response_type = return_type["response_type"]
|
|
43
|
+
is_enc = return_type["isENC"]
|
|
44
|
+
charset = return_type.get("charset")
|
|
45
|
+
|
|
46
|
+
def decode(item):
|
|
47
|
+
if item is None:
|
|
48
|
+
return None
|
|
49
|
+
if response_type == str:
|
|
50
|
+
return get_str_from_b64(item) if is_enc else item
|
|
51
|
+
elif response_type == int:
|
|
52
|
+
return int(get_str_from_b64(item)) if is_enc else int(item)
|
|
53
|
+
elif response_type == float:
|
|
54
|
+
return float(get_str_from_b64(item)) if is_enc else float(item)
|
|
55
|
+
elif response_type == bytes:
|
|
56
|
+
if is_enc:
|
|
57
|
+
return base64.b64decode(item)
|
|
58
|
+
if charset.value == Charset.UTF8.value:
|
|
59
|
+
return item.encode("utf-8")
|
|
60
|
+
elif charset.value == Charset.UTF16LE.value:
|
|
61
|
+
return item.encode("utf-16le")
|
|
62
|
+
elif charset.value == Charset.UTF16BE.value:
|
|
63
|
+
return item.encode("utf-16be")
|
|
64
|
+
elif response_type == date:
|
|
65
|
+
date_formats = [
|
|
66
|
+
"%Y-%m-%d", # 2023-12-25
|
|
67
|
+
"%Y/%m/%d", # 2023/12/25
|
|
68
|
+
"%Y/%d/%m", # 2023/25/12
|
|
69
|
+
"%m/%d/%Y", # 12/25/2023
|
|
70
|
+
"%d/%m/%Y", # 25/12/2023
|
|
71
|
+
"%m-%d-%Y", # 12-25-2023
|
|
72
|
+
"%d-%m-%Y", # 25-12-2023
|
|
73
|
+
"%Y%m%d", # 20231225
|
|
74
|
+
"%d.%m.%Y", # 25.12.2023
|
|
75
|
+
"%Y.%m.%d", # 2023.12.25
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
for fmt in date_formats:
|
|
79
|
+
try:
|
|
80
|
+
return datetime.strptime(item, fmt).date()
|
|
81
|
+
except ValueError:
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
# If no format worked, raise an error with the original item
|
|
85
|
+
raise ValueError(
|
|
86
|
+
f"Unable to parse date format for: '{item}'. Supported formats: {date_formats}"
|
|
87
|
+
)
|
|
88
|
+
elif response_type == type(None):
|
|
89
|
+
return None
|
|
90
|
+
else:
|
|
91
|
+
raise Exception(f"26, {log_return_code[26]}")
|
|
92
|
+
|
|
93
|
+
if not is_bulk:
|
|
94
|
+
return decode(data[0])
|
|
95
|
+
else:
|
|
96
|
+
return [decode(item) for item in data]
|
|
97
|
+
|
|
98
|
+
except Exception:
|
|
99
|
+
raise Exception(f"26, {log_return_code[26]}")
|