dataflow-core 2.1.6__py3-none-any.whl → 2.1.8__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 dataflow-core might be problematic. Click here for more details.
- authenticator/dataflowhubauthenticator.py +19 -17
- dataflow/dataflow.py +158 -34
- dataflow/models/__init__.py +2 -1
- dataflow/models/dataflow_zone.py +19 -0
- dataflow/models/role.py +12 -2
- dataflow/models/role_zone.py +17 -0
- dataflow/models/user.py +2 -2
- dataflow/schemas/__init__.py +0 -0
- dataflow/schemas/connection.py +84 -0
- dataflow/schemas/git_ssh.py +50 -0
- dataflow/schemas/secret.py +44 -0
- dataflow/secrets_manager/__init__.py +13 -0
- dataflow/secrets_manager/factory.py +59 -0
- dataflow/secrets_manager/interface.py +22 -0
- dataflow/secrets_manager/providers/__init__.py +0 -0
- dataflow/secrets_manager/providers/aws_manager.py +164 -0
- dataflow/secrets_manager/providers/azure_manager.py +185 -0
- dataflow/secrets_manager/service.py +156 -0
- dataflow/utils/exceptions.py +112 -0
- dataflow/utils/get_current_user.py +2 -0
- {dataflow_core-2.1.6.dist-info → dataflow_core-2.1.8.dist-info}/METADATA +3 -1
- {dataflow_core-2.1.6.dist-info → dataflow_core-2.1.8.dist-info}/RECORD +25 -14
- dataflow/models/runtime.py +0 -11
- dataflow/utils/aws_secrets_manager.py +0 -57
- dataflow/utils/json_handler.py +0 -33
- {dataflow_core-2.1.6.dist-info → dataflow_core-2.1.8.dist-info}/WHEEL +0 -0
- {dataflow_core-2.1.6.dist-info → dataflow_core-2.1.8.dist-info}/entry_points.txt +0 -0
- {dataflow_core-2.1.6.dist-info → dataflow_core-2.1.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Custom exceptions for the dataflow secrets manager."""
|
|
2
|
+
|
|
3
|
+
from dataflow.utils.logger import CustomLogger
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SecretsManagerException(Exception):
|
|
8
|
+
"""Base exception for all secrets manager errors."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, message: str, details: Optional[str] = None, operation: Optional[str] = None):
|
|
11
|
+
self.message = message
|
|
12
|
+
self.details = details
|
|
13
|
+
self.operation = operation
|
|
14
|
+
self.logger = CustomLogger().get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
# Log detailed error information
|
|
17
|
+
log_msg = f"SecretsManager Error"
|
|
18
|
+
if operation:
|
|
19
|
+
log_msg += f" in {operation}"
|
|
20
|
+
log_msg += f": {message}"
|
|
21
|
+
if details:
|
|
22
|
+
log_msg += f" | Details: {details}"
|
|
23
|
+
|
|
24
|
+
self.logger.error(log_msg)
|
|
25
|
+
super().__init__(message)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SecretNotFoundException(SecretsManagerException):
|
|
29
|
+
"""Raised when a requested secret is not found."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, secret_type: str, key: str, context: Optional[str] = None, original_error: Optional[str] = None):
|
|
32
|
+
message = f"{secret_type.capitalize()} not found"
|
|
33
|
+
|
|
34
|
+
details = f"Secret type: {secret_type}, Key: {key}"
|
|
35
|
+
if context:
|
|
36
|
+
details += f", Context: {context}"
|
|
37
|
+
if original_error:
|
|
38
|
+
details += f", Original error: {original_error}"
|
|
39
|
+
|
|
40
|
+
super().__init__(message, details, f"get_{secret_type}")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class SecretAlreadyExistsException(SecretsManagerException):
|
|
44
|
+
"""Raised when trying to create a secret that already exists."""
|
|
45
|
+
|
|
46
|
+
def __init__(self, secret_type: str, key: str, context: Optional[str] = None, original_error: Optional[str] = None, is_scheduled_for_deletion: bool = False):
|
|
47
|
+
if is_scheduled_for_deletion:
|
|
48
|
+
message = f"{secret_type.capitalize()} is in recovery mode. Please use another key name"
|
|
49
|
+
else:
|
|
50
|
+
message = f"{secret_type.capitalize()} already exists. Please use another key name"
|
|
51
|
+
|
|
52
|
+
details = f"Secret type: {secret_type}, Key: {key}"
|
|
53
|
+
if context:
|
|
54
|
+
details += f", Context: {context}"
|
|
55
|
+
if is_scheduled_for_deletion:
|
|
56
|
+
details += ", Status: Scheduled for deletion"
|
|
57
|
+
if original_error:
|
|
58
|
+
details += f", Original error: {original_error}"
|
|
59
|
+
|
|
60
|
+
super().__init__(message, details, f"create_{secret_type}")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class SecretValidationException(SecretsManagerException):
|
|
64
|
+
"""Raised when secret data validation fails."""
|
|
65
|
+
|
|
66
|
+
def __init__(self, secret_type: str, validation_error: str, original_error: Optional[str] = None):
|
|
67
|
+
message = f"Invalid {secret_type} data. Please check your input"
|
|
68
|
+
|
|
69
|
+
details = f"Secret type: {secret_type}, Validation error: {validation_error}"
|
|
70
|
+
if original_error:
|
|
71
|
+
details += f", Original error: {original_error}"
|
|
72
|
+
|
|
73
|
+
super().__init__(message, details, f"validate_{secret_type}")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class SecretManagerAuthException(SecretsManagerException):
|
|
77
|
+
"""Raised when authentication or authorization fails."""
|
|
78
|
+
|
|
79
|
+
def __init__(self, operation: str, original_error: Optional[str] = None):
|
|
80
|
+
message = "Access denied. Please check your permissions"
|
|
81
|
+
|
|
82
|
+
details = f"Operation: {operation}"
|
|
83
|
+
if original_error:
|
|
84
|
+
details += f", Original error: {original_error}"
|
|
85
|
+
|
|
86
|
+
super().__init__(message, details, operation)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class SecretManagerServiceException(SecretsManagerException):
|
|
90
|
+
"""Raised when the secret manager service is unavailable or fails."""
|
|
91
|
+
|
|
92
|
+
def __init__(self, operation: str, original_error: Optional[str] = None):
|
|
93
|
+
message = "We're experiencing some issues. Our best minds are working on it!"
|
|
94
|
+
|
|
95
|
+
details = f"Operation: {operation}"
|
|
96
|
+
if original_error:
|
|
97
|
+
details += f", Original error: {original_error}"
|
|
98
|
+
|
|
99
|
+
super().__init__(message, details, operation)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class SecretManagerConfigException(SecretsManagerException):
|
|
103
|
+
"""Raised when there's a configuration error."""
|
|
104
|
+
|
|
105
|
+
def __init__(self, config_issue: str, original_error: Optional[str] = None):
|
|
106
|
+
message = "Configuration issue detected. Please contact support"
|
|
107
|
+
|
|
108
|
+
details = f"Config issue: {config_issue}"
|
|
109
|
+
if original_error:
|
|
110
|
+
details += f", Original error: {original_error}"
|
|
111
|
+
|
|
112
|
+
super().__init__(message, details, "configuration")
|
|
@@ -26,9 +26,11 @@ def get_user_from_session(session_id: str, db: Session):
|
|
|
26
26
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found")
|
|
27
27
|
|
|
28
28
|
base_role = user.role_details.base_role
|
|
29
|
+
role_id = user.role_details.id
|
|
29
30
|
role_name = user.role_details.name
|
|
30
31
|
user.base_role = base_role
|
|
31
32
|
user.role = role_name
|
|
33
|
+
user.role_id = role_id
|
|
32
34
|
|
|
33
35
|
return user
|
|
34
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dataflow-core
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.8
|
|
4
4
|
Summary: Dataflow core package
|
|
5
5
|
Author: Dataflow
|
|
6
6
|
Author-email:
|
|
@@ -9,6 +9,8 @@ Requires-Dist: boto3
|
|
|
9
9
|
Requires-Dist: psycopg2-binary
|
|
10
10
|
Requires-Dist: pymysql
|
|
11
11
|
Requires-Dist: requests
|
|
12
|
+
Requires-Dist: azure-identity
|
|
13
|
+
Requires-Dist: azure-keyvault-secrets
|
|
12
14
|
Dynamic: author
|
|
13
15
|
Dynamic: requires-dist
|
|
14
16
|
Dynamic: summary
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
authenticator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
authenticator/dataflowairflowauthenticator.py,sha256=gEdCiL2yJQ7lYvAwbrjcAkccVMfehoMJldw9eU7cc2s,2243
|
|
3
|
-
authenticator/dataflowhubauthenticator.py,sha256
|
|
3
|
+
authenticator/dataflowhubauthenticator.py,sha256=WEIYk8T8kvXfyqPMnV83nzD4sSDwYEWLBnzcqZtTg1E,13473
|
|
4
4
|
authenticator/dataflowsupersetauthenticator.py,sha256=NkAmDaIc-ui-qEolu4xz_UY7P_2g8111hwNjPvAOW1Q,2839
|
|
5
5
|
dataflow/__init__.py,sha256=WTRg8HMpMWSgxYJ9ZGVldx4k07fAbta3mBmZ1hG9mWE,30
|
|
6
6
|
dataflow/configuration.py,sha256=7To6XwH1eESiYp39eqPcswXWwrdBUdPF6xN6WnazOF0,663
|
|
7
7
|
dataflow/database_manager.py,sha256=tJHMuOZ9Muskrh9t4uLRlTuFU0VkHAzoHlGP5DORIC4,899
|
|
8
|
-
dataflow/dataflow.py,sha256
|
|
8
|
+
dataflow/dataflow.py,sha256=Ixj4xSmpG94ByedfYJpzD4fCcmO5jXLxYpkJ4shoDeY,13331
|
|
9
9
|
dataflow/db.py,sha256=73ojGqpCTRVTlPszD73Ozhjih_BI2KTHmazqxxL6iWk,3780
|
|
10
10
|
dataflow/environment.py,sha256=05F-dBRyZu2mr26vuiuJU13pfgtRpA9yW69bk83HGUw,27239
|
|
11
|
-
dataflow/models/__init__.py,sha256=
|
|
11
|
+
dataflow/models/__init__.py,sha256=WnlLd-0T3HYtJloDms1a58lN66WzBIbBSTReDXD6HaQ,892
|
|
12
12
|
dataflow/models/app_types.py,sha256=yE_ZB13lhpK7AZ7PyBwnQlf0RlIHYs_-vdMKx7_RMlY,379
|
|
13
13
|
dataflow/models/blacklist_library.py,sha256=B2oi3Z8GcR_glhLAyinFk0W8c9txXvm3uOER6dY-q7I,991
|
|
14
14
|
dataflow/models/connection.py,sha256=_VJL3KuIrm8t4lJmtunIL3-AXF9Yvi5wUolzdR3tE0E,1017
|
|
15
|
+
dataflow/models/dataflow_zone.py,sha256=yFCvQXos5M1cU7ksbVSO338_RkT3hkdw2wr3kCJ_rec,769
|
|
15
16
|
dataflow/models/environment.py,sha256=300CUwx7d7bjadrMsTch7NSRYLCuf9AK9WVzlT26CAc,2616
|
|
16
17
|
dataflow/models/environment_status.py,sha256=lvPDNUsUoTW9D97B07aKqJQHRKp4LvPM28pQDMPH1ac,536
|
|
17
18
|
dataflow/models/git_ssh.py,sha256=W15SDypxzGOz_aZkHEnVZ6DIMVsjAsbSIXVIEt2mPYU,694
|
|
@@ -19,26 +20,36 @@ dataflow/models/pinned_projects.py,sha256=I-XMQq7__XJJi2lyOdEvQEfhPRz8D6KHA6Cbav
|
|
|
19
20
|
dataflow/models/project_details.py,sha256=iNb95L3UGjcC_Ws6FiUTDANCUFhYWpnsKraS6rmCyRU,1098
|
|
20
21
|
dataflow/models/recent_project_studio.py,sha256=m12KGCsv453C1ijHjfVD8E7cJ7Og_0N8uc7_9VlfkYw,812
|
|
21
22
|
dataflow/models/recent_projects.py,sha256=OFd5MSRXVRHs9UbvUNoJBBnh9rgsJ0lwE23wm5_Hc5w,321
|
|
22
|
-
dataflow/models/role.py,sha256=
|
|
23
|
+
dataflow/models/role.py,sha256=0fgLjCx7aETRwCV5SW0-4PQBWzWddWO9a_ObJA14VOY,962
|
|
23
24
|
dataflow/models/role_server.py,sha256=mMcfjsGX1cY8hOAOBBmrZgw8ozdfuvjKJoBlR6F0Kdc,689
|
|
24
|
-
dataflow/models/
|
|
25
|
+
dataflow/models/role_zone.py,sha256=uH8JheWyzUWcRECRzYuzdphUAUXeU5zRVA1Bhuz3h9w,772
|
|
25
26
|
dataflow/models/server_config.py,sha256=8ocKT8tPen9tedO8BLPEfkWxUEIHaqvA2L-qEhrFND0,1385
|
|
26
27
|
dataflow/models/session.py,sha256=c8TI6qXsM8utzp5vSQtAOXJSbgasnyu-a0qSAvA-rWs,459
|
|
27
28
|
dataflow/models/team.py,sha256=fjkqF0N4PSwSYTgHjEQl9wuC7yumd0iOb5nNFePI6q4,488
|
|
28
|
-
dataflow/models/user.py,sha256=
|
|
29
|
+
dataflow/models/user.py,sha256=qFvkU6hZQzv-QWCC8nDKonnpl2Z2YEqMni5iUVQpMB0,1041
|
|
29
30
|
dataflow/models/user_environment.py,sha256=yI9NutULcLiwlycuEin6ROe6o1Sjdv_sgw2MEkJFeYg,568
|
|
30
31
|
dataflow/models/user_team.py,sha256=r_fmKvf6JuGgiiI9TXWjVG2QZ3WOvDrOwYWVQ3r8oWo,659
|
|
31
32
|
dataflow/models/variables.py,sha256=Sinvv3zFYni5i_GrL69cVfhCh4tOOaIHiEzWYRJ-i10,1132
|
|
33
|
+
dataflow/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
+
dataflow/schemas/connection.py,sha256=1bKTSEPW1QwcFQe35QCIr-S5DTMr34WJCjSKhxMpPek,2449
|
|
35
|
+
dataflow/schemas/git_ssh.py,sha256=mJdEbUe2uQNXGpj2XnLZhTgqiISwH0Xw2O0utW1Bp9Y,1333
|
|
36
|
+
dataflow/schemas/secret.py,sha256=dAN_2IBTjnjf4sT6cyPVd_Zcdaw8s_EMG4aodMoCwXU,1165
|
|
32
37
|
dataflow/scripts/clone_environment.sh,sha256=xWJBw9z1W1rztrzLXYro3UtEdFuBSqNrB83y45zqFfE,487
|
|
33
38
|
dataflow/scripts/create_environment.sh,sha256=3FHgNplJuEZvyTsLqlCJNX9oyfXgsfqn80VZk2xtvso,828
|
|
34
39
|
dataflow/scripts/update_environment.sh,sha256=2dtn2xlNi6frpig-sqlGE1_IKRbbkqYOCpf_qyMKKII,992
|
|
40
|
+
dataflow/secrets_manager/__init__.py,sha256=idGqIDtYl0De2WIK9Obl-N7SDPSYtVM0D-wXfZjCiy4,559
|
|
41
|
+
dataflow/secrets_manager/factory.py,sha256=k1sIyXBKtas1upWJpq8Mks2d8kjLAHU7CFvjeuMXXxs,2160
|
|
42
|
+
dataflow/secrets_manager/interface.py,sha256=HhrKpQrprWIbDsVfU_qc59OXmSIuHXv106OXv6-Epqc,506
|
|
43
|
+
dataflow/secrets_manager/service.py,sha256=SSWgTXJTAwVPqMIc76cB2hR6nghNVOoMpIN9M0i7Su0,7241
|
|
44
|
+
dataflow/secrets_manager/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
+
dataflow/secrets_manager/providers/aws_manager.py,sha256=16peXyKeuAjv2RVTMUjrzArPYENK9Zu7jREWVgMfScA,8671
|
|
46
|
+
dataflow/secrets_manager/providers/azure_manager.py,sha256=sWOz-7ALnLt6vyM3lt14GBpzpmDnlH3hkdqtuApqkgU,9430
|
|
35
47
|
dataflow/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
dataflow/utils/
|
|
37
|
-
dataflow/utils/get_current_user.py,sha256=
|
|
38
|
-
dataflow/utils/json_handler.py,sha256=5_7WdypegRBDe2HSqBXyrJAdd92wsha8qRcmQvCj1TA,782
|
|
48
|
+
dataflow/utils/exceptions.py,sha256=8GRFoYZ5dPGQckVm2znaHpPi0ZAs69fK-RGKukEsapk,4432
|
|
49
|
+
dataflow/utils/get_current_user.py,sha256=4nSO3SPVMZhW-MsIgxR3f9ZzrFaIZIuyrM6hvfyE7PQ,1202
|
|
39
50
|
dataflow/utils/logger.py,sha256=7BFrOq5Oiqn8P4XZbgJzMP5O07d2fpdECbbfsjrUuHw,1213
|
|
40
|
-
dataflow_core-2.1.
|
|
41
|
-
dataflow_core-2.1.
|
|
42
|
-
dataflow_core-2.1.
|
|
43
|
-
dataflow_core-2.1.
|
|
44
|
-
dataflow_core-2.1.
|
|
51
|
+
dataflow_core-2.1.8.dist-info/METADATA,sha256=f7JqNJGVu3L1qea_GAEIsRDh3N4y-8lKrhcMhuvlZUs,369
|
|
52
|
+
dataflow_core-2.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
53
|
+
dataflow_core-2.1.8.dist-info/entry_points.txt,sha256=ppj_EIbYrJJwCPg1kfdsZk5q1N-Ejfis1neYrnjhO8o,117
|
|
54
|
+
dataflow_core-2.1.8.dist-info/top_level.txt,sha256=SZsUOpSCK9ntUy-3Tusxzf5A2e8ebwD8vouPb1dPt_8,23
|
|
55
|
+
dataflow_core-2.1.8.dist-info/RECORD,,
|
dataflow/models/runtime.py
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from sqlalchemy import Column, Integer, String, Boolean
|
|
2
|
-
from dataflow.db import Base
|
|
3
|
-
|
|
4
|
-
class RuntimeZone(Base):
|
|
5
|
-
__tablename__ = "RUNTIME_ZONE"
|
|
6
|
-
|
|
7
|
-
id = Column(Integer, primary_key=True, autoincrement=True, unique=True)
|
|
8
|
-
name = Column(String, unique=True, nullable=False)
|
|
9
|
-
display_name = Column(String, nullable=False)
|
|
10
|
-
display_order = Column(Integer)
|
|
11
|
-
spark_enabled = Column(Boolean, default=False)
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import boto3
|
|
2
|
-
from botocore.exceptions import ClientError, EndpointConnectionError, NoCredentialsError
|
|
3
|
-
import json
|
|
4
|
-
from .json_handler import JsonHandler
|
|
5
|
-
|
|
6
|
-
class SecretsManagerClient:
|
|
7
|
-
"""
|
|
8
|
-
A class to interact with AWS Secrets Manager for managing secrets.
|
|
9
|
-
|
|
10
|
-
Attributes:
|
|
11
|
-
client: The Boto3 client for Secrets Manager.
|
|
12
|
-
json_handler: An instance of JsonHandler for handling JSON operations.
|
|
13
|
-
"""
|
|
14
|
-
def __init__(self):
|
|
15
|
-
self.json_handler = JsonHandler()
|
|
16
|
-
try:
|
|
17
|
-
self.client = boto3.client('secretsmanager')
|
|
18
|
-
except EndpointConnectionError as e:
|
|
19
|
-
self.logger.error(f"Failed to initialize SecretsManagerClient: {e}")
|
|
20
|
-
raise Exception(f"Failed to initialize SecretsManagerClient: Unable to connect to the endpoint. {e}")
|
|
21
|
-
except NoCredentialsError as e:
|
|
22
|
-
self.logger.error(f"Failed to initialize SecretsManagerClient: {e}")
|
|
23
|
-
raise Exception(f"Failed to initialize SecretsManagerClient: No AWS credentials found. {e}")
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def get_secret_by_key(self, vault_path, user_name, conn_id: str, runtime, slug):
|
|
27
|
-
"""
|
|
28
|
-
Get information about a specific secret using a dynamically constructed vault path.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
vault_path (str): The base vault path.
|
|
32
|
-
user_name (str): The user name.
|
|
33
|
-
conn_id (str): The key of the secret to retrieve.
|
|
34
|
-
runtime (str, optional): The runtime environment. Defaults to None.
|
|
35
|
-
slug (str, optional): The slug identifier. Defaults to None.
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
str: Information about the secret in JSON format.
|
|
39
|
-
|
|
40
|
-
Raises:
|
|
41
|
-
Exception: If the operation fails.
|
|
42
|
-
"""
|
|
43
|
-
try:
|
|
44
|
-
if runtime and slug:
|
|
45
|
-
secret_name = f"{runtime}/{slug}/{vault_path}/{conn_id}"
|
|
46
|
-
else:
|
|
47
|
-
secret_name = f"{user_name}/{vault_path}/{conn_id}"
|
|
48
|
-
|
|
49
|
-
response = self.client.get_secret_value(SecretId=secret_name)
|
|
50
|
-
secret_data = json.loads(response.get('SecretString'))
|
|
51
|
-
|
|
52
|
-
return secret_data
|
|
53
|
-
except ClientError as e:
|
|
54
|
-
if e.response['Error']['Code'] == 'ResourceNotFoundException':
|
|
55
|
-
raise Exception(f"Secret named '{conn_id}' not found with path '{secret_name}'")
|
|
56
|
-
else:
|
|
57
|
-
raise Exception(f"Failed to get secret '{conn_id}': {e}")
|
dataflow/utils/json_handler.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
|
-
class JsonHandler:
|
|
4
|
-
"""
|
|
5
|
-
Helper class for handling JSON serialization and deserialization.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
def __init__(self):
|
|
9
|
-
pass
|
|
10
|
-
|
|
11
|
-
def dict_to_json(self, data_dict):
|
|
12
|
-
"""
|
|
13
|
-
Serialize a dictionary to JSON string.
|
|
14
|
-
|
|
15
|
-
Args:
|
|
16
|
-
data_dict (dict): The dictionary to serialize.
|
|
17
|
-
|
|
18
|
-
Returns:
|
|
19
|
-
str: The JSON string representation of the dictionary.
|
|
20
|
-
"""
|
|
21
|
-
return json.dumps(data_dict)
|
|
22
|
-
|
|
23
|
-
def json_to_dict(self, json_string):
|
|
24
|
-
"""
|
|
25
|
-
Deserialize a JSON string to dictionary.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
json_string (str): The JSON string to deserialize.
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
dict: The dictionary representation of the JSON string.
|
|
32
|
-
"""
|
|
33
|
-
return json.loads(json_string)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|