airbyte-source-shopify 2.5.12.dev202412101009__tar.gz → 2.5.13__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 (72) hide show
  1. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/PKG-INFO +2 -2
  2. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/pyproject.toml +2 -2
  3. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/exceptions.py +5 -0
  4. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/job.py +39 -4
  5. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/spec.json +2 -2
  6. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/README.md +0 -0
  7. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/__init__.py +0 -0
  8. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/auth.py +0 -0
  9. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/config_migrations.py +0 -0
  10. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/http_request.py +0 -0
  11. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/run.py +0 -0
  12. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/abandoned_checkouts.json +0 -0
  13. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/articles.json +0 -0
  14. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/balance_transactions.json +0 -0
  15. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/blogs.json +0 -0
  16. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/collections.json +0 -0
  17. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/collects.json +0 -0
  18. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/countries.json +0 -0
  19. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/custom_collections.json +0 -0
  20. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/customer_address.json +0 -0
  21. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/customer_journey_summary.json +0 -0
  22. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/customer_saved_search.json +0 -0
  23. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/customers.json +0 -0
  24. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/discount_codes.json +0 -0
  25. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/disputes.json +0 -0
  26. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/draft_orders.json +0 -0
  27. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/fulfillment_orders.json +0 -0
  28. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/fulfillments.json +0 -0
  29. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/inventory_items.json +0 -0
  30. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/inventory_levels.json +0 -0
  31. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/locations.json +0 -0
  32. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_articles.json +0 -0
  33. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_blogs.json +0 -0
  34. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_collections.json +0 -0
  35. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_customers.json +0 -0
  36. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_draft_orders.json +0 -0
  37. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_locations.json +0 -0
  38. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_orders.json +0 -0
  39. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_pages.json +0 -0
  40. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_product_images.json +0 -0
  41. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_product_variants.json +0 -0
  42. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_products.json +0 -0
  43. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_shops.json +0 -0
  44. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/metafield_smart_collections.json +0 -0
  45. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/order_agreements.json +0 -0
  46. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/order_refunds.json +0 -0
  47. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/order_risks.json +0 -0
  48. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/orders.json +0 -0
  49. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/pages.json +0 -0
  50. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/price_rules.json +0 -0
  51. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/product_images.json +0 -0
  52. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/product_variants.json +0 -0
  53. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/products.json +0 -0
  54. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/products_graph_ql.json +0 -0
  55. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/shop.json +0 -0
  56. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/smart_collections.json +0 -0
  57. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/tender_transactions.json +0 -0
  58. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/schemas/transactions.json +0 -0
  59. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/scopes.py +0 -0
  60. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/__init__.py +0 -0
  61. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/query.py +0 -0
  62. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/record.py +0 -0
  63. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/retry.py +0 -0
  64. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/status.py +0 -0
  65. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/bulk/tools.py +0 -0
  66. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/graphql.py +0 -0
  67. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/shopify_graphql/schema.py +0 -0
  68. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/source.py +0 -0
  69. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/streams/base_streams.py +0 -0
  70. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/streams/streams.py +0 -0
  71. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/transform.py +0 -0
  72. {airbyte_source_shopify-2.5.12.dev202412101009 → airbyte_source_shopify-2.5.13}/source_shopify/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-source-shopify
3
- Version: 2.5.12.dev202412101009
3
+ Version: 2.5.13
4
4
  Summary: Source CDK implementation for Shopify.
5
5
  Home-page: https://airbyte.com
6
6
  License: ELv2
@@ -11,7 +11,7 @@ Classifier: License :: Other/Proprietary License
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
- Requires-Dist: airbyte-cdk (>=5,<6)
14
+ Requires-Dist: airbyte-cdk (>=6,<7)
15
15
  Requires-Dist: graphql-query (>=1,<2)
16
16
  Requires-Dist: sgqlc (==16.3)
17
17
  Project-URL: Documentation, https://docs.airbyte.com/integrations/sources/shopify
@@ -5,7 +5,7 @@ requires = [
5
5
  build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [tool.poetry]
8
- version = "2.5.12.dev202412101009"
8
+ version = "2.5.13"
9
9
  name = "airbyte-source-shopify"
10
10
  description = "Source CDK implementation for Shopify."
11
11
  authors = [
@@ -22,7 +22,7 @@ packages = [
22
22
 
23
23
  [tool.poetry.dependencies]
24
24
  python = "^3.10,<3.12"
25
- airbyte-cdk = "^5"
25
+ airbyte-cdk = "^6"
26
26
  sgqlc = "==16.3"
27
27
  graphql-query = "^1"
28
28
 
@@ -52,6 +52,11 @@ class ShopifyBulkExceptions:
52
52
 
53
53
  failure_type: FailureType = FailureType.transient_error
54
54
 
55
+ class BulkJobCheckpointCollisionError(BaseBulkException):
56
+ """Raised when an attempt to create a job using the `checkpointed cursor` value goes into inf.loop."""
57
+
58
+ failure_type: FailureType = FailureType.transient_error
59
+
55
60
  class BulkJobRedirectToOtherShopError(BaseBulkException):
56
61
  """Raised when the response contains another shop name"""
57
62
 
@@ -53,7 +53,7 @@ class ShopifyBulkManager:
53
53
 
54
54
  # currents: _job_id, _job_state, _job_created_at, _job_self_canceled
55
55
  _job_id: Optional[str] = field(init=False, default=None)
56
- _job_state: str = field(init=False, default=None) # this string is based on ShopifyBulkJobStatus
56
+ _job_state: str | None = field(init=False, default=None) # this string is based on ShopifyBulkJobStatus
57
57
  # completed and saved Bulk Job result filename
58
58
  _job_result_filename: Optional[str] = field(init=False, default=None)
59
59
  # date-time when the Bulk Job was created on the server
@@ -70,6 +70,8 @@ class ShopifyBulkManager:
70
70
  _job_last_rec_count: int = field(init=False, default=0)
71
71
  # the flag to adjust the next slice from the checkpointed cursor vaue
72
72
  _job_adjust_slice_from_checkpoint: bool = field(init=False, default=False)
73
+ # keeps the last checkpointed cursor value for supported streams
74
+ _job_last_checkpoint_cursor_value: str | None = field(init=False, default=None)
73
75
 
74
76
  # expand slice factor
75
77
  _job_size_expand_factor: int = field(init=False, default=2)
@@ -209,6 +211,27 @@ class ShopifyBulkManager:
209
211
  # reseting the checkpoint flag, if bulk job has completed normally
210
212
  self._job_adjust_slice_from_checkpoint = False
211
213
 
214
+ def _set_last_checkpoint_cursor_value(self, checkpointed_cursor: str) -> None:
215
+ """
216
+ Sets the last checkpoint cursor value.
217
+
218
+ Args:
219
+ checkpointed_cursor (str): The cursor value to set as the last checkpoint. Defaults to None.
220
+ """
221
+ self._job_last_checkpoint_cursor_value = checkpointed_cursor
222
+
223
+ def _checkpoint_cursor_has_collision(self, checkpointed_cursor: str) -> bool:
224
+ """
225
+ Checks if the provided checkpointed cursor collides with the last checkpointed cursor value.
226
+
227
+ Args:
228
+ checkpointed_cursor (str): The cursor value to check for collision. Defaults to None.
229
+
230
+ Returns:
231
+ bool: True if the provided cursor collides with the last checkpointed cursor value, False otherwise.
232
+ """
233
+ return self._job_last_checkpoint_cursor_value == checkpointed_cursor
234
+
212
235
  def _job_completed(self) -> bool:
213
236
  return self._job_state == ShopifyBulkJobStatus.COMPLETED.value
214
237
 
@@ -329,7 +352,7 @@ class ShopifyBulkManager:
329
352
  def _on_completed_job(self, response: Optional[requests.Response] = None) -> None:
330
353
  self._job_result_filename = self._job_get_result(response)
331
354
 
332
- def _on_failed_job(self, response: requests.Response) -> AirbyteTracedException:
355
+ def _on_failed_job(self, response: requests.Response) -> AirbyteTracedException | None:
333
356
  if not self._supports_checkpointing:
334
357
  raise ShopifyBulkExceptions.BulkJobFailed(
335
358
  f"The BULK Job: `{self._job_id}` exited with {self._job_state}, details: {response.text}",
@@ -485,7 +508,7 @@ class ShopifyBulkManager:
485
508
  self._job_state = ShopifyBulkJobStatus.CREATED.value
486
509
  LOGGER.info(f"Stream: `{self.http_client.name}`, the BULK Job: `{self._job_id}` is {ShopifyBulkJobStatus.CREATED.value}")
487
510
 
488
- def job_size_normalize(self, start: datetime, end: datetime) -> datetime:
511
+ def job_size_normalize(self, start: datetime, end: datetime) -> None:
489
512
  # adjust slice size when it's bigger than the loop point when it should end,
490
513
  # to preserve correct job size adjustments when this is the only job we need to run, based on STATE provided
491
514
  requested_slice_size = (end - start).total_days()
@@ -498,8 +521,20 @@ class ShopifyBulkManager:
498
521
  def _adjust_slice_end(self, slice_end: datetime, checkpointed_cursor: Optional[str] = None) -> datetime:
499
522
  """
500
523
  Choose between the existing `slice_end` value or `checkpointed_cursor` value, if provided.
524
+
525
+ Optionally: raises the `transient` error if the checkpoint collision occurs.
501
526
  """
502
- return pdm.parse(checkpointed_cursor) if checkpointed_cursor else slice_end
527
+
528
+ if checkpointed_cursor:
529
+ if self._checkpoint_cursor_has_collision(checkpointed_cursor):
530
+ raise ShopifyBulkExceptions.BulkJobCheckpointCollisionError(
531
+ f"The stream: `{self.http_client.name}` checkpoint collision is detected. Try to increase the `BULK Job checkpoint (rows collected)` to the bigger value. The stream will be synced again during the next sync attempt."
532
+ )
533
+ # set the checkpointed cursor value
534
+ self._set_last_checkpoint_cursor_value(checkpointed_cursor)
535
+ return pdm.parse(checkpointed_cursor)
536
+
537
+ return slice_end
503
538
 
504
539
  def get_adjusted_job_end(self, slice_start: datetime, slice_end: datetime, checkpointed_cursor: Optional[str] = None) -> datetime:
505
540
  if self._job_adjust_slice_from_checkpoint:
@@ -115,10 +115,10 @@
115
115
  "job_checkpoint_interval": {
116
116
  "type": "integer",
117
117
  "title": "BULK Job checkpoint (rows collected)",
118
- "description": "The threshold, after which the single BULK Job should be checkpointed.",
118
+ "description": "The threshold, after which the single BULK Job should be checkpointed (min: 15k, max: 1M)",
119
119
  "default": 100000,
120
120
  "minimum": 15000,
121
- "maximum": 200000
121
+ "maximum": 1000000
122
122
  }
123
123
  }
124
124
  },