airbyte-source-shopify 3.1.0.dev202512181928__tar.gz → 3.1.1__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.
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/PKG-INFO +1 -1
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/pyproject.toml +1 -1
- airbyte_source_shopify-3.1.1/source_shopify/schemas/deleted_products.json +27 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/scopes.py +1 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/source.py +2 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/streams/streams.py +122 -36
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/README.md +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/__init__.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/auth.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/config_migrations.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/http_request.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/run.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/abandoned_checkouts.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/articles.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/balance_transactions.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/blogs.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/collections.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/collects.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/countries.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/custom_collections.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/customer_address.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/customer_journey_summary.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/customers.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/discount_codes.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/disputes.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/draft_orders.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/fulfillment_orders.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/fulfillments.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/inventory_items.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/inventory_levels.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/locations.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_articles.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_blogs.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_collections.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_customers.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_draft_orders.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_locations.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_orders.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_pages.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_product_images.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_product_variants.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_products.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_shops.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/metafield_smart_collections.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/order_agreements.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/order_refunds.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/order_risks.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/orders.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/pages.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/price_rules.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/product_images.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/product_variants.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/products.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/profile_location_groups.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/shop.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/smart_collections.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/tender_transactions.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/schemas/transactions.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/__init__.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/exceptions.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/job.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/query.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/record.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/retry.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/status.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/shopify_graphql/bulk/tools.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/spec.json +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/streams/base_streams.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/transform.py +0 -0
- {airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/utils.py +0 -0
{airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/pyproject.toml
RENAMED
|
@@ -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.1.
|
|
6
|
+
version = "3.1.1"
|
|
7
7
|
name = "airbyte-source-shopify"
|
|
8
8
|
description = "Source CDK implementation for Shopify."
|
|
9
9
|
authors = [ "Airbyte <contact@airbyte.io>",]
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
}
|
|
@@ -37,6 +37,7 @@ 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",),
|
|
40
41
|
"MetafieldProducts": ("read_products",),
|
|
41
42
|
"ProductImages": ("read_products",),
|
|
42
43
|
"MetafieldProductImages": ("read_products",),
|
|
@@ -27,6 +27,7 @@ from .streams.streams import (
|
|
|
27
27
|
CustomerAddress,
|
|
28
28
|
CustomerJourneySummary,
|
|
29
29
|
Customers,
|
|
30
|
+
DeletedProducts,
|
|
30
31
|
DiscountCodes,
|
|
31
32
|
Disputes,
|
|
32
33
|
DraftOrders,
|
|
@@ -211,6 +212,7 @@ class SourceShopify(AbstractSource):
|
|
|
211
212
|
PriceRules(config),
|
|
212
213
|
ProductImages(config),
|
|
213
214
|
Products(config),
|
|
215
|
+
DeletedProducts(config),
|
|
214
216
|
ProductVariants(config),
|
|
215
217
|
Shop(config),
|
|
216
218
|
SmartCollections(config),
|
|
@@ -135,6 +135,110 @@ 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
|
+
Note: This stream extends IncrementalShopifyStream (REST base class) rather than IncrementalShopifyGraphQlBulkStream
|
|
145
|
+
because it uses Shopify's standard GraphQL Events API, NOT the Bulk Operations API (bulkOperationRunQuery).
|
|
146
|
+
The Events API has a fundamentally different architecture:
|
|
147
|
+
- Uses immediate queries with cursor pagination (not async job creation + file download)
|
|
148
|
+
- Returns results in response.data.events.nodes (not JSONL files)
|
|
149
|
+
- Requires different URL endpoint (/graphql.json), request format (POST with query in body), and pagination logic
|
|
150
|
+
|
|
151
|
+
Therefore, url_base, path, request_params, next_page_token, and parse_response are overridden to accommodate
|
|
152
|
+
the GraphQL request/response structure while maintaining incremental sync capabilities from the base class.
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
data_field = "graphql"
|
|
156
|
+
cursor_field = "deleted_at"
|
|
157
|
+
http_method = "POST"
|
|
158
|
+
filter_field = None
|
|
159
|
+
|
|
160
|
+
_page_cursor: Optional[str] = None
|
|
161
|
+
|
|
162
|
+
EVENTS_QUERY = """
|
|
163
|
+
query GetDeletedProductEvents($first: Int!, $after: String, $query: String) {
|
|
164
|
+
events(first: $first, after: $after, query: $query, sortKey: CREATED_AT) {
|
|
165
|
+
pageInfo {
|
|
166
|
+
hasNextPage
|
|
167
|
+
endCursor
|
|
168
|
+
}
|
|
169
|
+
nodes {
|
|
170
|
+
... on BasicEvent {
|
|
171
|
+
id
|
|
172
|
+
createdAt
|
|
173
|
+
message
|
|
174
|
+
subjectId
|
|
175
|
+
subjectType
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def url_base(self) -> str:
|
|
184
|
+
return f"https://{self.config['shop']}.myshopify.com/admin/api/{self.api_version}/graphql.json"
|
|
185
|
+
|
|
186
|
+
def path(self, **kwargs) -> str:
|
|
187
|
+
return ""
|
|
188
|
+
|
|
189
|
+
def request_params(
|
|
190
|
+
self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs
|
|
191
|
+
) -> MutableMapping[str, Any]:
|
|
192
|
+
return {}
|
|
193
|
+
|
|
194
|
+
def request_body_json(
|
|
195
|
+
self,
|
|
196
|
+
stream_state: Optional[Mapping[str, Any]] = None,
|
|
197
|
+
stream_slice: Optional[Mapping[str, Any]] = None,
|
|
198
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
199
|
+
) -> Optional[Mapping[str, Any]]:
|
|
200
|
+
query_filter = "action:destroy AND subject_type:Product"
|
|
201
|
+
if stream_state and stream_state.get(self.cursor_field):
|
|
202
|
+
state_value = stream_state[self.cursor_field]
|
|
203
|
+
query_filter += f" AND created_at:>'{state_value}'"
|
|
204
|
+
|
|
205
|
+
variables = {
|
|
206
|
+
"first": 250,
|
|
207
|
+
"query": query_filter,
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if next_page_token and next_page_token.get("cursor"):
|
|
211
|
+
variables["after"] = next_page_token["cursor"]
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
"query": self.EVENTS_QUERY,
|
|
215
|
+
"variables": variables,
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
|
|
219
|
+
json_response = response.json()
|
|
220
|
+
page_info = json_response.get("data", {}).get("events", {}).get("pageInfo", {})
|
|
221
|
+
if page_info.get("hasNextPage"):
|
|
222
|
+
return {"cursor": page_info.get("endCursor")}
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]:
|
|
226
|
+
json_response = response.json()
|
|
227
|
+
events = json_response.get("data", {}).get("events", {}).get("nodes", [])
|
|
228
|
+
for event in events:
|
|
229
|
+
if event.get("subjectType") == "PRODUCT" and event.get("subjectId"):
|
|
230
|
+
subject_id = event.get("subjectId", "")
|
|
231
|
+
product_id = int(subject_id.split("/")[-1]) if "/" in subject_id else None
|
|
232
|
+
if product_id:
|
|
233
|
+
yield {
|
|
234
|
+
"id": product_id,
|
|
235
|
+
"deleted_at": event.get("createdAt"),
|
|
236
|
+
"deleted_message": event.get("message"),
|
|
237
|
+
"deleted_description": None,
|
|
238
|
+
"shop_url": self.config.get("shop"),
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
138
242
|
class MetafieldProducts(IncrementalShopifyGraphQlBulkStream):
|
|
139
243
|
parent_stream_class = Products
|
|
140
244
|
bulk_query: MetafieldProduct = MetafieldProduct
|
|
@@ -197,47 +301,18 @@ class MetafieldSmartCollections(MetafieldShopifySubstream):
|
|
|
197
301
|
|
|
198
302
|
class Collects(IncrementalShopifyStream):
|
|
199
303
|
"""
|
|
200
|
-
Collects stream
|
|
201
|
-
|
|
202
|
-
https://shopify.dev/docs/api/admin-rest/latest/resources/collect
|
|
203
|
-
|
|
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.
|
|
304
|
+
Collects stream does not support Incremental Refresh based on datetime fields, only `since_id` is supported:
|
|
305
|
+
https://shopify.dev/docs/admin-api/rest/reference/products/collect
|
|
206
306
|
|
|
207
|
-
|
|
307
|
+
The Collect stream is the link between Products and Collections, if the Collection is created for Products,
|
|
308
|
+
the `collect` record is created, it's reasonable to Full Refresh all collects. As for Incremental refresh -
|
|
309
|
+
we would use the since_id specificaly for this stream.
|
|
208
310
|
"""
|
|
209
311
|
|
|
210
312
|
data_field = "collects"
|
|
211
|
-
cursor_field = "
|
|
313
|
+
cursor_field = "id"
|
|
212
314
|
order_field = "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)
|
|
315
|
+
filter_field = "since_id"
|
|
241
316
|
|
|
242
317
|
|
|
243
318
|
class Collections(IncrementalShopifyGraphQlBulkStream):
|
|
@@ -397,6 +472,17 @@ class Countries(HttpSubStream, FullRefreshShopifyGraphQlBulkStream):
|
|
|
397
472
|
query = DeliveryProfile
|
|
398
473
|
response_field = "deliveryProfiles"
|
|
399
474
|
|
|
475
|
+
def stream_slices(
|
|
476
|
+
self,
|
|
477
|
+
stream_state: Optional[Mapping[str, Any]] = None,
|
|
478
|
+
**kwargs,
|
|
479
|
+
) -> Iterable[Optional[Mapping[str, Any]]]:
|
|
480
|
+
for stream_slice in super().stream_slices(stream_state=stream_state, **kwargs):
|
|
481
|
+
parent = stream_slice.get("parent", {})
|
|
482
|
+
profile_location_groups = parent.get("profile_location_groups", [])
|
|
483
|
+
if profile_location_groups:
|
|
484
|
+
yield stream_slice
|
|
485
|
+
|
|
400
486
|
def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
|
|
401
487
|
json_response = response.json().get("data", {})
|
|
402
488
|
if not json_response:
|
|
File without changes
|
|
File without changes
|
{airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/auth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{airbyte_source_shopify-3.1.0.dev202512181928 → airbyte_source_shopify-3.1.1}/source_shopify/run.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|