dc-python-sdk 1.5.30__tar.gz → 1.5.32__tar.gz

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.
Files changed (36) hide show
  1. {dc_python_sdk-1.5.30/src/dc_python_sdk.egg-info → dc_python_sdk-1.5.32}/PKG-INFO +1 -1
  2. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/pyproject.toml +1 -1
  3. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/setup.cfg +1 -1
  4. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32/src/dc_python_sdk.egg-info}/PKG-INFO +1 -1
  5. dc_python_sdk-1.5.32/src/dc_sdk/handler.py +210 -0
  6. dc_python_sdk-1.5.30/src/dc_sdk/handler.py +0 -72
  7. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/LICENSE +0 -0
  8. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/README.md +0 -0
  9. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_python_sdk.egg-info/SOURCES.txt +0 -0
  10. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_python_sdk.egg-info/dependency_links.txt +0 -0
  11. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_python_sdk.egg-info/entry_points.txt +0 -0
  12. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_python_sdk.egg-info/requires.txt +0 -0
  13. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_python_sdk.egg-info/top_level.txt +0 -0
  14. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/__init__.py +0 -0
  15. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/app.py +0 -0
  16. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/cli.py +0 -0
  17. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/errors.py +0 -0
  18. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/__init__.py +0 -0
  19. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/ai.py +0 -0
  20. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/ai_http.py +0 -0
  21. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/mapping.py +0 -0
  22. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/models/__init__.py +0 -0
  23. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/models/enums.py +0 -0
  24. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/models/errors.py +0 -0
  25. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/models/log_templates.py +0 -0
  26. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/models/pipeline_details.py +0 -0
  27. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/pipeline.py +0 -0
  28. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/server.py +0 -0
  29. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/__init__.py +0 -0
  30. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/api.py +0 -0
  31. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/aws.py +0 -0
  32. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/environment.py +0 -0
  33. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/loader.py +0 -0
  34. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/logger.py +0 -0
  35. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/src/services/session.py +0 -0
  36. {dc_python_sdk-1.5.30 → dc_python_sdk-1.5.32}/src/dc_sdk/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dc-python-sdk
3
- Version: 1.5.30
3
+ Version: 1.5.32
4
4
  Summary: Data Connector Python SDK
5
5
  Home-page: https://github.com/data-connector/dc-python-sdk
6
6
  Author: DataConnector
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dc-python-sdk"
7
- version = "1.5.30"
7
+ version = "1.5.32"
8
8
  description = "Data Connector Python SDK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.6"
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = dc-python-sdk
3
- version = 1.5.30
3
+ version = 1.5.32
4
4
  author = DataConnector
5
5
  author_email = josh@dataconnector.com
6
6
  description = A small example package
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dc-python-sdk
3
- Version: 1.5.30
3
+ Version: 1.5.32
4
4
  Summary: Data Connector Python SDK
5
5
  Home-page: https://github.com/data-connector/dc-python-sdk
6
6
  Author: DataConnector
@@ -0,0 +1,210 @@
1
+ from dc_sdk.errors import Error
2
+ from dc_sdk.src.mapping import Mapping
3
+ import traceback
4
+ from importlib.metadata import version
5
+
6
+ def get_action_name(action: int) -> str:
7
+ return {
8
+ 0: "authenticating",
9
+ 1: "retrieving fields",
10
+ 2: "retrieving 5 row preview",
11
+ 3: "testing connection",
12
+ 4: "starting the connector"
13
+ }[action]
14
+
15
+ def apply_data_filters(results, data_filters):
16
+ if not data_filters:
17
+ return results
18
+
19
+ # Connectors may return either:
20
+ # 1) a bare list of rows, or
21
+ # 2) an envelope: {"data": [...], "next_page": ...}
22
+ is_envelope = isinstance(results, dict) and isinstance(results.get("data"), list)
23
+ rows = results.get("data") if is_envelope else results
24
+ if not isinstance(rows, list):
25
+ return results
26
+
27
+ # 🔹 UI → backend operator mapping
28
+ OPERATOR_MAP = {
29
+ # text
30
+ "text_contains": "CONTAINS",
31
+ "text_not_contains": "NOT_CONTAINS",
32
+ "text_starts_with": "STARTS_WITH",
33
+ "text_ends_with": "ENDS_WITH",
34
+
35
+ # equality
36
+ "is_equal": "EQ",
37
+ "is_not_equal": "NEQ",
38
+
39
+ # empty
40
+ "is_empty": "IS_EMPTY",
41
+ "is_not_empty": "IS_NOT_EMPTY",
42
+
43
+ # numeric
44
+ "gt": "GT",
45
+ "gte": "GTE",
46
+ "lt": "LT",
47
+ "lte": "LTE",
48
+
49
+ # range
50
+ "between": "BETWEEN",
51
+ "not_between": "NOT_BETWEEN",
52
+
53
+ # ignore
54
+ "none": None,
55
+ }
56
+
57
+ def try_parse_number(val):
58
+ try:
59
+ return float(val)
60
+ except:
61
+ return val
62
+
63
+ def normalize(row_val, v1, v2=None):
64
+ row_num = try_parse_number(row_val)
65
+ v1_num = try_parse_number(v1)
66
+ v2_num = try_parse_number(v2) if v2 is not None else None
67
+
68
+ # If both are numbers → compare as numbers
69
+ if isinstance(row_num, float) and isinstance(v1_num, float):
70
+ return row_num, v1_num, v2_num
71
+
72
+ # Otherwise → compare as strings
73
+ return str(row_val), str(v1), str(v2) if v2 is not None else None
74
+
75
+ def match(row, f):
76
+ ui_operator = f.get("operator_cd")
77
+ operator = OPERATOR_MAP.get(ui_operator)
78
+
79
+ if operator is None:
80
+ return True # skip "none"
81
+
82
+ col = f.get("column_name")
83
+ val1 = f.get("value_1_txt")
84
+ val2 = f.get("value_2_txt")
85
+
86
+ # Some connectors can emit non-dict rows; keep filtering resilient.
87
+ if not isinstance(row, dict):
88
+ return False
89
+ row_val = row.get(col)
90
+
91
+ # ---- EMPTY HANDLING ----
92
+ if operator == "IS_EMPTY":
93
+ return row_val is None or str(row_val).strip() == ""
94
+
95
+ if operator == "IS_NOT_EMPTY":
96
+ return row_val is not None and str(row_val).strip() != ""
97
+
98
+ if row_val is None:
99
+ return False
100
+
101
+ # Normalize values
102
+ row_val, v1, v2 = normalize(row_val, val1, val2)
103
+
104
+ # ---- OPERATORS ----
105
+
106
+ if operator == "EQ":
107
+ return row_val == v1
108
+
109
+ elif operator == "NEQ":
110
+ return row_val != v1
111
+
112
+ elif operator == "GT":
113
+ return row_val > v1
114
+
115
+ elif operator == "GTE":
116
+ return row_val >= v1
117
+
118
+ elif operator == "LT":
119
+ return row_val < v1
120
+
121
+ elif operator == "LTE":
122
+ return row_val <= v1
123
+
124
+ elif operator == "BETWEEN":
125
+ return v1 <= row_val <= v2
126
+
127
+ elif operator == "NOT_BETWEEN":
128
+ return not (v1 <= row_val <= v2)
129
+
130
+ elif operator == "CONTAINS":
131
+ return str(v1).lower() in str(row_val).lower()
132
+
133
+ elif operator == "NOT_CONTAINS":
134
+ return str(v1).lower() not in str(row_val).lower()
135
+
136
+ elif operator == "STARTS_WITH":
137
+ return str(row_val).lower().startswith(str(v1).lower())
138
+
139
+ elif operator == "ENDS_WITH":
140
+ return str(row_val).lower().endswith(str(v1).lower())
141
+
142
+ return True
143
+
144
+ # 🔹 Apply filters (AND logic)
145
+ filtered_rows = [row for row in rows if all(match(row, f) for f in data_filters)]
146
+ if is_envelope:
147
+ return {**results, "data": filtered_rows}
148
+ return filtered_rows
149
+
150
+
151
+ def handler(event, context):
152
+ print("version: ", version("dc-python-sdk"))
153
+ """Lambda Handler"""
154
+ action_name = None
155
+ internal_error = False
156
+ message = None
157
+ results = None
158
+ error = None
159
+ mapping = None
160
+ action = int(event['action']) if 'action' in event else 4
161
+ get_objects = event.get('get_objects', True)
162
+ credentials_dict = event['credentials'] if 'credentials' in event else None
163
+ object_id = event['object_id'] if 'object_id' in event else None
164
+ field_ids = event['mapping'] if 'mapping' in event else None
165
+ options = event['options'] if 'options' in event else dict()
166
+ next_page = event['next_page'] if 'next_page' in event else None
167
+ n_rows = event['n_rows'] if 'n_rows' in event else None
168
+ filters = event['filters'] if 'filters' in event else None
169
+ data_filters = event['data_filters'] if 'data_filters' in event else None
170
+
171
+ try:
172
+ action_name = get_action_name(action)
173
+ mapping = Mapping(credentials_dict)
174
+
175
+ if action == 0:
176
+ if get_objects:
177
+ results, message = mapping.connect_get_objects()
178
+ else:
179
+ results, message = mapping.authenticate()
180
+ elif action == 1:
181
+ results, message = mapping.get_fields(object_id, options)
182
+ elif action == 2:
183
+ results, message = mapping.get_five_row_preview(
184
+ object_id, field_ids, options, n_rows, filters, next_page)
185
+ results = apply_data_filters(results, data_filters)
186
+ elif action == 3:
187
+ results, message = mapping.test_connection()
188
+ else:
189
+ raise Error("Invalid action", "InvalidActionError")
190
+ except Error as e:
191
+ message = e.message
192
+ internal_error = e.internal
193
+ error_trace = traceback.format_exc()
194
+ error = error_trace
195
+
196
+ except Exception as e:
197
+ error_trace = traceback.format_exc()
198
+ error = error_trace
199
+ internal_error = True
200
+
201
+ if error:
202
+ print(error)
203
+
204
+ return {
205
+ 'message': message if not internal_error else f"Something went wrong with {action_name}",
206
+ 'results': results,
207
+ 'credentials': mapping.connector.credentials if mapping else None,
208
+ 'error': error,
209
+ 'internal_error': internal_error
210
+ }
@@ -1,72 +0,0 @@
1
- from dc_sdk.errors import Error
2
- from dc_sdk.src.mapping import Mapping
3
- import traceback
4
- from importlib.metadata import version
5
-
6
- def get_action_name(action: int) -> str:
7
- return {
8
- 0: "authenticating",
9
- 1: "retrieving fields",
10
- 2: "retrieving 5 row preview",
11
- 3: "testing connection",
12
- 4: "starting the connector"
13
- }[action]
14
-
15
- def handler(event, context):
16
- print("version: ", version("dc-python-sdk"))
17
- """Lambda Handler"""
18
- action_name = None
19
- internal_error = False
20
- message = None
21
- results = None
22
- error = None
23
- mapping = None
24
- action = int(event['action']) if 'action' in event else 4
25
- get_objects = event.get('get_objects', True)
26
- credentials_dict = event['credentials'] if 'credentials' in event else None
27
- object_id = event['object_id'] if 'object_id' in event else None
28
- field_ids = event['mapping'] if 'mapping' in event else None
29
- options = event['options'] if 'options' in event else dict()
30
- next_page = event['next_page'] if 'next_page' in event else None
31
- n_rows = event['n_rows'] if 'n_rows' in event else None
32
- filters = event['filters'] if 'filters' in event else None
33
-
34
- try:
35
- action_name = get_action_name(action)
36
- mapping = Mapping(credentials_dict)
37
-
38
- if action == 0:
39
- if get_objects:
40
- results, message = mapping.connect_get_objects()
41
- else:
42
- results, message = mapping.authenticate()
43
- elif action == 1:
44
- results, message = mapping.get_fields(object_id, options)
45
- elif action == 2:
46
- results, message = mapping.get_five_row_preview(
47
- object_id, field_ids, options, n_rows, filters, next_page)
48
- elif action == 3:
49
- results, message = mapping.test_connection()
50
- else:
51
- raise Error("Invalid action", "InvalidActionError")
52
- except Error as e:
53
- message = e.message
54
- internal_error = e.internal
55
- error_trace = traceback.format_exc()
56
- error = error_trace
57
-
58
- except Exception as e:
59
- error_trace = traceback.format_exc()
60
- error = error_trace
61
- internal_error = True
62
-
63
- if error:
64
- print(error)
65
-
66
- return {
67
- 'message': message if not internal_error else f"Something went wrong with {action_name}",
68
- 'results': results,
69
- 'credentials': mapping.connector.credentials if mapping else None,
70
- 'error': error,
71
- 'internal_error': internal_error
72
- }
File without changes
File without changes