airbyte-source-shopify 3.0.14.dev202512222245__tar.gz → 3.1.0.dev202512181916__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 (70) hide show
  1. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/PKG-INFO +1 -1
  2. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/pyproject.toml +1 -1
  3. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/scopes.py +0 -1
  4. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/source.py +0 -2
  5. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/streams/streams.py +36 -101
  6. airbyte_source_shopify-3.0.14.dev202512222245/source_shopify/schemas/deleted_products.json +0 -27
  7. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/README.md +0 -0
  8. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/__init__.py +0 -0
  9. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/auth.py +0 -0
  10. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/config_migrations.py +0 -0
  11. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/http_request.py +0 -0
  12. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/run.py +0 -0
  13. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/abandoned_checkouts.json +0 -0
  14. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/articles.json +0 -0
  15. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/balance_transactions.json +0 -0
  16. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/blogs.json +0 -0
  17. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/collections.json +0 -0
  18. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/collects.json +0 -0
  19. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/countries.json +0 -0
  20. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/custom_collections.json +0 -0
  21. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/customer_address.json +0 -0
  22. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/customer_journey_summary.json +0 -0
  23. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/customers.json +0 -0
  24. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/discount_codes.json +0 -0
  25. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/disputes.json +0 -0
  26. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/draft_orders.json +0 -0
  27. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/fulfillment_orders.json +0 -0
  28. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/fulfillments.json +0 -0
  29. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/inventory_items.json +0 -0
  30. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/inventory_levels.json +0 -0
  31. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/locations.json +0 -0
  32. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_articles.json +0 -0
  33. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_blogs.json +0 -0
  34. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_collections.json +0 -0
  35. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_customers.json +0 -0
  36. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_draft_orders.json +0 -0
  37. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_locations.json +0 -0
  38. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_orders.json +0 -0
  39. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_pages.json +0 -0
  40. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_product_images.json +0 -0
  41. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_product_variants.json +0 -0
  42. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_products.json +0 -0
  43. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_shops.json +0 -0
  44. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/metafield_smart_collections.json +0 -0
  45. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/order_agreements.json +0 -0
  46. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/order_refunds.json +0 -0
  47. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/order_risks.json +0 -0
  48. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/orders.json +0 -0
  49. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/pages.json +0 -0
  50. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/price_rules.json +0 -0
  51. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/product_images.json +0 -0
  52. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/product_variants.json +0 -0
  53. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/products.json +0 -0
  54. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/profile_location_groups.json +0 -0
  55. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/shop.json +0 -0
  56. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/smart_collections.json +0 -0
  57. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/tender_transactions.json +0 -0
  58. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/schemas/transactions.json +0 -0
  59. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/__init__.py +0 -0
  60. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/exceptions.py +0 -0
  61. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/job.py +0 -0
  62. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/query.py +0 -0
  63. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/record.py +0 -0
  64. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/retry.py +0 -0
  65. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/status.py +0 -0
  66. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/shopify_graphql/bulk/tools.py +0 -0
  67. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/spec.json +0 -0
  68. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/streams/base_streams.py +0 -0
  69. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/transform.py +0 -0
  70. {airbyte_source_shopify-3.0.14.dev202512222245 → airbyte_source_shopify-3.1.0.dev202512181916}/source_shopify/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-source-shopify
3
- Version: 3.0.14.dev202512222245
3
+ Version: 3.1.0.dev202512181916
4
4
  Summary: Source CDK implementation for Shopify.
5
5
  Home-page: https://airbyte.com
6
6
  License: ELv2
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
3
3
  build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
- version = "3.0.14.dev.202512222245"
6
+ version = "3.1.0.dev.202512181916"
7
7
  name = "airbyte-source-shopify"
8
8
  description = "Source CDK implementation for Shopify."
9
9
  authors = [ "Airbyte <contact@airbyte.io>",]
@@ -37,7 +37,6 @@ SCOPES_MAPPING: Mapping[str, set[str]] = {
37
37
  "MetafieldDraftOrders": ("read_draft_orders",),
38
38
  # SCOPE: read_products
39
39
  "Products": ("read_products",),
40
- "DeletedProducts": ("read_products",),
41
40
  "MetafieldProducts": ("read_products",),
42
41
  "ProductImages": ("read_products",),
43
42
  "MetafieldProductImages": ("read_products",),
@@ -27,7 +27,6 @@ from .streams.streams import (
27
27
  CustomerAddress,
28
28
  CustomerJourneySummary,
29
29
  Customers,
30
- DeletedProducts,
31
30
  DiscountCodes,
32
31
  Disputes,
33
32
  DraftOrders,
@@ -212,7 +211,6 @@ class SourceShopify(AbstractSource):
212
211
  PriceRules(config),
213
212
  ProductImages(config),
214
213
  Products(config),
215
- DeletedProducts(config),
216
214
  ProductVariants(config),
217
215
  Shop(config),
218
216
  SmartCollections(config),
@@ -135,100 +135,6 @@ class Products(IncrementalShopifyGraphQlBulkStream):
135
135
  bulk_query: Product = Product
136
136
 
137
137
 
138
- class DeletedProducts(IncrementalShopifyStream):
139
- """
140
- Stream for fetching deleted products using the Shopify GraphQL Events API.
141
- This stream queries events with action:destroy and subject_type:Product to get deleted product records.
142
- https://shopify.dev/docs/api/admin-graphql/latest/queries/events
143
- """
144
-
145
- data_field = "graphql"
146
- cursor_field = "deleted_at"
147
- http_method = "POST"
148
- filter_field = None
149
-
150
- _page_cursor: Optional[str] = None
151
-
152
- EVENTS_QUERY = """
153
- query GetDeletedProductEvents($first: Int!, $after: String, $query: String) {
154
- events(first: $first, after: $after, query: $query, sortKey: CREATED_AT) {
155
- pageInfo {
156
- hasNextPage
157
- endCursor
158
- }
159
- nodes {
160
- ... on BasicEvent {
161
- id
162
- createdAt
163
- message
164
- subjectId
165
- subjectType
166
- }
167
- }
168
- }
169
- }
170
- """
171
-
172
- @property
173
- def url_base(self) -> str:
174
- return f"https://{self.config['shop']}.myshopify.com/admin/api/{self.api_version}/graphql.json"
175
-
176
- def path(self, **kwargs) -> str:
177
- return ""
178
-
179
- def request_params(
180
- self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs
181
- ) -> MutableMapping[str, Any]:
182
- return {}
183
-
184
- def request_body_json(
185
- self,
186
- stream_state: Optional[Mapping[str, Any]] = None,
187
- stream_slice: Optional[Mapping[str, Any]] = None,
188
- next_page_token: Optional[Mapping[str, Any]] = None,
189
- ) -> Optional[Mapping[str, Any]]:
190
- query_filter = "action:destroy AND subject_type:Product"
191
- if stream_state and stream_state.get(self.cursor_field):
192
- state_value = stream_state[self.cursor_field]
193
- query_filter += f" AND created_at:>'{state_value}'"
194
-
195
- variables = {
196
- "first": 250,
197
- "query": query_filter,
198
- }
199
-
200
- if next_page_token and next_page_token.get("cursor"):
201
- variables["after"] = next_page_token["cursor"]
202
-
203
- return {
204
- "query": self.EVENTS_QUERY,
205
- "variables": variables,
206
- }
207
-
208
- def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
209
- json_response = response.json()
210
- page_info = json_response.get("data", {}).get("events", {}).get("pageInfo", {})
211
- if page_info.get("hasNextPage"):
212
- return {"cursor": page_info.get("endCursor")}
213
- return None
214
-
215
- def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]:
216
- json_response = response.json()
217
- events = json_response.get("data", {}).get("events", {}).get("nodes", [])
218
- for event in events:
219
- if event.get("subjectType") == "PRODUCT" and event.get("subjectId"):
220
- subject_id = event.get("subjectId", "")
221
- product_id = int(subject_id.split("/")[-1]) if "/" in subject_id else None
222
- if product_id:
223
- yield {
224
- "id": product_id,
225
- "deleted_at": event.get("createdAt"),
226
- "deleted_message": event.get("message"),
227
- "deleted_description": None,
228
- "shop_url": self.config.get("shop"),
229
- }
230
-
231
-
232
138
  class MetafieldProducts(IncrementalShopifyGraphQlBulkStream):
233
139
  parent_stream_class = Products
234
140
  bulk_query: MetafieldProduct = MetafieldProduct
@@ -291,18 +197,47 @@ class MetafieldSmartCollections(MetafieldShopifySubstream):
291
197
 
292
198
  class Collects(IncrementalShopifyStream):
293
199
  """
294
- Collects stream does not support Incremental Refresh based on datetime fields, only `since_id` is supported:
295
- https://shopify.dev/docs/admin-api/rest/reference/products/collect
200
+ Collects stream uses client-side incremental sync because the Shopify REST API
201
+ does not support filtering by updated_at for this endpoint - only `since_id` is available.
202
+ https://shopify.dev/docs/api/admin-rest/latest/resources/collect
296
203
 
297
- The Collect stream is the link between Products and Collections, if the Collection is created for Products,
298
- the `collect` record is created, it's reasonable to Full Refresh all collects. As for Incremental refresh -
299
- we would use the since_id specificaly for this stream.
204
+ The Collect stream is the link between Products and Collections. To capture both new records
205
+ AND updates to existing records, we fetch all records and filter client-side based on updated_at.
206
+
207
+ Breaking change from previous versions: cursor_field changed from `id` to `updated_at`.
300
208
  """
301
209
 
302
210
  data_field = "collects"
303
- cursor_field = "id"
211
+ cursor_field = "updated_at"
304
212
  order_field = "id"
305
- filter_field = "since_id"
213
+
214
+ def request_params(
215
+ self, stream_state: Optional[Mapping[str, Any]] = None, next_page_token: Optional[Mapping[str, Any]] = None, **kwargs
216
+ ) -> MutableMapping[str, Any]:
217
+ """
218
+ Override to implement client-side incremental sync.
219
+ We fetch all records (no server-side filtering) and filter client-side using filter_records_newer_than_state.
220
+ The Shopify Collects API only supports since_id filtering, which cannot capture updates to existing records.
221
+ """
222
+ params = {"limit": self.limit}
223
+ if next_page_token:
224
+ params.update(**next_page_token)
225
+ else:
226
+ params["order"] = f"{self.order_field} asc"
227
+ return params
228
+
229
+ def read_records(
230
+ self,
231
+ stream_state: Optional[Mapping[str, Any]] = None,
232
+ stream_slice: Optional[Mapping[str, Any]] = None,
233
+ **kwargs,
234
+ ) -> Iterable[Mapping[str, Any]]:
235
+ """
236
+ Override to apply client-side filtering based on updated_at cursor.
237
+ This ensures we capture both new records and updates to existing records.
238
+ """
239
+ records = super().read_records(stream_state=stream_state, stream_slice=stream_slice, **kwargs)
240
+ yield from self.filter_records_newer_than_state(stream_state, records)
306
241
 
307
242
 
308
243
  class Collections(IncrementalShopifyGraphQlBulkStream):
@@ -1,27 +0,0 @@
1
- {
2
- "type": ["object", "null"],
3
- "additionalProperties": true,
4
- "properties": {
5
- "id": {
6
- "description": "The unique identifier of the deleted product.",
7
- "type": ["null", "integer"]
8
- },
9
- "deleted_at": {
10
- "description": "The date and time when the product was deleted.",
11
- "type": ["null", "string"],
12
- "format": "date-time"
13
- },
14
- "deleted_message": {
15
- "description": "Message related to the deletion of the product.",
16
- "type": ["null", "string"]
17
- },
18
- "deleted_description": {
19
- "description": "Description of the reason for deletion.",
20
- "type": ["null", "string"]
21
- },
22
- "shop_url": {
23
- "description": "The URL of the shop where the product was listed.",
24
- "type": ["null", "string"]
25
- }
26
- }
27
- }