dc-python-sdk 1.5.45__tar.gz → 1.5.47__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 (35) hide show
  1. {dc_python_sdk-1.5.45/src/dc_python_sdk.egg-info → dc_python_sdk-1.5.47}/PKG-INFO +1 -1
  2. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/pyproject.toml +1 -1
  3. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/setup.cfg +1 -1
  4. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47/src/dc_python_sdk.egg-info}/PKG-INFO +1 -1
  5. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/models/pipeline_details.py +1 -0
  6. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/pipeline.py +39 -41
  7. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/api.py +12 -0
  8. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/LICENSE +0 -0
  9. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/README.md +0 -0
  10. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_python_sdk.egg-info/SOURCES.txt +0 -0
  11. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_python_sdk.egg-info/dependency_links.txt +0 -0
  12. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_python_sdk.egg-info/entry_points.txt +0 -0
  13. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_python_sdk.egg-info/requires.txt +0 -0
  14. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_python_sdk.egg-info/top_level.txt +0 -0
  15. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/__init__.py +0 -0
  16. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/app.py +0 -0
  17. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/cli.py +0 -0
  18. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/errors.py +0 -0
  19. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/handler.py +0 -0
  20. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/__init__.py +0 -0
  21. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/ai.py +0 -0
  22. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/ai_http.py +0 -0
  23. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/mapping.py +0 -0
  24. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/models/__init__.py +0 -0
  25. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/models/enums.py +0 -0
  26. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/models/errors.py +0 -0
  27. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/models/log_templates.py +0 -0
  28. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/server.py +0 -0
  29. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/__init__.py +0 -0
  30. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/aws.py +0 -0
  31. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/environment.py +0 -0
  32. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/loader.py +0 -0
  33. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/logger.py +0 -0
  34. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/src/dc_sdk/src/services/session.py +0 -0
  35. {dc_python_sdk-1.5.45 → dc_python_sdk-1.5.47}/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.45
3
+ Version: 1.5.47
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.45"
7
+ version = "1.5.47"
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.45
3
+ version = 1.5.47
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.45
3
+ Version: 1.5.47
4
4
  Summary: Data Connector Python SDK
5
5
  Home-page: https://github.com/data-connector/dc-python-sdk
6
6
  Author: DataConnector
@@ -37,6 +37,7 @@ class PipelineDetails:
37
37
  self.primary_key_column_nm = row_data.get('primary_key_column_nm')
38
38
  self.updated_date_column_nm = row_data.get('updated_date_column_nm')
39
39
  self.sync_cursor_dsc = row_data.get('sync_cursor_dsc')
40
+ self.pending_sync_cursor_dsc = row_data.get('pending_sync_cursor_dsc')
40
41
 
41
42
  def increment_stage(self):
42
43
  self.stage += 1
@@ -155,7 +155,7 @@ class PipelineConductor:
155
155
  self._update_extracted_sync_cursor(results.get("metadata"))
156
156
 
157
157
  if self._should_track_sync_cursor():
158
- self._upload_extracted_sync_cursor()
158
+ self._save_pending_sync_cursor()
159
159
 
160
160
  self.log(self.log_templates.GET_DATA_FINISH.format(self.row_count, self.pipeline_details.source_object_id))
161
161
 
@@ -256,60 +256,58 @@ class PipelineConductor:
256
256
  if self.extracted_sync_cursor is None or sync_cursor > self.extracted_sync_cursor:
257
257
  self.extracted_sync_cursor = sync_cursor
258
258
 
259
- def _get_sync_cursor_key_name(self):
260
- return f"transfers/e{self.pipeline_run_history_id}-sync_cursor.json"
259
+ def _save_pending_sync_cursor(self):
260
+ if not self._should_track_sync_cursor():
261
+ return
261
262
 
262
- def _upload_extracted_sync_cursor(self):
263
263
  if self.extracted_sync_cursor is None:
264
+ self.internal_log(
265
+ "Stay in Sync: no sync cursor value was extracted from source data."
266
+ )
264
267
  return
265
268
 
266
- payload = json.dumps({"sync_cursor": self.extracted_sync_cursor})
267
- json_buffer = io.StringIO(payload)
268
- key_name = self._get_sync_cursor_key_name()
269
-
270
- if PipelineEnvironment.platform == "aws":
271
- self.aws.upload_object(key_name, json_buffer=json_buffer)
272
- elif PipelineEnvironment.platform == "azure":
273
- key_name = f"{PipelineEnvironment.app_env}/{key_name}"
274
- self.azure.upload_object(key_name, json_buffer=json_buffer)
275
-
276
- self.internal_log(f"Uploaded sync cursor sidecar to {key_name}")
277
-
278
- def _load_extracted_sync_cursor(self):
279
- key_name = self._get_sync_cursor_key_name()
269
+ if self.mode != "prod":
270
+ self.internal_log(
271
+ f"Stay in Sync: extracted sync cursor {self.extracted_sync_cursor} (dev mode; not saved)."
272
+ )
273
+ return
280
274
 
281
275
  try:
282
- if PipelineEnvironment.platform == "aws":
283
- file_object = self.aws.download_object(key_name)
284
- elif PipelineEnvironment.platform == "azure":
285
- file_object = self.azure.download_object(
286
- f"{PipelineEnvironment.app_env}/{key_name}"
287
- )
288
- else:
289
- return None
290
-
291
- payload = json.load(file_object)
292
- return payload.get("sync_cursor")
276
+ self.api.save_pending_sync_cursor(
277
+ self.pipeline_id, self.extracted_sync_cursor
278
+ )
279
+ self.log(
280
+ f"Stay in Sync: saved pending sync cursor {self.extracted_sync_cursor}."
281
+ )
293
282
  except Exception as e:
294
- self.internal_log(f"No sync cursor sidecar found: {e}")
295
- return None
283
+ self.log(
284
+ f"Stay in Sync: failed to save pending sync cursor {self.extracted_sync_cursor}. {e}"
285
+ )
296
286
 
297
287
  def _persist_sync_cursor_after_load(self):
298
288
  if self.task != "DESTINATION":
299
289
  return
300
290
 
301
- sync_cursor = self._load_extracted_sync_cursor()
302
- if sync_cursor is None:
291
+ if self.mode != "prod":
303
292
  return
304
293
 
305
- if self.mode == "prod":
306
- self.api.save_sync_cursor(self.pipeline_id, sync_cursor)
307
-
308
- if PipelineEnvironment.platform == "aws":
309
- self.aws.delete_object(self._get_sync_cursor_key_name())
310
- elif PipelineEnvironment.platform == "azure":
311
- self.azure.delete_object(
312
- f"{PipelineEnvironment.app_env}/{self._get_sync_cursor_key_name()}"
294
+ try:
295
+ result = self.api.commit_sync_cursor(self.pipeline_id)
296
+ if result.get("committed"):
297
+ sync_cursor_dsc = result.get("sync_cursor_dsc", "")
298
+ self.log(
299
+ f"Stay in Sync: committed sync cursor {sync_cursor_dsc}."
300
+ )
301
+ else:
302
+ self.log(
303
+ "Stay in Sync: destination load finished but no pending sync cursor was committed."
304
+ )
305
+ except Exception as e:
306
+ self.log(
307
+ f"Stay in Sync: failed to commit sync cursor during destination load. {e}"
308
+ )
309
+ self.internal_log(
310
+ "Stay in Sync: commit will be retried when the pipeline run history is finalized."
313
311
  )
314
312
 
315
313
  def _call_connector_load_data(
@@ -113,6 +113,18 @@ class DataConnectorAPI:
113
113
 
114
114
  self.post(f"{pipeline_id}/mapping", body)
115
115
 
116
+ def save_pending_sync_cursor(self, pipeline_id, pending_sync_cursor):
117
+ self.put(
118
+ f"{pipeline_id}/pending-sync-cursor",
119
+ {"pending_sync_cursor_dsc": pending_sync_cursor},
120
+ )
121
+
122
+ def commit_sync_cursor(self, pipeline_id):
123
+ self.put(
124
+ f"{pipeline_id}/sync-cursor",
125
+ {"commit": True},
126
+ )
127
+
116
128
  def save_sync_cursor(self, pipeline_id, sync_cursor):
117
129
  self.put(
118
130
  f"{pipeline_id}/sync-cursor",
File without changes
File without changes