airbyte-agent-shopify 0.1.0__py3-none-any.whl

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 (57) hide show
  1. airbyte_agent_shopify/__init__.py +349 -0
  2. airbyte_agent_shopify/_vendored/__init__.py +1 -0
  3. airbyte_agent_shopify/_vendored/connector_sdk/__init__.py +82 -0
  4. airbyte_agent_shopify/_vendored/connector_sdk/auth_strategies.py +1120 -0
  5. airbyte_agent_shopify/_vendored/connector_sdk/auth_template.py +135 -0
  6. airbyte_agent_shopify/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
  7. airbyte_agent_shopify/_vendored/connector_sdk/cloud_utils/client.py +213 -0
  8. airbyte_agent_shopify/_vendored/connector_sdk/connector_model_loader.py +965 -0
  9. airbyte_agent_shopify/_vendored/connector_sdk/constants.py +78 -0
  10. airbyte_agent_shopify/_vendored/connector_sdk/exceptions.py +23 -0
  11. airbyte_agent_shopify/_vendored/connector_sdk/executor/__init__.py +31 -0
  12. airbyte_agent_shopify/_vendored/connector_sdk/executor/hosted_executor.py +196 -0
  13. airbyte_agent_shopify/_vendored/connector_sdk/executor/local_executor.py +1722 -0
  14. airbyte_agent_shopify/_vendored/connector_sdk/executor/models.py +190 -0
  15. airbyte_agent_shopify/_vendored/connector_sdk/extensions.py +693 -0
  16. airbyte_agent_shopify/_vendored/connector_sdk/http/__init__.py +37 -0
  17. airbyte_agent_shopify/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
  18. airbyte_agent_shopify/_vendored/connector_sdk/http/adapters/httpx_adapter.py +251 -0
  19. airbyte_agent_shopify/_vendored/connector_sdk/http/config.py +98 -0
  20. airbyte_agent_shopify/_vendored/connector_sdk/http/exceptions.py +119 -0
  21. airbyte_agent_shopify/_vendored/connector_sdk/http/protocols.py +114 -0
  22. airbyte_agent_shopify/_vendored/connector_sdk/http/response.py +104 -0
  23. airbyte_agent_shopify/_vendored/connector_sdk/http_client.py +693 -0
  24. airbyte_agent_shopify/_vendored/connector_sdk/introspection.py +262 -0
  25. airbyte_agent_shopify/_vendored/connector_sdk/logging/__init__.py +11 -0
  26. airbyte_agent_shopify/_vendored/connector_sdk/logging/logger.py +273 -0
  27. airbyte_agent_shopify/_vendored/connector_sdk/logging/types.py +93 -0
  28. airbyte_agent_shopify/_vendored/connector_sdk/observability/__init__.py +11 -0
  29. airbyte_agent_shopify/_vendored/connector_sdk/observability/config.py +179 -0
  30. airbyte_agent_shopify/_vendored/connector_sdk/observability/models.py +19 -0
  31. airbyte_agent_shopify/_vendored/connector_sdk/observability/redactor.py +81 -0
  32. airbyte_agent_shopify/_vendored/connector_sdk/observability/session.py +103 -0
  33. airbyte_agent_shopify/_vendored/connector_sdk/performance/__init__.py +6 -0
  34. airbyte_agent_shopify/_vendored/connector_sdk/performance/instrumentation.py +57 -0
  35. airbyte_agent_shopify/_vendored/connector_sdk/performance/metrics.py +93 -0
  36. airbyte_agent_shopify/_vendored/connector_sdk/schema/__init__.py +75 -0
  37. airbyte_agent_shopify/_vendored/connector_sdk/schema/base.py +164 -0
  38. airbyte_agent_shopify/_vendored/connector_sdk/schema/components.py +239 -0
  39. airbyte_agent_shopify/_vendored/connector_sdk/schema/connector.py +120 -0
  40. airbyte_agent_shopify/_vendored/connector_sdk/schema/extensions.py +230 -0
  41. airbyte_agent_shopify/_vendored/connector_sdk/schema/operations.py +146 -0
  42. airbyte_agent_shopify/_vendored/connector_sdk/schema/security.py +223 -0
  43. airbyte_agent_shopify/_vendored/connector_sdk/secrets.py +182 -0
  44. airbyte_agent_shopify/_vendored/connector_sdk/telemetry/__init__.py +10 -0
  45. airbyte_agent_shopify/_vendored/connector_sdk/telemetry/config.py +32 -0
  46. airbyte_agent_shopify/_vendored/connector_sdk/telemetry/events.py +59 -0
  47. airbyte_agent_shopify/_vendored/connector_sdk/telemetry/tracker.py +155 -0
  48. airbyte_agent_shopify/_vendored/connector_sdk/types.py +245 -0
  49. airbyte_agent_shopify/_vendored/connector_sdk/utils.py +60 -0
  50. airbyte_agent_shopify/_vendored/connector_sdk/validation.py +828 -0
  51. airbyte_agent_shopify/connector.py +2985 -0
  52. airbyte_agent_shopify/connector_model.py +11641 -0
  53. airbyte_agent_shopify/models.py +1192 -0
  54. airbyte_agent_shopify/types.py +338 -0
  55. airbyte_agent_shopify-0.1.0.dist-info/METADATA +139 -0
  56. airbyte_agent_shopify-0.1.0.dist-info/RECORD +57 -0
  57. airbyte_agent_shopify-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,2985 @@
1
+ """
2
+ Shopify connector.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import logging
8
+ from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
9
+ try:
10
+ from typing import Literal
11
+ except ImportError:
12
+ from typing_extensions import Literal
13
+
14
+ from .connector_model import ShopifyConnectorModel
15
+ from ._vendored.connector_sdk.introspection import describe_entities, generate_tool_description
16
+ from .types import (
17
+ AbandonedCheckoutsListParams,
18
+ CollectsGetParams,
19
+ CollectsListParams,
20
+ CountriesGetParams,
21
+ CountriesListParams,
22
+ CustomCollectionsGetParams,
23
+ CustomCollectionsListParams,
24
+ CustomerAddressGetParams,
25
+ CustomerAddressListParams,
26
+ CustomersGetParams,
27
+ CustomersListParams,
28
+ DiscountCodesGetParams,
29
+ DiscountCodesListParams,
30
+ DraftOrdersGetParams,
31
+ DraftOrdersListParams,
32
+ FulfillmentOrdersGetParams,
33
+ FulfillmentOrdersListParams,
34
+ FulfillmentsGetParams,
35
+ FulfillmentsListParams,
36
+ InventoryItemsGetParams,
37
+ InventoryItemsListParams,
38
+ InventoryLevelsListParams,
39
+ LocationsGetParams,
40
+ LocationsListParams,
41
+ MetafieldCustomersListParams,
42
+ MetafieldDraftOrdersListParams,
43
+ MetafieldLocationsListParams,
44
+ MetafieldOrdersListParams,
45
+ MetafieldProductImagesListParams,
46
+ MetafieldProductVariantsListParams,
47
+ MetafieldProductsListParams,
48
+ MetafieldShopsGetParams,
49
+ MetafieldShopsListParams,
50
+ MetafieldSmartCollectionsListParams,
51
+ OrderRefundsGetParams,
52
+ OrderRefundsListParams,
53
+ OrdersGetParams,
54
+ OrdersListParams,
55
+ PriceRulesGetParams,
56
+ PriceRulesListParams,
57
+ ProductImagesGetParams,
58
+ ProductImagesListParams,
59
+ ProductVariantsGetParams,
60
+ ProductVariantsListParams,
61
+ ProductsGetParams,
62
+ ProductsListParams,
63
+ ShopGetParams,
64
+ SmartCollectionsGetParams,
65
+ SmartCollectionsListParams,
66
+ TenderTransactionsListParams,
67
+ TransactionsGetParams,
68
+ TransactionsListParams,
69
+ )
70
+ if TYPE_CHECKING:
71
+ from .models import ShopifyAuthConfig
72
+ # Import response models and envelope models at runtime
73
+ from .models import (
74
+ ShopifyExecuteResult,
75
+ ShopifyExecuteResultWithMeta,
76
+ CustomersListResult,
77
+ OrdersListResult,
78
+ ProductsListResult,
79
+ ProductVariantsListResult,
80
+ ProductImagesListResult,
81
+ AbandonedCheckoutsListResult,
82
+ LocationsListResult,
83
+ InventoryLevelsListResult,
84
+ InventoryItemsListResult,
85
+ PriceRulesListResult,
86
+ DiscountCodesListResult,
87
+ CustomCollectionsListResult,
88
+ SmartCollectionsListResult,
89
+ CollectsListResult,
90
+ DraftOrdersListResult,
91
+ FulfillmentsListResult,
92
+ OrderRefundsListResult,
93
+ TransactionsListResult,
94
+ TenderTransactionsListResult,
95
+ CountriesListResult,
96
+ MetafieldShopsListResult,
97
+ MetafieldCustomersListResult,
98
+ MetafieldProductsListResult,
99
+ MetafieldOrdersListResult,
100
+ MetafieldDraftOrdersListResult,
101
+ MetafieldLocationsListResult,
102
+ MetafieldProductVariantsListResult,
103
+ MetafieldSmartCollectionsListResult,
104
+ MetafieldProductImagesListResult,
105
+ CustomerAddressListResult,
106
+ FulfillmentOrdersListResult,
107
+ AbandonedCheckout,
108
+ Collect,
109
+ Country,
110
+ CustomCollection,
111
+ Customer,
112
+ CustomerAddress,
113
+ DiscountCode,
114
+ DraftOrder,
115
+ Fulfillment,
116
+ FulfillmentOrder,
117
+ InventoryItem,
118
+ InventoryLevel,
119
+ Location,
120
+ Metafield,
121
+ Order,
122
+ PriceRule,
123
+ Product,
124
+ ProductImage,
125
+ ProductVariant,
126
+ Refund,
127
+ Shop,
128
+ SmartCollection,
129
+ TenderTransaction,
130
+ Transaction,
131
+ )
132
+
133
+ # TypeVar for decorator type preservation
134
+ _F = TypeVar("_F", bound=Callable[..., Any])
135
+
136
+
137
+
138
+ class ShopifyConnector:
139
+ """
140
+ Type-safe Shopify API connector.
141
+
142
+ Auto-generated from OpenAPI specification with full type safety.
143
+ """
144
+
145
+ connector_name = "shopify"
146
+ connector_version = "0.1.1"
147
+ vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
148
+
149
+ # Map of (entity, action) -> needs_envelope for envelope wrapping decision
150
+ _ENVELOPE_MAP = {
151
+ ("customers", "list"): True,
152
+ ("customers", "get"): None,
153
+ ("orders", "list"): True,
154
+ ("orders", "get"): None,
155
+ ("products", "list"): True,
156
+ ("products", "get"): None,
157
+ ("product_variants", "list"): True,
158
+ ("product_variants", "get"): None,
159
+ ("product_images", "list"): True,
160
+ ("product_images", "get"): None,
161
+ ("abandoned_checkouts", "list"): True,
162
+ ("locations", "list"): True,
163
+ ("locations", "get"): None,
164
+ ("inventory_levels", "list"): True,
165
+ ("inventory_items", "list"): True,
166
+ ("inventory_items", "get"): None,
167
+ ("shop", "get"): None,
168
+ ("price_rules", "list"): True,
169
+ ("price_rules", "get"): None,
170
+ ("discount_codes", "list"): True,
171
+ ("discount_codes", "get"): None,
172
+ ("custom_collections", "list"): True,
173
+ ("custom_collections", "get"): None,
174
+ ("smart_collections", "list"): True,
175
+ ("smart_collections", "get"): None,
176
+ ("collects", "list"): True,
177
+ ("collects", "get"): None,
178
+ ("draft_orders", "list"): True,
179
+ ("draft_orders", "get"): None,
180
+ ("fulfillments", "list"): True,
181
+ ("fulfillments", "get"): None,
182
+ ("order_refunds", "list"): True,
183
+ ("order_refunds", "get"): None,
184
+ ("transactions", "list"): True,
185
+ ("transactions", "get"): None,
186
+ ("tender_transactions", "list"): True,
187
+ ("countries", "list"): True,
188
+ ("countries", "get"): None,
189
+ ("metafield_shops", "list"): True,
190
+ ("metafield_shops", "get"): None,
191
+ ("metafield_customers", "list"): True,
192
+ ("metafield_products", "list"): True,
193
+ ("metafield_orders", "list"): True,
194
+ ("metafield_draft_orders", "list"): True,
195
+ ("metafield_locations", "list"): True,
196
+ ("metafield_product_variants", "list"): True,
197
+ ("metafield_smart_collections", "list"): True,
198
+ ("metafield_product_images", "list"): True,
199
+ ("customer_address", "list"): True,
200
+ ("customer_address", "get"): None,
201
+ ("fulfillment_orders", "list"): True,
202
+ ("fulfillment_orders", "get"): None,
203
+ }
204
+
205
+ # Map of (entity, action) -> {python_param_name: api_param_name}
206
+ # Used to convert snake_case TypedDict keys to API parameter names in execute()
207
+ _PARAM_MAP = {
208
+ ('customers', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'created_at_min': 'created_at_min', 'created_at_max': 'created_at_max', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max'},
209
+ ('customers', 'get'): {'customer_id': 'customer_id'},
210
+ ('orders', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'created_at_min': 'created_at_min', 'created_at_max': 'created_at_max', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max', 'status': 'status', 'financial_status': 'financial_status', 'fulfillment_status': 'fulfillment_status'},
211
+ ('orders', 'get'): {'order_id': 'order_id'},
212
+ ('products', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'created_at_min': 'created_at_min', 'created_at_max': 'created_at_max', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max', 'status': 'status', 'product_type': 'product_type', 'vendor': 'vendor', 'collection_id': 'collection_id'},
213
+ ('products', 'get'): {'product_id': 'product_id'},
214
+ ('product_variants', 'list'): {'product_id': 'product_id', 'limit': 'limit', 'since_id': 'since_id'},
215
+ ('product_variants', 'get'): {'variant_id': 'variant_id'},
216
+ ('product_images', 'list'): {'product_id': 'product_id', 'since_id': 'since_id'},
217
+ ('product_images', 'get'): {'product_id': 'product_id', 'image_id': 'image_id'},
218
+ ('abandoned_checkouts', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'created_at_min': 'created_at_min', 'created_at_max': 'created_at_max', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max', 'status': 'status'},
219
+ ('locations', 'get'): {'location_id': 'location_id'},
220
+ ('inventory_levels', 'list'): {'location_id': 'location_id', 'limit': 'limit'},
221
+ ('inventory_items', 'list'): {'ids': 'ids', 'limit': 'limit'},
222
+ ('inventory_items', 'get'): {'inventory_item_id': 'inventory_item_id'},
223
+ ('price_rules', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'created_at_min': 'created_at_min', 'created_at_max': 'created_at_max', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max'},
224
+ ('price_rules', 'get'): {'price_rule_id': 'price_rule_id'},
225
+ ('discount_codes', 'list'): {'price_rule_id': 'price_rule_id', 'limit': 'limit'},
226
+ ('discount_codes', 'get'): {'price_rule_id': 'price_rule_id', 'discount_code_id': 'discount_code_id'},
227
+ ('custom_collections', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'title': 'title', 'product_id': 'product_id', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max'},
228
+ ('custom_collections', 'get'): {'collection_id': 'collection_id'},
229
+ ('smart_collections', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'title': 'title', 'product_id': 'product_id', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max'},
230
+ ('smart_collections', 'get'): {'collection_id': 'collection_id'},
231
+ ('collects', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'collection_id': 'collection_id', 'product_id': 'product_id'},
232
+ ('collects', 'get'): {'collect_id': 'collect_id'},
233
+ ('draft_orders', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'status': 'status', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max'},
234
+ ('draft_orders', 'get'): {'draft_order_id': 'draft_order_id'},
235
+ ('fulfillments', 'list'): {'order_id': 'order_id', 'limit': 'limit', 'since_id': 'since_id', 'created_at_min': 'created_at_min', 'created_at_max': 'created_at_max', 'updated_at_min': 'updated_at_min', 'updated_at_max': 'updated_at_max'},
236
+ ('fulfillments', 'get'): {'order_id': 'order_id', 'fulfillment_id': 'fulfillment_id'},
237
+ ('order_refunds', 'list'): {'order_id': 'order_id', 'limit': 'limit'},
238
+ ('order_refunds', 'get'): {'order_id': 'order_id', 'refund_id': 'refund_id'},
239
+ ('transactions', 'list'): {'order_id': 'order_id', 'since_id': 'since_id'},
240
+ ('transactions', 'get'): {'order_id': 'order_id', 'transaction_id': 'transaction_id'},
241
+ ('tender_transactions', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'processed_at_min': 'processed_at_min', 'processed_at_max': 'processed_at_max', 'order': 'order'},
242
+ ('countries', 'list'): {'since_id': 'since_id'},
243
+ ('countries', 'get'): {'country_id': 'country_id'},
244
+ ('metafield_shops', 'list'): {'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key', 'type': 'type'},
245
+ ('metafield_shops', 'get'): {'metafield_id': 'metafield_id'},
246
+ ('metafield_customers', 'list'): {'customer_id': 'customer_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
247
+ ('metafield_products', 'list'): {'product_id': 'product_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
248
+ ('metafield_orders', 'list'): {'order_id': 'order_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
249
+ ('metafield_draft_orders', 'list'): {'draft_order_id': 'draft_order_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
250
+ ('metafield_locations', 'list'): {'location_id': 'location_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
251
+ ('metafield_product_variants', 'list'): {'variant_id': 'variant_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
252
+ ('metafield_smart_collections', 'list'): {'collection_id': 'collection_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
253
+ ('metafield_product_images', 'list'): {'product_id': 'product_id', 'image_id': 'image_id', 'limit': 'limit', 'since_id': 'since_id', 'namespace': 'namespace', 'key': 'key'},
254
+ ('customer_address', 'list'): {'customer_id': 'customer_id', 'limit': 'limit'},
255
+ ('customer_address', 'get'): {'customer_id': 'customer_id', 'address_id': 'address_id'},
256
+ ('fulfillment_orders', 'list'): {'order_id': 'order_id'},
257
+ ('fulfillment_orders', 'get'): {'fulfillment_order_id': 'fulfillment_order_id'},
258
+ }
259
+
260
+ def __init__(
261
+ self,
262
+ auth_config: ShopifyAuthConfig | None = None,
263
+ external_user_id: str | None = None,
264
+ airbyte_client_id: str | None = None,
265
+ airbyte_client_secret: str | None = None,
266
+ on_token_refresh: Any | None = None,
267
+ shop: str | None = None ):
268
+ """
269
+ Initialize a new shopify connector instance.
270
+
271
+ Supports both local and hosted execution modes:
272
+ - Local mode: Provide `auth_config` for direct API calls
273
+ - Hosted mode: Provide `external_user_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution
274
+
275
+ Args:
276
+ auth_config: Typed authentication configuration (required for local mode)
277
+ external_user_id: External user ID (required for hosted mode)
278
+ airbyte_client_id: Airbyte OAuth client ID (required for hosted mode)
279
+ airbyte_client_secret: Airbyte OAuth client secret (required for hosted mode)
280
+ on_token_refresh: Optional callback for OAuth2 token refresh persistence.
281
+ Called with new_tokens dict when tokens are refreshed. Can be sync or async.
282
+ Example: lambda tokens: save_to_database(tokens) shop: Your Shopify store name (e.g., 'my-store' from my-store.myshopify.com)
283
+ Examples:
284
+ # Local mode (direct API calls)
285
+ connector = ShopifyConnector(auth_config=ShopifyAuthConfig(api_key="...", shop="..."))
286
+ # Hosted mode (executed on Airbyte cloud)
287
+ connector = ShopifyConnector(
288
+ external_user_id="user-123",
289
+ airbyte_client_id="client_abc123",
290
+ airbyte_client_secret="secret_xyz789"
291
+ )
292
+
293
+ # Local mode with OAuth2 token refresh callback
294
+ def save_tokens(new_tokens: dict) -> None:
295
+ # Persist updated tokens to your storage (file, database, etc.)
296
+ with open("tokens.json", "w") as f:
297
+ json.dump(new_tokens, f)
298
+
299
+ connector = ShopifyConnector(
300
+ auth_config=ShopifyAuthConfig(access_token="...", refresh_token="..."),
301
+ on_token_refresh=save_tokens
302
+ )
303
+ """
304
+ # Hosted mode: external_user_id, airbyte_client_id, and airbyte_client_secret provided
305
+ if external_user_id and airbyte_client_id and airbyte_client_secret:
306
+ from ._vendored.connector_sdk.executor import HostedExecutor
307
+ self._executor = HostedExecutor(
308
+ external_user_id=external_user_id,
309
+ airbyte_client_id=airbyte_client_id,
310
+ airbyte_client_secret=airbyte_client_secret,
311
+ connector_definition_id=str(ShopifyConnectorModel.id),
312
+ )
313
+ else:
314
+ # Local mode: auth_config required
315
+ if not auth_config:
316
+ raise ValueError(
317
+ "Either provide (external_user_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
318
+ "or auth_config for local mode"
319
+ )
320
+
321
+ from ._vendored.connector_sdk.executor import LocalExecutor
322
+
323
+ # Build config_values dict from server variables
324
+ config_values: dict[str, str] = {}
325
+ if shop:
326
+ config_values["shop"] = shop
327
+
328
+ self._executor = LocalExecutor(
329
+ model=ShopifyConnectorModel,
330
+ auth_config=auth_config.model_dump() if auth_config else None,
331
+ config_values=config_values,
332
+ on_token_refresh=on_token_refresh
333
+ )
334
+
335
+ # Update base_url with server variables if provided
336
+ base_url = self._executor.http_client.base_url
337
+ if shop:
338
+ base_url = base_url.replace("{shop}", shop)
339
+ self._executor.http_client.base_url = base_url
340
+
341
+ # Initialize entity query objects
342
+ self.customers = CustomersQuery(self)
343
+ self.orders = OrdersQuery(self)
344
+ self.products = ProductsQuery(self)
345
+ self.product_variants = ProductVariantsQuery(self)
346
+ self.product_images = ProductImagesQuery(self)
347
+ self.abandoned_checkouts = AbandonedCheckoutsQuery(self)
348
+ self.locations = LocationsQuery(self)
349
+ self.inventory_levels = InventoryLevelsQuery(self)
350
+ self.inventory_items = InventoryItemsQuery(self)
351
+ self.shop = ShopQuery(self)
352
+ self.price_rules = PriceRulesQuery(self)
353
+ self.discount_codes = DiscountCodesQuery(self)
354
+ self.custom_collections = CustomCollectionsQuery(self)
355
+ self.smart_collections = SmartCollectionsQuery(self)
356
+ self.collects = CollectsQuery(self)
357
+ self.draft_orders = DraftOrdersQuery(self)
358
+ self.fulfillments = FulfillmentsQuery(self)
359
+ self.order_refunds = OrderRefundsQuery(self)
360
+ self.transactions = TransactionsQuery(self)
361
+ self.tender_transactions = TenderTransactionsQuery(self)
362
+ self.countries = CountriesQuery(self)
363
+ self.metafield_shops = MetafieldShopsQuery(self)
364
+ self.metafield_customers = MetafieldCustomersQuery(self)
365
+ self.metafield_products = MetafieldProductsQuery(self)
366
+ self.metafield_orders = MetafieldOrdersQuery(self)
367
+ self.metafield_draft_orders = MetafieldDraftOrdersQuery(self)
368
+ self.metafield_locations = MetafieldLocationsQuery(self)
369
+ self.metafield_product_variants = MetafieldProductVariantsQuery(self)
370
+ self.metafield_smart_collections = MetafieldSmartCollectionsQuery(self)
371
+ self.metafield_product_images = MetafieldProductImagesQuery(self)
372
+ self.customer_address = CustomerAddressQuery(self)
373
+ self.fulfillment_orders = FulfillmentOrdersQuery(self)
374
+
375
+ # ===== TYPED EXECUTE METHOD (Recommended Interface) =====
376
+
377
+ @overload
378
+ async def execute(
379
+ self,
380
+ entity: Literal["customers"],
381
+ action: Literal["list"],
382
+ params: "CustomersListParams"
383
+ ) -> "CustomersListResult": ...
384
+
385
+ @overload
386
+ async def execute(
387
+ self,
388
+ entity: Literal["customers"],
389
+ action: Literal["get"],
390
+ params: "CustomersGetParams"
391
+ ) -> "Customer": ...
392
+
393
+ @overload
394
+ async def execute(
395
+ self,
396
+ entity: Literal["orders"],
397
+ action: Literal["list"],
398
+ params: "OrdersListParams"
399
+ ) -> "OrdersListResult": ...
400
+
401
+ @overload
402
+ async def execute(
403
+ self,
404
+ entity: Literal["orders"],
405
+ action: Literal["get"],
406
+ params: "OrdersGetParams"
407
+ ) -> "Order": ...
408
+
409
+ @overload
410
+ async def execute(
411
+ self,
412
+ entity: Literal["products"],
413
+ action: Literal["list"],
414
+ params: "ProductsListParams"
415
+ ) -> "ProductsListResult": ...
416
+
417
+ @overload
418
+ async def execute(
419
+ self,
420
+ entity: Literal["products"],
421
+ action: Literal["get"],
422
+ params: "ProductsGetParams"
423
+ ) -> "Product": ...
424
+
425
+ @overload
426
+ async def execute(
427
+ self,
428
+ entity: Literal["product_variants"],
429
+ action: Literal["list"],
430
+ params: "ProductVariantsListParams"
431
+ ) -> "ProductVariantsListResult": ...
432
+
433
+ @overload
434
+ async def execute(
435
+ self,
436
+ entity: Literal["product_variants"],
437
+ action: Literal["get"],
438
+ params: "ProductVariantsGetParams"
439
+ ) -> "ProductVariant": ...
440
+
441
+ @overload
442
+ async def execute(
443
+ self,
444
+ entity: Literal["product_images"],
445
+ action: Literal["list"],
446
+ params: "ProductImagesListParams"
447
+ ) -> "ProductImagesListResult": ...
448
+
449
+ @overload
450
+ async def execute(
451
+ self,
452
+ entity: Literal["product_images"],
453
+ action: Literal["get"],
454
+ params: "ProductImagesGetParams"
455
+ ) -> "ProductImage": ...
456
+
457
+ @overload
458
+ async def execute(
459
+ self,
460
+ entity: Literal["abandoned_checkouts"],
461
+ action: Literal["list"],
462
+ params: "AbandonedCheckoutsListParams"
463
+ ) -> "AbandonedCheckoutsListResult": ...
464
+
465
+ @overload
466
+ async def execute(
467
+ self,
468
+ entity: Literal["locations"],
469
+ action: Literal["list"],
470
+ params: "LocationsListParams"
471
+ ) -> "LocationsListResult": ...
472
+
473
+ @overload
474
+ async def execute(
475
+ self,
476
+ entity: Literal["locations"],
477
+ action: Literal["get"],
478
+ params: "LocationsGetParams"
479
+ ) -> "Location": ...
480
+
481
+ @overload
482
+ async def execute(
483
+ self,
484
+ entity: Literal["inventory_levels"],
485
+ action: Literal["list"],
486
+ params: "InventoryLevelsListParams"
487
+ ) -> "InventoryLevelsListResult": ...
488
+
489
+ @overload
490
+ async def execute(
491
+ self,
492
+ entity: Literal["inventory_items"],
493
+ action: Literal["list"],
494
+ params: "InventoryItemsListParams"
495
+ ) -> "InventoryItemsListResult": ...
496
+
497
+ @overload
498
+ async def execute(
499
+ self,
500
+ entity: Literal["inventory_items"],
501
+ action: Literal["get"],
502
+ params: "InventoryItemsGetParams"
503
+ ) -> "InventoryItem": ...
504
+
505
+ @overload
506
+ async def execute(
507
+ self,
508
+ entity: Literal["shop"],
509
+ action: Literal["get"],
510
+ params: "ShopGetParams"
511
+ ) -> "Shop": ...
512
+
513
+ @overload
514
+ async def execute(
515
+ self,
516
+ entity: Literal["price_rules"],
517
+ action: Literal["list"],
518
+ params: "PriceRulesListParams"
519
+ ) -> "PriceRulesListResult": ...
520
+
521
+ @overload
522
+ async def execute(
523
+ self,
524
+ entity: Literal["price_rules"],
525
+ action: Literal["get"],
526
+ params: "PriceRulesGetParams"
527
+ ) -> "PriceRule": ...
528
+
529
+ @overload
530
+ async def execute(
531
+ self,
532
+ entity: Literal["discount_codes"],
533
+ action: Literal["list"],
534
+ params: "DiscountCodesListParams"
535
+ ) -> "DiscountCodesListResult": ...
536
+
537
+ @overload
538
+ async def execute(
539
+ self,
540
+ entity: Literal["discount_codes"],
541
+ action: Literal["get"],
542
+ params: "DiscountCodesGetParams"
543
+ ) -> "DiscountCode": ...
544
+
545
+ @overload
546
+ async def execute(
547
+ self,
548
+ entity: Literal["custom_collections"],
549
+ action: Literal["list"],
550
+ params: "CustomCollectionsListParams"
551
+ ) -> "CustomCollectionsListResult": ...
552
+
553
+ @overload
554
+ async def execute(
555
+ self,
556
+ entity: Literal["custom_collections"],
557
+ action: Literal["get"],
558
+ params: "CustomCollectionsGetParams"
559
+ ) -> "CustomCollection": ...
560
+
561
+ @overload
562
+ async def execute(
563
+ self,
564
+ entity: Literal["smart_collections"],
565
+ action: Literal["list"],
566
+ params: "SmartCollectionsListParams"
567
+ ) -> "SmartCollectionsListResult": ...
568
+
569
+ @overload
570
+ async def execute(
571
+ self,
572
+ entity: Literal["smart_collections"],
573
+ action: Literal["get"],
574
+ params: "SmartCollectionsGetParams"
575
+ ) -> "SmartCollection": ...
576
+
577
+ @overload
578
+ async def execute(
579
+ self,
580
+ entity: Literal["collects"],
581
+ action: Literal["list"],
582
+ params: "CollectsListParams"
583
+ ) -> "CollectsListResult": ...
584
+
585
+ @overload
586
+ async def execute(
587
+ self,
588
+ entity: Literal["collects"],
589
+ action: Literal["get"],
590
+ params: "CollectsGetParams"
591
+ ) -> "Collect": ...
592
+
593
+ @overload
594
+ async def execute(
595
+ self,
596
+ entity: Literal["draft_orders"],
597
+ action: Literal["list"],
598
+ params: "DraftOrdersListParams"
599
+ ) -> "DraftOrdersListResult": ...
600
+
601
+ @overload
602
+ async def execute(
603
+ self,
604
+ entity: Literal["draft_orders"],
605
+ action: Literal["get"],
606
+ params: "DraftOrdersGetParams"
607
+ ) -> "DraftOrder": ...
608
+
609
+ @overload
610
+ async def execute(
611
+ self,
612
+ entity: Literal["fulfillments"],
613
+ action: Literal["list"],
614
+ params: "FulfillmentsListParams"
615
+ ) -> "FulfillmentsListResult": ...
616
+
617
+ @overload
618
+ async def execute(
619
+ self,
620
+ entity: Literal["fulfillments"],
621
+ action: Literal["get"],
622
+ params: "FulfillmentsGetParams"
623
+ ) -> "Fulfillment": ...
624
+
625
+ @overload
626
+ async def execute(
627
+ self,
628
+ entity: Literal["order_refunds"],
629
+ action: Literal["list"],
630
+ params: "OrderRefundsListParams"
631
+ ) -> "OrderRefundsListResult": ...
632
+
633
+ @overload
634
+ async def execute(
635
+ self,
636
+ entity: Literal["order_refunds"],
637
+ action: Literal["get"],
638
+ params: "OrderRefundsGetParams"
639
+ ) -> "Refund": ...
640
+
641
+ @overload
642
+ async def execute(
643
+ self,
644
+ entity: Literal["transactions"],
645
+ action: Literal["list"],
646
+ params: "TransactionsListParams"
647
+ ) -> "TransactionsListResult": ...
648
+
649
+ @overload
650
+ async def execute(
651
+ self,
652
+ entity: Literal["transactions"],
653
+ action: Literal["get"],
654
+ params: "TransactionsGetParams"
655
+ ) -> "Transaction": ...
656
+
657
+ @overload
658
+ async def execute(
659
+ self,
660
+ entity: Literal["tender_transactions"],
661
+ action: Literal["list"],
662
+ params: "TenderTransactionsListParams"
663
+ ) -> "TenderTransactionsListResult": ...
664
+
665
+ @overload
666
+ async def execute(
667
+ self,
668
+ entity: Literal["countries"],
669
+ action: Literal["list"],
670
+ params: "CountriesListParams"
671
+ ) -> "CountriesListResult": ...
672
+
673
+ @overload
674
+ async def execute(
675
+ self,
676
+ entity: Literal["countries"],
677
+ action: Literal["get"],
678
+ params: "CountriesGetParams"
679
+ ) -> "Country": ...
680
+
681
+ @overload
682
+ async def execute(
683
+ self,
684
+ entity: Literal["metafield_shops"],
685
+ action: Literal["list"],
686
+ params: "MetafieldShopsListParams"
687
+ ) -> "MetafieldShopsListResult": ...
688
+
689
+ @overload
690
+ async def execute(
691
+ self,
692
+ entity: Literal["metafield_shops"],
693
+ action: Literal["get"],
694
+ params: "MetafieldShopsGetParams"
695
+ ) -> "Metafield": ...
696
+
697
+ @overload
698
+ async def execute(
699
+ self,
700
+ entity: Literal["metafield_customers"],
701
+ action: Literal["list"],
702
+ params: "MetafieldCustomersListParams"
703
+ ) -> "MetafieldCustomersListResult": ...
704
+
705
+ @overload
706
+ async def execute(
707
+ self,
708
+ entity: Literal["metafield_products"],
709
+ action: Literal["list"],
710
+ params: "MetafieldProductsListParams"
711
+ ) -> "MetafieldProductsListResult": ...
712
+
713
+ @overload
714
+ async def execute(
715
+ self,
716
+ entity: Literal["metafield_orders"],
717
+ action: Literal["list"],
718
+ params: "MetafieldOrdersListParams"
719
+ ) -> "MetafieldOrdersListResult": ...
720
+
721
+ @overload
722
+ async def execute(
723
+ self,
724
+ entity: Literal["metafield_draft_orders"],
725
+ action: Literal["list"],
726
+ params: "MetafieldDraftOrdersListParams"
727
+ ) -> "MetafieldDraftOrdersListResult": ...
728
+
729
+ @overload
730
+ async def execute(
731
+ self,
732
+ entity: Literal["metafield_locations"],
733
+ action: Literal["list"],
734
+ params: "MetafieldLocationsListParams"
735
+ ) -> "MetafieldLocationsListResult": ...
736
+
737
+ @overload
738
+ async def execute(
739
+ self,
740
+ entity: Literal["metafield_product_variants"],
741
+ action: Literal["list"],
742
+ params: "MetafieldProductVariantsListParams"
743
+ ) -> "MetafieldProductVariantsListResult": ...
744
+
745
+ @overload
746
+ async def execute(
747
+ self,
748
+ entity: Literal["metafield_smart_collections"],
749
+ action: Literal["list"],
750
+ params: "MetafieldSmartCollectionsListParams"
751
+ ) -> "MetafieldSmartCollectionsListResult": ...
752
+
753
+ @overload
754
+ async def execute(
755
+ self,
756
+ entity: Literal["metafield_product_images"],
757
+ action: Literal["list"],
758
+ params: "MetafieldProductImagesListParams"
759
+ ) -> "MetafieldProductImagesListResult": ...
760
+
761
+ @overload
762
+ async def execute(
763
+ self,
764
+ entity: Literal["customer_address"],
765
+ action: Literal["list"],
766
+ params: "CustomerAddressListParams"
767
+ ) -> "CustomerAddressListResult": ...
768
+
769
+ @overload
770
+ async def execute(
771
+ self,
772
+ entity: Literal["customer_address"],
773
+ action: Literal["get"],
774
+ params: "CustomerAddressGetParams"
775
+ ) -> "CustomerAddress": ...
776
+
777
+ @overload
778
+ async def execute(
779
+ self,
780
+ entity: Literal["fulfillment_orders"],
781
+ action: Literal["list"],
782
+ params: "FulfillmentOrdersListParams"
783
+ ) -> "FulfillmentOrdersListResult": ...
784
+
785
+ @overload
786
+ async def execute(
787
+ self,
788
+ entity: Literal["fulfillment_orders"],
789
+ action: Literal["get"],
790
+ params: "FulfillmentOrdersGetParams"
791
+ ) -> "FulfillmentOrder": ...
792
+
793
+
794
+ @overload
795
+ async def execute(
796
+ self,
797
+ entity: str,
798
+ action: str,
799
+ params: dict[str, Any]
800
+ ) -> ShopifyExecuteResult[Any] | ShopifyExecuteResultWithMeta[Any, Any] | Any: ...
801
+
802
+ async def execute(
803
+ self,
804
+ entity: str,
805
+ action: str,
806
+ params: dict[str, Any] | None = None
807
+ ) -> Any:
808
+ """
809
+ Execute an entity operation with full type safety.
810
+
811
+ This is the recommended interface for blessed connectors as it:
812
+ - Uses the same signature as non-blessed connectors
813
+ - Provides full IDE autocomplete for entity/action/params
814
+ - Makes migration from generic to blessed connectors seamless
815
+
816
+ Args:
817
+ entity: Entity name (e.g., "customers")
818
+ action: Operation action (e.g., "create", "get", "list")
819
+ params: Operation parameters (typed based on entity+action)
820
+
821
+ Returns:
822
+ Typed response based on the operation
823
+
824
+ Example:
825
+ customer = await connector.execute(
826
+ entity="customers",
827
+ action="get",
828
+ params={"id": "cus_123"}
829
+ )
830
+ """
831
+ from ._vendored.connector_sdk.executor import ExecutionConfig
832
+
833
+ # Remap parameter names from snake_case (TypedDict keys) to API parameter names
834
+ if params:
835
+ param_map = self._PARAM_MAP.get((entity, action), {})
836
+ if param_map:
837
+ params = {param_map.get(k, k): v for k, v in params.items()}
838
+
839
+ # Use ExecutionConfig for both local and hosted executors
840
+ config = ExecutionConfig(
841
+ entity=entity,
842
+ action=action,
843
+ params=params
844
+ )
845
+
846
+ result = await self._executor.execute(config)
847
+
848
+ if not result.success:
849
+ raise RuntimeError(f"Execution failed: {result.error}")
850
+
851
+ # Check if this operation has extractors configured
852
+ has_extractors = self._ENVELOPE_MAP.get((entity, action), False)
853
+
854
+ if has_extractors:
855
+ # With extractors - return Pydantic envelope with data and meta
856
+ if result.meta is not None:
857
+ return ShopifyExecuteResultWithMeta[Any, Any](
858
+ data=result.data,
859
+ meta=result.meta
860
+ )
861
+ else:
862
+ return ShopifyExecuteResult[Any](data=result.data)
863
+ else:
864
+ # No extractors - return raw response data
865
+ return result.data
866
+
867
+ # ===== INTROSPECTION METHODS =====
868
+
869
+ @classmethod
870
+ def describe(cls, func: _F) -> _F:
871
+ """
872
+ Decorator that populates a function's docstring with connector capabilities.
873
+
874
+ This class method can be used as a decorator to automatically generate
875
+ comprehensive documentation for AI tool functions.
876
+
877
+ Usage:
878
+ @mcp.tool()
879
+ @ShopifyConnector.describe
880
+ async def execute(entity: str, action: str, params: dict):
881
+ '''Execute operations.'''
882
+ ...
883
+
884
+ The decorated function's __doc__ will be updated with:
885
+ - Available entities and their actions
886
+ - Parameter signatures with required (*) and optional (?) markers
887
+ - Response structure documentation
888
+ - Example questions (if available in OpenAPI spec)
889
+
890
+ Args:
891
+ func: The function to decorate
892
+
893
+ Returns:
894
+ The same function with updated __doc__
895
+ """
896
+ description = generate_tool_description(ShopifyConnectorModel)
897
+
898
+ original_doc = func.__doc__ or ""
899
+ if original_doc.strip():
900
+ func.__doc__ = f"{original_doc.strip()}\n{description}"
901
+ else:
902
+ func.__doc__ = description
903
+
904
+ return func
905
+
906
+ def list_entities(self) -> list[dict[str, Any]]:
907
+ """
908
+ Get structured data about available entities, actions, and parameters.
909
+
910
+ Returns a list of entity descriptions with:
911
+ - entity_name: Name of the entity (e.g., "contacts", "deals")
912
+ - description: Entity description from the first endpoint
913
+ - available_actions: List of actions (e.g., ["list", "get", "create"])
914
+ - parameters: Dict mapping action -> list of parameter dicts
915
+
916
+ Example:
917
+ entities = connector.list_entities()
918
+ for entity in entities:
919
+ print(f"{entity['entity_name']}: {entity['available_actions']}")
920
+ """
921
+ return describe_entities(ShopifyConnectorModel)
922
+
923
+ def entity_schema(self, entity: str) -> dict[str, Any] | None:
924
+ """
925
+ Get the JSON schema for an entity.
926
+
927
+ Args:
928
+ entity: Entity name (e.g., "contacts", "companies")
929
+
930
+ Returns:
931
+ JSON schema dict describing the entity structure, or None if not found.
932
+
933
+ Example:
934
+ schema = connector.entity_schema("contacts")
935
+ if schema:
936
+ print(f"Contact properties: {list(schema.get('properties', {}).keys())}")
937
+ """
938
+ entity_def = next(
939
+ (e for e in ShopifyConnectorModel.entities if e.name == entity),
940
+ None
941
+ )
942
+ if entity_def is None:
943
+ logging.getLogger(__name__).warning(
944
+ f"Entity '{entity}' not found. Available entities: "
945
+ f"{[e.name for e in ShopifyConnectorModel.entities]}"
946
+ )
947
+ return entity_def.entity_schema if entity_def else None
948
+
949
+
950
+
951
+ class CustomersQuery:
952
+ """
953
+ Query class for Customers entity operations.
954
+ """
955
+
956
+ def __init__(self, connector: ShopifyConnector):
957
+ """Initialize query with connector reference."""
958
+ self._connector = connector
959
+
960
+ async def list(
961
+ self,
962
+ limit: int | None = None,
963
+ since_id: int | None = None,
964
+ created_at_min: str | None = None,
965
+ created_at_max: str | None = None,
966
+ updated_at_min: str | None = None,
967
+ updated_at_max: str | None = None,
968
+ **kwargs
969
+ ) -> CustomersListResult:
970
+ """
971
+ Returns a list of customers from the store
972
+
973
+ Args:
974
+ limit: Maximum number of results to return (max 250)
975
+ since_id: Restrict results to after the specified ID
976
+ created_at_min: Show customers created after date (ISO 8601 format)
977
+ created_at_max: Show customers created before date (ISO 8601 format)
978
+ updated_at_min: Show customers last updated after date (ISO 8601 format)
979
+ updated_at_max: Show customers last updated before date (ISO 8601 format)
980
+ **kwargs: Additional parameters
981
+
982
+ Returns:
983
+ CustomersListResult
984
+ """
985
+ params = {k: v for k, v in {
986
+ "limit": limit,
987
+ "since_id": since_id,
988
+ "created_at_min": created_at_min,
989
+ "created_at_max": created_at_max,
990
+ "updated_at_min": updated_at_min,
991
+ "updated_at_max": updated_at_max,
992
+ **kwargs
993
+ }.items() if v is not None}
994
+
995
+ result = await self._connector.execute("customers", "list", params)
996
+ # Cast generic envelope to concrete typed result
997
+ return CustomersListResult(
998
+ data=result.data,
999
+ meta=result.meta
1000
+ )
1001
+
1002
+
1003
+
1004
+ async def get(
1005
+ self,
1006
+ customer_id: str,
1007
+ **kwargs
1008
+ ) -> Customer:
1009
+ """
1010
+ Retrieves a single customer by ID
1011
+
1012
+ Args:
1013
+ customer_id: The customer ID
1014
+ **kwargs: Additional parameters
1015
+
1016
+ Returns:
1017
+ Customer
1018
+ """
1019
+ params = {k: v for k, v in {
1020
+ "customer_id": customer_id,
1021
+ **kwargs
1022
+ }.items() if v is not None}
1023
+
1024
+ result = await self._connector.execute("customers", "get", params)
1025
+ return result
1026
+
1027
+
1028
+
1029
+ class OrdersQuery:
1030
+ """
1031
+ Query class for Orders entity operations.
1032
+ """
1033
+
1034
+ def __init__(self, connector: ShopifyConnector):
1035
+ """Initialize query with connector reference."""
1036
+ self._connector = connector
1037
+
1038
+ async def list(
1039
+ self,
1040
+ limit: int | None = None,
1041
+ since_id: int | None = None,
1042
+ created_at_min: str | None = None,
1043
+ created_at_max: str | None = None,
1044
+ updated_at_min: str | None = None,
1045
+ updated_at_max: str | None = None,
1046
+ status: str | None = None,
1047
+ financial_status: str | None = None,
1048
+ fulfillment_status: str | None = None,
1049
+ **kwargs
1050
+ ) -> OrdersListResult:
1051
+ """
1052
+ Returns a list of orders from the store
1053
+
1054
+ Args:
1055
+ limit: Maximum number of results to return (max 250)
1056
+ since_id: Restrict results to after the specified ID
1057
+ created_at_min: Show orders created after date (ISO 8601 format)
1058
+ created_at_max: Show orders created before date (ISO 8601 format)
1059
+ updated_at_min: Show orders last updated after date (ISO 8601 format)
1060
+ updated_at_max: Show orders last updated before date (ISO 8601 format)
1061
+ status: Filter orders by status
1062
+ financial_status: Filter orders by financial status
1063
+ fulfillment_status: Filter orders by fulfillment status
1064
+ **kwargs: Additional parameters
1065
+
1066
+ Returns:
1067
+ OrdersListResult
1068
+ """
1069
+ params = {k: v for k, v in {
1070
+ "limit": limit,
1071
+ "since_id": since_id,
1072
+ "created_at_min": created_at_min,
1073
+ "created_at_max": created_at_max,
1074
+ "updated_at_min": updated_at_min,
1075
+ "updated_at_max": updated_at_max,
1076
+ "status": status,
1077
+ "financial_status": financial_status,
1078
+ "fulfillment_status": fulfillment_status,
1079
+ **kwargs
1080
+ }.items() if v is not None}
1081
+
1082
+ result = await self._connector.execute("orders", "list", params)
1083
+ # Cast generic envelope to concrete typed result
1084
+ return OrdersListResult(
1085
+ data=result.data,
1086
+ meta=result.meta
1087
+ )
1088
+
1089
+
1090
+
1091
+ async def get(
1092
+ self,
1093
+ order_id: str,
1094
+ **kwargs
1095
+ ) -> Order:
1096
+ """
1097
+ Retrieves a single order by ID
1098
+
1099
+ Args:
1100
+ order_id: The order ID
1101
+ **kwargs: Additional parameters
1102
+
1103
+ Returns:
1104
+ Order
1105
+ """
1106
+ params = {k: v for k, v in {
1107
+ "order_id": order_id,
1108
+ **kwargs
1109
+ }.items() if v is not None}
1110
+
1111
+ result = await self._connector.execute("orders", "get", params)
1112
+ return result
1113
+
1114
+
1115
+
1116
+ class ProductsQuery:
1117
+ """
1118
+ Query class for Products entity operations.
1119
+ """
1120
+
1121
+ def __init__(self, connector: ShopifyConnector):
1122
+ """Initialize query with connector reference."""
1123
+ self._connector = connector
1124
+
1125
+ async def list(
1126
+ self,
1127
+ limit: int | None = None,
1128
+ since_id: int | None = None,
1129
+ created_at_min: str | None = None,
1130
+ created_at_max: str | None = None,
1131
+ updated_at_min: str | None = None,
1132
+ updated_at_max: str | None = None,
1133
+ status: str | None = None,
1134
+ product_type: str | None = None,
1135
+ vendor: str | None = None,
1136
+ collection_id: int | None = None,
1137
+ **kwargs
1138
+ ) -> ProductsListResult:
1139
+ """
1140
+ Returns a list of products from the store
1141
+
1142
+ Args:
1143
+ limit: Maximum number of results to return (max 250)
1144
+ since_id: Restrict results to after the specified ID
1145
+ created_at_min: Show products created after date (ISO 8601 format)
1146
+ created_at_max: Show products created before date (ISO 8601 format)
1147
+ updated_at_min: Show products last updated after date (ISO 8601 format)
1148
+ updated_at_max: Show products last updated before date (ISO 8601 format)
1149
+ status: Filter products by status
1150
+ product_type: Filter by product type
1151
+ vendor: Filter by vendor
1152
+ collection_id: Filter by collection ID
1153
+ **kwargs: Additional parameters
1154
+
1155
+ Returns:
1156
+ ProductsListResult
1157
+ """
1158
+ params = {k: v for k, v in {
1159
+ "limit": limit,
1160
+ "since_id": since_id,
1161
+ "created_at_min": created_at_min,
1162
+ "created_at_max": created_at_max,
1163
+ "updated_at_min": updated_at_min,
1164
+ "updated_at_max": updated_at_max,
1165
+ "status": status,
1166
+ "product_type": product_type,
1167
+ "vendor": vendor,
1168
+ "collection_id": collection_id,
1169
+ **kwargs
1170
+ }.items() if v is not None}
1171
+
1172
+ result = await self._connector.execute("products", "list", params)
1173
+ # Cast generic envelope to concrete typed result
1174
+ return ProductsListResult(
1175
+ data=result.data,
1176
+ meta=result.meta
1177
+ )
1178
+
1179
+
1180
+
1181
+ async def get(
1182
+ self,
1183
+ product_id: str,
1184
+ **kwargs
1185
+ ) -> Product:
1186
+ """
1187
+ Retrieves a single product by ID
1188
+
1189
+ Args:
1190
+ product_id: The product ID
1191
+ **kwargs: Additional parameters
1192
+
1193
+ Returns:
1194
+ Product
1195
+ """
1196
+ params = {k: v for k, v in {
1197
+ "product_id": product_id,
1198
+ **kwargs
1199
+ }.items() if v is not None}
1200
+
1201
+ result = await self._connector.execute("products", "get", params)
1202
+ return result
1203
+
1204
+
1205
+
1206
+ class ProductVariantsQuery:
1207
+ """
1208
+ Query class for ProductVariants entity operations.
1209
+ """
1210
+
1211
+ def __init__(self, connector: ShopifyConnector):
1212
+ """Initialize query with connector reference."""
1213
+ self._connector = connector
1214
+
1215
+ async def list(
1216
+ self,
1217
+ product_id: str,
1218
+ limit: int | None = None,
1219
+ since_id: int | None = None,
1220
+ **kwargs
1221
+ ) -> ProductVariantsListResult:
1222
+ """
1223
+ Returns a list of variants for a product
1224
+
1225
+ Args:
1226
+ product_id: The product ID
1227
+ limit: Maximum number of results to return (max 250)
1228
+ since_id: Restrict results to after the specified ID
1229
+ **kwargs: Additional parameters
1230
+
1231
+ Returns:
1232
+ ProductVariantsListResult
1233
+ """
1234
+ params = {k: v for k, v in {
1235
+ "product_id": product_id,
1236
+ "limit": limit,
1237
+ "since_id": since_id,
1238
+ **kwargs
1239
+ }.items() if v is not None}
1240
+
1241
+ result = await self._connector.execute("product_variants", "list", params)
1242
+ # Cast generic envelope to concrete typed result
1243
+ return ProductVariantsListResult(
1244
+ data=result.data,
1245
+ meta=result.meta
1246
+ )
1247
+
1248
+
1249
+
1250
+ async def get(
1251
+ self,
1252
+ variant_id: str,
1253
+ **kwargs
1254
+ ) -> ProductVariant:
1255
+ """
1256
+ Retrieves a single product variant by ID
1257
+
1258
+ Args:
1259
+ variant_id: The variant ID
1260
+ **kwargs: Additional parameters
1261
+
1262
+ Returns:
1263
+ ProductVariant
1264
+ """
1265
+ params = {k: v for k, v in {
1266
+ "variant_id": variant_id,
1267
+ **kwargs
1268
+ }.items() if v is not None}
1269
+
1270
+ result = await self._connector.execute("product_variants", "get", params)
1271
+ return result
1272
+
1273
+
1274
+
1275
+ class ProductImagesQuery:
1276
+ """
1277
+ Query class for ProductImages entity operations.
1278
+ """
1279
+
1280
+ def __init__(self, connector: ShopifyConnector):
1281
+ """Initialize query with connector reference."""
1282
+ self._connector = connector
1283
+
1284
+ async def list(
1285
+ self,
1286
+ product_id: str,
1287
+ since_id: int | None = None,
1288
+ **kwargs
1289
+ ) -> ProductImagesListResult:
1290
+ """
1291
+ Returns a list of images for a product
1292
+
1293
+ Args:
1294
+ product_id: The product ID
1295
+ since_id: Restrict results to after the specified ID
1296
+ **kwargs: Additional parameters
1297
+
1298
+ Returns:
1299
+ ProductImagesListResult
1300
+ """
1301
+ params = {k: v for k, v in {
1302
+ "product_id": product_id,
1303
+ "since_id": since_id,
1304
+ **kwargs
1305
+ }.items() if v is not None}
1306
+
1307
+ result = await self._connector.execute("product_images", "list", params)
1308
+ # Cast generic envelope to concrete typed result
1309
+ return ProductImagesListResult(
1310
+ data=result.data,
1311
+ meta=result.meta
1312
+ )
1313
+
1314
+
1315
+
1316
+ async def get(
1317
+ self,
1318
+ product_id: str,
1319
+ image_id: str,
1320
+ **kwargs
1321
+ ) -> ProductImage:
1322
+ """
1323
+ Retrieves a single product image by ID
1324
+
1325
+ Args:
1326
+ product_id: The product ID
1327
+ image_id: The image ID
1328
+ **kwargs: Additional parameters
1329
+
1330
+ Returns:
1331
+ ProductImage
1332
+ """
1333
+ params = {k: v for k, v in {
1334
+ "product_id": product_id,
1335
+ "image_id": image_id,
1336
+ **kwargs
1337
+ }.items() if v is not None}
1338
+
1339
+ result = await self._connector.execute("product_images", "get", params)
1340
+ return result
1341
+
1342
+
1343
+
1344
+ class AbandonedCheckoutsQuery:
1345
+ """
1346
+ Query class for AbandonedCheckouts entity operations.
1347
+ """
1348
+
1349
+ def __init__(self, connector: ShopifyConnector):
1350
+ """Initialize query with connector reference."""
1351
+ self._connector = connector
1352
+
1353
+ async def list(
1354
+ self,
1355
+ limit: int | None = None,
1356
+ since_id: int | None = None,
1357
+ created_at_min: str | None = None,
1358
+ created_at_max: str | None = None,
1359
+ updated_at_min: str | None = None,
1360
+ updated_at_max: str | None = None,
1361
+ status: str | None = None,
1362
+ **kwargs
1363
+ ) -> AbandonedCheckoutsListResult:
1364
+ """
1365
+ Returns a list of abandoned checkouts
1366
+
1367
+ Args:
1368
+ limit: Maximum number of results to return (max 250)
1369
+ since_id: Restrict results to after the specified ID
1370
+ created_at_min: Show checkouts created after date (ISO 8601 format)
1371
+ created_at_max: Show checkouts created before date (ISO 8601 format)
1372
+ updated_at_min: Show checkouts last updated after date (ISO 8601 format)
1373
+ updated_at_max: Show checkouts last updated before date (ISO 8601 format)
1374
+ status: Filter checkouts by status
1375
+ **kwargs: Additional parameters
1376
+
1377
+ Returns:
1378
+ AbandonedCheckoutsListResult
1379
+ """
1380
+ params = {k: v for k, v in {
1381
+ "limit": limit,
1382
+ "since_id": since_id,
1383
+ "created_at_min": created_at_min,
1384
+ "created_at_max": created_at_max,
1385
+ "updated_at_min": updated_at_min,
1386
+ "updated_at_max": updated_at_max,
1387
+ "status": status,
1388
+ **kwargs
1389
+ }.items() if v is not None}
1390
+
1391
+ result = await self._connector.execute("abandoned_checkouts", "list", params)
1392
+ # Cast generic envelope to concrete typed result
1393
+ return AbandonedCheckoutsListResult(
1394
+ data=result.data,
1395
+ meta=result.meta
1396
+ )
1397
+
1398
+
1399
+
1400
+ class LocationsQuery:
1401
+ """
1402
+ Query class for Locations entity operations.
1403
+ """
1404
+
1405
+ def __init__(self, connector: ShopifyConnector):
1406
+ """Initialize query with connector reference."""
1407
+ self._connector = connector
1408
+
1409
+ async def list(
1410
+ self,
1411
+ **kwargs
1412
+ ) -> LocationsListResult:
1413
+ """
1414
+ Returns a list of locations for the store
1415
+
1416
+ Returns:
1417
+ LocationsListResult
1418
+ """
1419
+ params = {k: v for k, v in {
1420
+ **kwargs
1421
+ }.items() if v is not None}
1422
+
1423
+ result = await self._connector.execute("locations", "list", params)
1424
+ # Cast generic envelope to concrete typed result
1425
+ return LocationsListResult(
1426
+ data=result.data,
1427
+ meta=result.meta
1428
+ )
1429
+
1430
+
1431
+
1432
+ async def get(
1433
+ self,
1434
+ location_id: str,
1435
+ **kwargs
1436
+ ) -> Location:
1437
+ """
1438
+ Retrieves a single location by ID
1439
+
1440
+ Args:
1441
+ location_id: The location ID
1442
+ **kwargs: Additional parameters
1443
+
1444
+ Returns:
1445
+ Location
1446
+ """
1447
+ params = {k: v for k, v in {
1448
+ "location_id": location_id,
1449
+ **kwargs
1450
+ }.items() if v is not None}
1451
+
1452
+ result = await self._connector.execute("locations", "get", params)
1453
+ return result
1454
+
1455
+
1456
+
1457
+ class InventoryLevelsQuery:
1458
+ """
1459
+ Query class for InventoryLevels entity operations.
1460
+ """
1461
+
1462
+ def __init__(self, connector: ShopifyConnector):
1463
+ """Initialize query with connector reference."""
1464
+ self._connector = connector
1465
+
1466
+ async def list(
1467
+ self,
1468
+ location_id: str,
1469
+ limit: int | None = None,
1470
+ **kwargs
1471
+ ) -> InventoryLevelsListResult:
1472
+ """
1473
+ Returns a list of inventory levels for a specific location
1474
+
1475
+ Args:
1476
+ location_id: The location ID
1477
+ limit: Maximum number of results to return (max 250)
1478
+ **kwargs: Additional parameters
1479
+
1480
+ Returns:
1481
+ InventoryLevelsListResult
1482
+ """
1483
+ params = {k: v for k, v in {
1484
+ "location_id": location_id,
1485
+ "limit": limit,
1486
+ **kwargs
1487
+ }.items() if v is not None}
1488
+
1489
+ result = await self._connector.execute("inventory_levels", "list", params)
1490
+ # Cast generic envelope to concrete typed result
1491
+ return InventoryLevelsListResult(
1492
+ data=result.data,
1493
+ meta=result.meta
1494
+ )
1495
+
1496
+
1497
+
1498
+ class InventoryItemsQuery:
1499
+ """
1500
+ Query class for InventoryItems entity operations.
1501
+ """
1502
+
1503
+ def __init__(self, connector: ShopifyConnector):
1504
+ """Initialize query with connector reference."""
1505
+ self._connector = connector
1506
+
1507
+ async def list(
1508
+ self,
1509
+ ids: str,
1510
+ limit: int | None = None,
1511
+ **kwargs
1512
+ ) -> InventoryItemsListResult:
1513
+ """
1514
+ Returns a list of inventory items
1515
+
1516
+ Args:
1517
+ ids: Comma-separated list of inventory item IDs
1518
+ limit: Maximum number of results to return (max 250)
1519
+ **kwargs: Additional parameters
1520
+
1521
+ Returns:
1522
+ InventoryItemsListResult
1523
+ """
1524
+ params = {k: v for k, v in {
1525
+ "ids": ids,
1526
+ "limit": limit,
1527
+ **kwargs
1528
+ }.items() if v is not None}
1529
+
1530
+ result = await self._connector.execute("inventory_items", "list", params)
1531
+ # Cast generic envelope to concrete typed result
1532
+ return InventoryItemsListResult(
1533
+ data=result.data,
1534
+ meta=result.meta
1535
+ )
1536
+
1537
+
1538
+
1539
+ async def get(
1540
+ self,
1541
+ inventory_item_id: str,
1542
+ **kwargs
1543
+ ) -> InventoryItem:
1544
+ """
1545
+ Retrieves a single inventory item by ID
1546
+
1547
+ Args:
1548
+ inventory_item_id: The inventory item ID
1549
+ **kwargs: Additional parameters
1550
+
1551
+ Returns:
1552
+ InventoryItem
1553
+ """
1554
+ params = {k: v for k, v in {
1555
+ "inventory_item_id": inventory_item_id,
1556
+ **kwargs
1557
+ }.items() if v is not None}
1558
+
1559
+ result = await self._connector.execute("inventory_items", "get", params)
1560
+ return result
1561
+
1562
+
1563
+
1564
+ class ShopQuery:
1565
+ """
1566
+ Query class for Shop entity operations.
1567
+ """
1568
+
1569
+ def __init__(self, connector: ShopifyConnector):
1570
+ """Initialize query with connector reference."""
1571
+ self._connector = connector
1572
+
1573
+ async def get(
1574
+ self,
1575
+ **kwargs
1576
+ ) -> Shop:
1577
+ """
1578
+ Retrieves the shop's configuration
1579
+
1580
+ Returns:
1581
+ Shop
1582
+ """
1583
+ params = {k: v for k, v in {
1584
+ **kwargs
1585
+ }.items() if v is not None}
1586
+
1587
+ result = await self._connector.execute("shop", "get", params)
1588
+ return result
1589
+
1590
+
1591
+
1592
+ class PriceRulesQuery:
1593
+ """
1594
+ Query class for PriceRules entity operations.
1595
+ """
1596
+
1597
+ def __init__(self, connector: ShopifyConnector):
1598
+ """Initialize query with connector reference."""
1599
+ self._connector = connector
1600
+
1601
+ async def list(
1602
+ self,
1603
+ limit: int | None = None,
1604
+ since_id: int | None = None,
1605
+ created_at_min: str | None = None,
1606
+ created_at_max: str | None = None,
1607
+ updated_at_min: str | None = None,
1608
+ updated_at_max: str | None = None,
1609
+ **kwargs
1610
+ ) -> PriceRulesListResult:
1611
+ """
1612
+ Returns a list of price rules
1613
+
1614
+ Args:
1615
+ limit: Maximum number of results to return (max 250)
1616
+ since_id: Restrict results to after the specified ID
1617
+ created_at_min: Show price rules created after date (ISO 8601 format)
1618
+ created_at_max: Show price rules created before date (ISO 8601 format)
1619
+ updated_at_min: Show price rules last updated after date (ISO 8601 format)
1620
+ updated_at_max: Show price rules last updated before date (ISO 8601 format)
1621
+ **kwargs: Additional parameters
1622
+
1623
+ Returns:
1624
+ PriceRulesListResult
1625
+ """
1626
+ params = {k: v for k, v in {
1627
+ "limit": limit,
1628
+ "since_id": since_id,
1629
+ "created_at_min": created_at_min,
1630
+ "created_at_max": created_at_max,
1631
+ "updated_at_min": updated_at_min,
1632
+ "updated_at_max": updated_at_max,
1633
+ **kwargs
1634
+ }.items() if v is not None}
1635
+
1636
+ result = await self._connector.execute("price_rules", "list", params)
1637
+ # Cast generic envelope to concrete typed result
1638
+ return PriceRulesListResult(
1639
+ data=result.data,
1640
+ meta=result.meta
1641
+ )
1642
+
1643
+
1644
+
1645
+ async def get(
1646
+ self,
1647
+ price_rule_id: str,
1648
+ **kwargs
1649
+ ) -> PriceRule:
1650
+ """
1651
+ Retrieves a single price rule by ID
1652
+
1653
+ Args:
1654
+ price_rule_id: The price rule ID
1655
+ **kwargs: Additional parameters
1656
+
1657
+ Returns:
1658
+ PriceRule
1659
+ """
1660
+ params = {k: v for k, v in {
1661
+ "price_rule_id": price_rule_id,
1662
+ **kwargs
1663
+ }.items() if v is not None}
1664
+
1665
+ result = await self._connector.execute("price_rules", "get", params)
1666
+ return result
1667
+
1668
+
1669
+
1670
+ class DiscountCodesQuery:
1671
+ """
1672
+ Query class for DiscountCodes entity operations.
1673
+ """
1674
+
1675
+ def __init__(self, connector: ShopifyConnector):
1676
+ """Initialize query with connector reference."""
1677
+ self._connector = connector
1678
+
1679
+ async def list(
1680
+ self,
1681
+ price_rule_id: str,
1682
+ limit: int | None = None,
1683
+ **kwargs
1684
+ ) -> DiscountCodesListResult:
1685
+ """
1686
+ Returns a list of discount codes for a price rule
1687
+
1688
+ Args:
1689
+ price_rule_id: The price rule ID
1690
+ limit: Maximum number of results to return (max 250)
1691
+ **kwargs: Additional parameters
1692
+
1693
+ Returns:
1694
+ DiscountCodesListResult
1695
+ """
1696
+ params = {k: v for k, v in {
1697
+ "price_rule_id": price_rule_id,
1698
+ "limit": limit,
1699
+ **kwargs
1700
+ }.items() if v is not None}
1701
+
1702
+ result = await self._connector.execute("discount_codes", "list", params)
1703
+ # Cast generic envelope to concrete typed result
1704
+ return DiscountCodesListResult(
1705
+ data=result.data,
1706
+ meta=result.meta
1707
+ )
1708
+
1709
+
1710
+
1711
+ async def get(
1712
+ self,
1713
+ price_rule_id: str,
1714
+ discount_code_id: str,
1715
+ **kwargs
1716
+ ) -> DiscountCode:
1717
+ """
1718
+ Retrieves a single discount code by ID
1719
+
1720
+ Args:
1721
+ price_rule_id: The price rule ID
1722
+ discount_code_id: The discount code ID
1723
+ **kwargs: Additional parameters
1724
+
1725
+ Returns:
1726
+ DiscountCode
1727
+ """
1728
+ params = {k: v for k, v in {
1729
+ "price_rule_id": price_rule_id,
1730
+ "discount_code_id": discount_code_id,
1731
+ **kwargs
1732
+ }.items() if v is not None}
1733
+
1734
+ result = await self._connector.execute("discount_codes", "get", params)
1735
+ return result
1736
+
1737
+
1738
+
1739
+ class CustomCollectionsQuery:
1740
+ """
1741
+ Query class for CustomCollections entity operations.
1742
+ """
1743
+
1744
+ def __init__(self, connector: ShopifyConnector):
1745
+ """Initialize query with connector reference."""
1746
+ self._connector = connector
1747
+
1748
+ async def list(
1749
+ self,
1750
+ limit: int | None = None,
1751
+ since_id: int | None = None,
1752
+ title: str | None = None,
1753
+ product_id: int | None = None,
1754
+ updated_at_min: str | None = None,
1755
+ updated_at_max: str | None = None,
1756
+ **kwargs
1757
+ ) -> CustomCollectionsListResult:
1758
+ """
1759
+ Returns a list of custom collections
1760
+
1761
+ Args:
1762
+ limit: Maximum number of results to return (max 250)
1763
+ since_id: Restrict results to after the specified ID
1764
+ title: Filter by collection title
1765
+ product_id: Filter by product ID
1766
+ updated_at_min: Show collections last updated after date (ISO 8601 format)
1767
+ updated_at_max: Show collections last updated before date (ISO 8601 format)
1768
+ **kwargs: Additional parameters
1769
+
1770
+ Returns:
1771
+ CustomCollectionsListResult
1772
+ """
1773
+ params = {k: v for k, v in {
1774
+ "limit": limit,
1775
+ "since_id": since_id,
1776
+ "title": title,
1777
+ "product_id": product_id,
1778
+ "updated_at_min": updated_at_min,
1779
+ "updated_at_max": updated_at_max,
1780
+ **kwargs
1781
+ }.items() if v is not None}
1782
+
1783
+ result = await self._connector.execute("custom_collections", "list", params)
1784
+ # Cast generic envelope to concrete typed result
1785
+ return CustomCollectionsListResult(
1786
+ data=result.data,
1787
+ meta=result.meta
1788
+ )
1789
+
1790
+
1791
+
1792
+ async def get(
1793
+ self,
1794
+ collection_id: str,
1795
+ **kwargs
1796
+ ) -> CustomCollection:
1797
+ """
1798
+ Retrieves a single custom collection by ID
1799
+
1800
+ Args:
1801
+ collection_id: The collection ID
1802
+ **kwargs: Additional parameters
1803
+
1804
+ Returns:
1805
+ CustomCollection
1806
+ """
1807
+ params = {k: v for k, v in {
1808
+ "collection_id": collection_id,
1809
+ **kwargs
1810
+ }.items() if v is not None}
1811
+
1812
+ result = await self._connector.execute("custom_collections", "get", params)
1813
+ return result
1814
+
1815
+
1816
+
1817
+ class SmartCollectionsQuery:
1818
+ """
1819
+ Query class for SmartCollections entity operations.
1820
+ """
1821
+
1822
+ def __init__(self, connector: ShopifyConnector):
1823
+ """Initialize query with connector reference."""
1824
+ self._connector = connector
1825
+
1826
+ async def list(
1827
+ self,
1828
+ limit: int | None = None,
1829
+ since_id: int | None = None,
1830
+ title: str | None = None,
1831
+ product_id: int | None = None,
1832
+ updated_at_min: str | None = None,
1833
+ updated_at_max: str | None = None,
1834
+ **kwargs
1835
+ ) -> SmartCollectionsListResult:
1836
+ """
1837
+ Returns a list of smart collections
1838
+
1839
+ Args:
1840
+ limit: Maximum number of results to return (max 250)
1841
+ since_id: Restrict results to after the specified ID
1842
+ title: Filter by collection title
1843
+ product_id: Filter by product ID
1844
+ updated_at_min: Show collections last updated after date (ISO 8601 format)
1845
+ updated_at_max: Show collections last updated before date (ISO 8601 format)
1846
+ **kwargs: Additional parameters
1847
+
1848
+ Returns:
1849
+ SmartCollectionsListResult
1850
+ """
1851
+ params = {k: v for k, v in {
1852
+ "limit": limit,
1853
+ "since_id": since_id,
1854
+ "title": title,
1855
+ "product_id": product_id,
1856
+ "updated_at_min": updated_at_min,
1857
+ "updated_at_max": updated_at_max,
1858
+ **kwargs
1859
+ }.items() if v is not None}
1860
+
1861
+ result = await self._connector.execute("smart_collections", "list", params)
1862
+ # Cast generic envelope to concrete typed result
1863
+ return SmartCollectionsListResult(
1864
+ data=result.data,
1865
+ meta=result.meta
1866
+ )
1867
+
1868
+
1869
+
1870
+ async def get(
1871
+ self,
1872
+ collection_id: str,
1873
+ **kwargs
1874
+ ) -> SmartCollection:
1875
+ """
1876
+ Retrieves a single smart collection by ID
1877
+
1878
+ Args:
1879
+ collection_id: The collection ID
1880
+ **kwargs: Additional parameters
1881
+
1882
+ Returns:
1883
+ SmartCollection
1884
+ """
1885
+ params = {k: v for k, v in {
1886
+ "collection_id": collection_id,
1887
+ **kwargs
1888
+ }.items() if v is not None}
1889
+
1890
+ result = await self._connector.execute("smart_collections", "get", params)
1891
+ return result
1892
+
1893
+
1894
+
1895
+ class CollectsQuery:
1896
+ """
1897
+ Query class for Collects entity operations.
1898
+ """
1899
+
1900
+ def __init__(self, connector: ShopifyConnector):
1901
+ """Initialize query with connector reference."""
1902
+ self._connector = connector
1903
+
1904
+ async def list(
1905
+ self,
1906
+ limit: int | None = None,
1907
+ since_id: int | None = None,
1908
+ collection_id: int | None = None,
1909
+ product_id: int | None = None,
1910
+ **kwargs
1911
+ ) -> CollectsListResult:
1912
+ """
1913
+ Returns a list of collects (links between products and collections)
1914
+
1915
+ Args:
1916
+ limit: Maximum number of results to return (max 250)
1917
+ since_id: Restrict results to after the specified ID
1918
+ collection_id: Filter by collection ID
1919
+ product_id: Filter by product ID
1920
+ **kwargs: Additional parameters
1921
+
1922
+ Returns:
1923
+ CollectsListResult
1924
+ """
1925
+ params = {k: v for k, v in {
1926
+ "limit": limit,
1927
+ "since_id": since_id,
1928
+ "collection_id": collection_id,
1929
+ "product_id": product_id,
1930
+ **kwargs
1931
+ }.items() if v is not None}
1932
+
1933
+ result = await self._connector.execute("collects", "list", params)
1934
+ # Cast generic envelope to concrete typed result
1935
+ return CollectsListResult(
1936
+ data=result.data,
1937
+ meta=result.meta
1938
+ )
1939
+
1940
+
1941
+
1942
+ async def get(
1943
+ self,
1944
+ collect_id: str,
1945
+ **kwargs
1946
+ ) -> Collect:
1947
+ """
1948
+ Retrieves a single collect by ID
1949
+
1950
+ Args:
1951
+ collect_id: The collect ID
1952
+ **kwargs: Additional parameters
1953
+
1954
+ Returns:
1955
+ Collect
1956
+ """
1957
+ params = {k: v for k, v in {
1958
+ "collect_id": collect_id,
1959
+ **kwargs
1960
+ }.items() if v is not None}
1961
+
1962
+ result = await self._connector.execute("collects", "get", params)
1963
+ return result
1964
+
1965
+
1966
+
1967
+ class DraftOrdersQuery:
1968
+ """
1969
+ Query class for DraftOrders entity operations.
1970
+ """
1971
+
1972
+ def __init__(self, connector: ShopifyConnector):
1973
+ """Initialize query with connector reference."""
1974
+ self._connector = connector
1975
+
1976
+ async def list(
1977
+ self,
1978
+ limit: int | None = None,
1979
+ since_id: int | None = None,
1980
+ status: str | None = None,
1981
+ updated_at_min: str | None = None,
1982
+ updated_at_max: str | None = None,
1983
+ **kwargs
1984
+ ) -> DraftOrdersListResult:
1985
+ """
1986
+ Returns a list of draft orders
1987
+
1988
+ Args:
1989
+ limit: Maximum number of results to return (max 250)
1990
+ since_id: Restrict results to after the specified ID
1991
+ status: Filter draft orders by status
1992
+ updated_at_min: Show draft orders last updated after date (ISO 8601 format)
1993
+ updated_at_max: Show draft orders last updated before date (ISO 8601 format)
1994
+ **kwargs: Additional parameters
1995
+
1996
+ Returns:
1997
+ DraftOrdersListResult
1998
+ """
1999
+ params = {k: v for k, v in {
2000
+ "limit": limit,
2001
+ "since_id": since_id,
2002
+ "status": status,
2003
+ "updated_at_min": updated_at_min,
2004
+ "updated_at_max": updated_at_max,
2005
+ **kwargs
2006
+ }.items() if v is not None}
2007
+
2008
+ result = await self._connector.execute("draft_orders", "list", params)
2009
+ # Cast generic envelope to concrete typed result
2010
+ return DraftOrdersListResult(
2011
+ data=result.data,
2012
+ meta=result.meta
2013
+ )
2014
+
2015
+
2016
+
2017
+ async def get(
2018
+ self,
2019
+ draft_order_id: str,
2020
+ **kwargs
2021
+ ) -> DraftOrder:
2022
+ """
2023
+ Retrieves a single draft order by ID
2024
+
2025
+ Args:
2026
+ draft_order_id: The draft order ID
2027
+ **kwargs: Additional parameters
2028
+
2029
+ Returns:
2030
+ DraftOrder
2031
+ """
2032
+ params = {k: v for k, v in {
2033
+ "draft_order_id": draft_order_id,
2034
+ **kwargs
2035
+ }.items() if v is not None}
2036
+
2037
+ result = await self._connector.execute("draft_orders", "get", params)
2038
+ return result
2039
+
2040
+
2041
+
2042
+ class FulfillmentsQuery:
2043
+ """
2044
+ Query class for Fulfillments entity operations.
2045
+ """
2046
+
2047
+ def __init__(self, connector: ShopifyConnector):
2048
+ """Initialize query with connector reference."""
2049
+ self._connector = connector
2050
+
2051
+ async def list(
2052
+ self,
2053
+ order_id: str,
2054
+ limit: int | None = None,
2055
+ since_id: int | None = None,
2056
+ created_at_min: str | None = None,
2057
+ created_at_max: str | None = None,
2058
+ updated_at_min: str | None = None,
2059
+ updated_at_max: str | None = None,
2060
+ **kwargs
2061
+ ) -> FulfillmentsListResult:
2062
+ """
2063
+ Returns a list of fulfillments for an order
2064
+
2065
+ Args:
2066
+ order_id: The order ID
2067
+ limit: Maximum number of results to return (max 250)
2068
+ since_id: Restrict results to after the specified ID
2069
+ created_at_min: Show fulfillments created after date (ISO 8601 format)
2070
+ created_at_max: Show fulfillments created before date (ISO 8601 format)
2071
+ updated_at_min: Show fulfillments last updated after date (ISO 8601 format)
2072
+ updated_at_max: Show fulfillments last updated before date (ISO 8601 format)
2073
+ **kwargs: Additional parameters
2074
+
2075
+ Returns:
2076
+ FulfillmentsListResult
2077
+ """
2078
+ params = {k: v for k, v in {
2079
+ "order_id": order_id,
2080
+ "limit": limit,
2081
+ "since_id": since_id,
2082
+ "created_at_min": created_at_min,
2083
+ "created_at_max": created_at_max,
2084
+ "updated_at_min": updated_at_min,
2085
+ "updated_at_max": updated_at_max,
2086
+ **kwargs
2087
+ }.items() if v is not None}
2088
+
2089
+ result = await self._connector.execute("fulfillments", "list", params)
2090
+ # Cast generic envelope to concrete typed result
2091
+ return FulfillmentsListResult(
2092
+ data=result.data,
2093
+ meta=result.meta
2094
+ )
2095
+
2096
+
2097
+
2098
+ async def get(
2099
+ self,
2100
+ order_id: str,
2101
+ fulfillment_id: str,
2102
+ **kwargs
2103
+ ) -> Fulfillment:
2104
+ """
2105
+ Retrieves a single fulfillment by ID
2106
+
2107
+ Args:
2108
+ order_id: The order ID
2109
+ fulfillment_id: The fulfillment ID
2110
+ **kwargs: Additional parameters
2111
+
2112
+ Returns:
2113
+ Fulfillment
2114
+ """
2115
+ params = {k: v for k, v in {
2116
+ "order_id": order_id,
2117
+ "fulfillment_id": fulfillment_id,
2118
+ **kwargs
2119
+ }.items() if v is not None}
2120
+
2121
+ result = await self._connector.execute("fulfillments", "get", params)
2122
+ return result
2123
+
2124
+
2125
+
2126
+ class OrderRefundsQuery:
2127
+ """
2128
+ Query class for OrderRefunds entity operations.
2129
+ """
2130
+
2131
+ def __init__(self, connector: ShopifyConnector):
2132
+ """Initialize query with connector reference."""
2133
+ self._connector = connector
2134
+
2135
+ async def list(
2136
+ self,
2137
+ order_id: str,
2138
+ limit: int | None = None,
2139
+ **kwargs
2140
+ ) -> OrderRefundsListResult:
2141
+ """
2142
+ Returns a list of refunds for an order
2143
+
2144
+ Args:
2145
+ order_id: The order ID
2146
+ limit: Maximum number of results to return (max 250)
2147
+ **kwargs: Additional parameters
2148
+
2149
+ Returns:
2150
+ OrderRefundsListResult
2151
+ """
2152
+ params = {k: v for k, v in {
2153
+ "order_id": order_id,
2154
+ "limit": limit,
2155
+ **kwargs
2156
+ }.items() if v is not None}
2157
+
2158
+ result = await self._connector.execute("order_refunds", "list", params)
2159
+ # Cast generic envelope to concrete typed result
2160
+ return OrderRefundsListResult(
2161
+ data=result.data,
2162
+ meta=result.meta
2163
+ )
2164
+
2165
+
2166
+
2167
+ async def get(
2168
+ self,
2169
+ order_id: str,
2170
+ refund_id: str,
2171
+ **kwargs
2172
+ ) -> Refund:
2173
+ """
2174
+ Retrieves a single refund by ID
2175
+
2176
+ Args:
2177
+ order_id: The order ID
2178
+ refund_id: The refund ID
2179
+ **kwargs: Additional parameters
2180
+
2181
+ Returns:
2182
+ Refund
2183
+ """
2184
+ params = {k: v for k, v in {
2185
+ "order_id": order_id,
2186
+ "refund_id": refund_id,
2187
+ **kwargs
2188
+ }.items() if v is not None}
2189
+
2190
+ result = await self._connector.execute("order_refunds", "get", params)
2191
+ return result
2192
+
2193
+
2194
+
2195
+ class TransactionsQuery:
2196
+ """
2197
+ Query class for Transactions entity operations.
2198
+ """
2199
+
2200
+ def __init__(self, connector: ShopifyConnector):
2201
+ """Initialize query with connector reference."""
2202
+ self._connector = connector
2203
+
2204
+ async def list(
2205
+ self,
2206
+ order_id: str,
2207
+ since_id: int | None = None,
2208
+ **kwargs
2209
+ ) -> TransactionsListResult:
2210
+ """
2211
+ Returns a list of transactions for an order
2212
+
2213
+ Args:
2214
+ order_id: The order ID
2215
+ since_id: Restrict results to after the specified ID
2216
+ **kwargs: Additional parameters
2217
+
2218
+ Returns:
2219
+ TransactionsListResult
2220
+ """
2221
+ params = {k: v for k, v in {
2222
+ "order_id": order_id,
2223
+ "since_id": since_id,
2224
+ **kwargs
2225
+ }.items() if v is not None}
2226
+
2227
+ result = await self._connector.execute("transactions", "list", params)
2228
+ # Cast generic envelope to concrete typed result
2229
+ return TransactionsListResult(
2230
+ data=result.data,
2231
+ meta=result.meta
2232
+ )
2233
+
2234
+
2235
+
2236
+ async def get(
2237
+ self,
2238
+ order_id: str,
2239
+ transaction_id: str,
2240
+ **kwargs
2241
+ ) -> Transaction:
2242
+ """
2243
+ Retrieves a single transaction by ID
2244
+
2245
+ Args:
2246
+ order_id: The order ID
2247
+ transaction_id: The transaction ID
2248
+ **kwargs: Additional parameters
2249
+
2250
+ Returns:
2251
+ Transaction
2252
+ """
2253
+ params = {k: v for k, v in {
2254
+ "order_id": order_id,
2255
+ "transaction_id": transaction_id,
2256
+ **kwargs
2257
+ }.items() if v is not None}
2258
+
2259
+ result = await self._connector.execute("transactions", "get", params)
2260
+ return result
2261
+
2262
+
2263
+
2264
+ class TenderTransactionsQuery:
2265
+ """
2266
+ Query class for TenderTransactions entity operations.
2267
+ """
2268
+
2269
+ def __init__(self, connector: ShopifyConnector):
2270
+ """Initialize query with connector reference."""
2271
+ self._connector = connector
2272
+
2273
+ async def list(
2274
+ self,
2275
+ limit: int | None = None,
2276
+ since_id: int | None = None,
2277
+ processed_at_min: str | None = None,
2278
+ processed_at_max: str | None = None,
2279
+ order: str | None = None,
2280
+ **kwargs
2281
+ ) -> TenderTransactionsListResult:
2282
+ """
2283
+ Returns a list of tender transactions
2284
+
2285
+ Args:
2286
+ limit: Maximum number of results to return (max 250)
2287
+ since_id: Restrict results to after the specified ID
2288
+ processed_at_min: Show tender transactions processed after date (ISO 8601 format)
2289
+ processed_at_max: Show tender transactions processed before date (ISO 8601 format)
2290
+ order: Order of results
2291
+ **kwargs: Additional parameters
2292
+
2293
+ Returns:
2294
+ TenderTransactionsListResult
2295
+ """
2296
+ params = {k: v for k, v in {
2297
+ "limit": limit,
2298
+ "since_id": since_id,
2299
+ "processed_at_min": processed_at_min,
2300
+ "processed_at_max": processed_at_max,
2301
+ "order": order,
2302
+ **kwargs
2303
+ }.items() if v is not None}
2304
+
2305
+ result = await self._connector.execute("tender_transactions", "list", params)
2306
+ # Cast generic envelope to concrete typed result
2307
+ return TenderTransactionsListResult(
2308
+ data=result.data,
2309
+ meta=result.meta
2310
+ )
2311
+
2312
+
2313
+
2314
+ class CountriesQuery:
2315
+ """
2316
+ Query class for Countries entity operations.
2317
+ """
2318
+
2319
+ def __init__(self, connector: ShopifyConnector):
2320
+ """Initialize query with connector reference."""
2321
+ self._connector = connector
2322
+
2323
+ async def list(
2324
+ self,
2325
+ since_id: int | None = None,
2326
+ **kwargs
2327
+ ) -> CountriesListResult:
2328
+ """
2329
+ Returns a list of countries
2330
+
2331
+ Args:
2332
+ since_id: Restrict results to after the specified ID
2333
+ **kwargs: Additional parameters
2334
+
2335
+ Returns:
2336
+ CountriesListResult
2337
+ """
2338
+ params = {k: v for k, v in {
2339
+ "since_id": since_id,
2340
+ **kwargs
2341
+ }.items() if v is not None}
2342
+
2343
+ result = await self._connector.execute("countries", "list", params)
2344
+ # Cast generic envelope to concrete typed result
2345
+ return CountriesListResult(
2346
+ data=result.data,
2347
+ meta=result.meta
2348
+ )
2349
+
2350
+
2351
+
2352
+ async def get(
2353
+ self,
2354
+ country_id: str,
2355
+ **kwargs
2356
+ ) -> Country:
2357
+ """
2358
+ Retrieves a single country by ID
2359
+
2360
+ Args:
2361
+ country_id: The country ID
2362
+ **kwargs: Additional parameters
2363
+
2364
+ Returns:
2365
+ Country
2366
+ """
2367
+ params = {k: v for k, v in {
2368
+ "country_id": country_id,
2369
+ **kwargs
2370
+ }.items() if v is not None}
2371
+
2372
+ result = await self._connector.execute("countries", "get", params)
2373
+ return result
2374
+
2375
+
2376
+
2377
+ class MetafieldShopsQuery:
2378
+ """
2379
+ Query class for MetafieldShops entity operations.
2380
+ """
2381
+
2382
+ def __init__(self, connector: ShopifyConnector):
2383
+ """Initialize query with connector reference."""
2384
+ self._connector = connector
2385
+
2386
+ async def list(
2387
+ self,
2388
+ limit: int | None = None,
2389
+ since_id: int | None = None,
2390
+ namespace: str | None = None,
2391
+ key: str | None = None,
2392
+ type: str | None = None,
2393
+ **kwargs
2394
+ ) -> MetafieldShopsListResult:
2395
+ """
2396
+ Returns a list of metafields for the shop
2397
+
2398
+ Args:
2399
+ limit: Maximum number of results to return (max 250)
2400
+ since_id: Restrict results to after the specified ID
2401
+ namespace: Filter by namespace
2402
+ key: Filter by key
2403
+ type: Filter by type
2404
+ **kwargs: Additional parameters
2405
+
2406
+ Returns:
2407
+ MetafieldShopsListResult
2408
+ """
2409
+ params = {k: v for k, v in {
2410
+ "limit": limit,
2411
+ "since_id": since_id,
2412
+ "namespace": namespace,
2413
+ "key": key,
2414
+ "type": type,
2415
+ **kwargs
2416
+ }.items() if v is not None}
2417
+
2418
+ result = await self._connector.execute("metafield_shops", "list", params)
2419
+ # Cast generic envelope to concrete typed result
2420
+ return MetafieldShopsListResult(
2421
+ data=result.data,
2422
+ meta=result.meta
2423
+ )
2424
+
2425
+
2426
+
2427
+ async def get(
2428
+ self,
2429
+ metafield_id: str,
2430
+ **kwargs
2431
+ ) -> Metafield:
2432
+ """
2433
+ Retrieves a single metafield by ID
2434
+
2435
+ Args:
2436
+ metafield_id: The metafield ID
2437
+ **kwargs: Additional parameters
2438
+
2439
+ Returns:
2440
+ Metafield
2441
+ """
2442
+ params = {k: v for k, v in {
2443
+ "metafield_id": metafield_id,
2444
+ **kwargs
2445
+ }.items() if v is not None}
2446
+
2447
+ result = await self._connector.execute("metafield_shops", "get", params)
2448
+ return result
2449
+
2450
+
2451
+
2452
+ class MetafieldCustomersQuery:
2453
+ """
2454
+ Query class for MetafieldCustomers entity operations.
2455
+ """
2456
+
2457
+ def __init__(self, connector: ShopifyConnector):
2458
+ """Initialize query with connector reference."""
2459
+ self._connector = connector
2460
+
2461
+ async def list(
2462
+ self,
2463
+ customer_id: str,
2464
+ limit: int | None = None,
2465
+ since_id: int | None = None,
2466
+ namespace: str | None = None,
2467
+ key: str | None = None,
2468
+ **kwargs
2469
+ ) -> MetafieldCustomersListResult:
2470
+ """
2471
+ Returns a list of metafields for a customer
2472
+
2473
+ Args:
2474
+ customer_id: The customer ID
2475
+ limit: Maximum number of results to return (max 250)
2476
+ since_id: Restrict results to after the specified ID
2477
+ namespace: Filter by namespace
2478
+ key: Filter by key
2479
+ **kwargs: Additional parameters
2480
+
2481
+ Returns:
2482
+ MetafieldCustomersListResult
2483
+ """
2484
+ params = {k: v for k, v in {
2485
+ "customer_id": customer_id,
2486
+ "limit": limit,
2487
+ "since_id": since_id,
2488
+ "namespace": namespace,
2489
+ "key": key,
2490
+ **kwargs
2491
+ }.items() if v is not None}
2492
+
2493
+ result = await self._connector.execute("metafield_customers", "list", params)
2494
+ # Cast generic envelope to concrete typed result
2495
+ return MetafieldCustomersListResult(
2496
+ data=result.data,
2497
+ meta=result.meta
2498
+ )
2499
+
2500
+
2501
+
2502
+ class MetafieldProductsQuery:
2503
+ """
2504
+ Query class for MetafieldProducts entity operations.
2505
+ """
2506
+
2507
+ def __init__(self, connector: ShopifyConnector):
2508
+ """Initialize query with connector reference."""
2509
+ self._connector = connector
2510
+
2511
+ async def list(
2512
+ self,
2513
+ product_id: str,
2514
+ limit: int | None = None,
2515
+ since_id: int | None = None,
2516
+ namespace: str | None = None,
2517
+ key: str | None = None,
2518
+ **kwargs
2519
+ ) -> MetafieldProductsListResult:
2520
+ """
2521
+ Returns a list of metafields for a product
2522
+
2523
+ Args:
2524
+ product_id: The product ID
2525
+ limit: Maximum number of results to return (max 250)
2526
+ since_id: Restrict results to after the specified ID
2527
+ namespace: Filter by namespace
2528
+ key: Filter by key
2529
+ **kwargs: Additional parameters
2530
+
2531
+ Returns:
2532
+ MetafieldProductsListResult
2533
+ """
2534
+ params = {k: v for k, v in {
2535
+ "product_id": product_id,
2536
+ "limit": limit,
2537
+ "since_id": since_id,
2538
+ "namespace": namespace,
2539
+ "key": key,
2540
+ **kwargs
2541
+ }.items() if v is not None}
2542
+
2543
+ result = await self._connector.execute("metafield_products", "list", params)
2544
+ # Cast generic envelope to concrete typed result
2545
+ return MetafieldProductsListResult(
2546
+ data=result.data,
2547
+ meta=result.meta
2548
+ )
2549
+
2550
+
2551
+
2552
+ class MetafieldOrdersQuery:
2553
+ """
2554
+ Query class for MetafieldOrders entity operations.
2555
+ """
2556
+
2557
+ def __init__(self, connector: ShopifyConnector):
2558
+ """Initialize query with connector reference."""
2559
+ self._connector = connector
2560
+
2561
+ async def list(
2562
+ self,
2563
+ order_id: str,
2564
+ limit: int | None = None,
2565
+ since_id: int | None = None,
2566
+ namespace: str | None = None,
2567
+ key: str | None = None,
2568
+ **kwargs
2569
+ ) -> MetafieldOrdersListResult:
2570
+ """
2571
+ Returns a list of metafields for an order
2572
+
2573
+ Args:
2574
+ order_id: The order ID
2575
+ limit: Maximum number of results to return (max 250)
2576
+ since_id: Restrict results to after the specified ID
2577
+ namespace: Filter by namespace
2578
+ key: Filter by key
2579
+ **kwargs: Additional parameters
2580
+
2581
+ Returns:
2582
+ MetafieldOrdersListResult
2583
+ """
2584
+ params = {k: v for k, v in {
2585
+ "order_id": order_id,
2586
+ "limit": limit,
2587
+ "since_id": since_id,
2588
+ "namespace": namespace,
2589
+ "key": key,
2590
+ **kwargs
2591
+ }.items() if v is not None}
2592
+
2593
+ result = await self._connector.execute("metafield_orders", "list", params)
2594
+ # Cast generic envelope to concrete typed result
2595
+ return MetafieldOrdersListResult(
2596
+ data=result.data,
2597
+ meta=result.meta
2598
+ )
2599
+
2600
+
2601
+
2602
+ class MetafieldDraftOrdersQuery:
2603
+ """
2604
+ Query class for MetafieldDraftOrders entity operations.
2605
+ """
2606
+
2607
+ def __init__(self, connector: ShopifyConnector):
2608
+ """Initialize query with connector reference."""
2609
+ self._connector = connector
2610
+
2611
+ async def list(
2612
+ self,
2613
+ draft_order_id: str,
2614
+ limit: int | None = None,
2615
+ since_id: int | None = None,
2616
+ namespace: str | None = None,
2617
+ key: str | None = None,
2618
+ **kwargs
2619
+ ) -> MetafieldDraftOrdersListResult:
2620
+ """
2621
+ Returns a list of metafields for a draft order
2622
+
2623
+ Args:
2624
+ draft_order_id: The draft order ID
2625
+ limit: Maximum number of results to return (max 250)
2626
+ since_id: Restrict results to after the specified ID
2627
+ namespace: Filter by namespace
2628
+ key: Filter by key
2629
+ **kwargs: Additional parameters
2630
+
2631
+ Returns:
2632
+ MetafieldDraftOrdersListResult
2633
+ """
2634
+ params = {k: v for k, v in {
2635
+ "draft_order_id": draft_order_id,
2636
+ "limit": limit,
2637
+ "since_id": since_id,
2638
+ "namespace": namespace,
2639
+ "key": key,
2640
+ **kwargs
2641
+ }.items() if v is not None}
2642
+
2643
+ result = await self._connector.execute("metafield_draft_orders", "list", params)
2644
+ # Cast generic envelope to concrete typed result
2645
+ return MetafieldDraftOrdersListResult(
2646
+ data=result.data,
2647
+ meta=result.meta
2648
+ )
2649
+
2650
+
2651
+
2652
+ class MetafieldLocationsQuery:
2653
+ """
2654
+ Query class for MetafieldLocations entity operations.
2655
+ """
2656
+
2657
+ def __init__(self, connector: ShopifyConnector):
2658
+ """Initialize query with connector reference."""
2659
+ self._connector = connector
2660
+
2661
+ async def list(
2662
+ self,
2663
+ location_id: str,
2664
+ limit: int | None = None,
2665
+ since_id: int | None = None,
2666
+ namespace: str | None = None,
2667
+ key: str | None = None,
2668
+ **kwargs
2669
+ ) -> MetafieldLocationsListResult:
2670
+ """
2671
+ Returns a list of metafields for a location
2672
+
2673
+ Args:
2674
+ location_id: The location ID
2675
+ limit: Maximum number of results to return (max 250)
2676
+ since_id: Restrict results to after the specified ID
2677
+ namespace: Filter by namespace
2678
+ key: Filter by key
2679
+ **kwargs: Additional parameters
2680
+
2681
+ Returns:
2682
+ MetafieldLocationsListResult
2683
+ """
2684
+ params = {k: v for k, v in {
2685
+ "location_id": location_id,
2686
+ "limit": limit,
2687
+ "since_id": since_id,
2688
+ "namespace": namespace,
2689
+ "key": key,
2690
+ **kwargs
2691
+ }.items() if v is not None}
2692
+
2693
+ result = await self._connector.execute("metafield_locations", "list", params)
2694
+ # Cast generic envelope to concrete typed result
2695
+ return MetafieldLocationsListResult(
2696
+ data=result.data,
2697
+ meta=result.meta
2698
+ )
2699
+
2700
+
2701
+
2702
+ class MetafieldProductVariantsQuery:
2703
+ """
2704
+ Query class for MetafieldProductVariants entity operations.
2705
+ """
2706
+
2707
+ def __init__(self, connector: ShopifyConnector):
2708
+ """Initialize query with connector reference."""
2709
+ self._connector = connector
2710
+
2711
+ async def list(
2712
+ self,
2713
+ variant_id: str,
2714
+ limit: int | None = None,
2715
+ since_id: int | None = None,
2716
+ namespace: str | None = None,
2717
+ key: str | None = None,
2718
+ **kwargs
2719
+ ) -> MetafieldProductVariantsListResult:
2720
+ """
2721
+ Returns a list of metafields for a product variant
2722
+
2723
+ Args:
2724
+ variant_id: The variant ID
2725
+ limit: Maximum number of results to return (max 250)
2726
+ since_id: Restrict results to after the specified ID
2727
+ namespace: Filter by namespace
2728
+ key: Filter by key
2729
+ **kwargs: Additional parameters
2730
+
2731
+ Returns:
2732
+ MetafieldProductVariantsListResult
2733
+ """
2734
+ params = {k: v for k, v in {
2735
+ "variant_id": variant_id,
2736
+ "limit": limit,
2737
+ "since_id": since_id,
2738
+ "namespace": namespace,
2739
+ "key": key,
2740
+ **kwargs
2741
+ }.items() if v is not None}
2742
+
2743
+ result = await self._connector.execute("metafield_product_variants", "list", params)
2744
+ # Cast generic envelope to concrete typed result
2745
+ return MetafieldProductVariantsListResult(
2746
+ data=result.data,
2747
+ meta=result.meta
2748
+ )
2749
+
2750
+
2751
+
2752
+ class MetafieldSmartCollectionsQuery:
2753
+ """
2754
+ Query class for MetafieldSmartCollections entity operations.
2755
+ """
2756
+
2757
+ def __init__(self, connector: ShopifyConnector):
2758
+ """Initialize query with connector reference."""
2759
+ self._connector = connector
2760
+
2761
+ async def list(
2762
+ self,
2763
+ collection_id: str,
2764
+ limit: int | None = None,
2765
+ since_id: int | None = None,
2766
+ namespace: str | None = None,
2767
+ key: str | None = None,
2768
+ **kwargs
2769
+ ) -> MetafieldSmartCollectionsListResult:
2770
+ """
2771
+ Returns a list of metafields for a smart collection
2772
+
2773
+ Args:
2774
+ collection_id: The collection ID
2775
+ limit: Maximum number of results to return (max 250)
2776
+ since_id: Restrict results to after the specified ID
2777
+ namespace: Filter by namespace
2778
+ key: Filter by key
2779
+ **kwargs: Additional parameters
2780
+
2781
+ Returns:
2782
+ MetafieldSmartCollectionsListResult
2783
+ """
2784
+ params = {k: v for k, v in {
2785
+ "collection_id": collection_id,
2786
+ "limit": limit,
2787
+ "since_id": since_id,
2788
+ "namespace": namespace,
2789
+ "key": key,
2790
+ **kwargs
2791
+ }.items() if v is not None}
2792
+
2793
+ result = await self._connector.execute("metafield_smart_collections", "list", params)
2794
+ # Cast generic envelope to concrete typed result
2795
+ return MetafieldSmartCollectionsListResult(
2796
+ data=result.data,
2797
+ meta=result.meta
2798
+ )
2799
+
2800
+
2801
+
2802
+ class MetafieldProductImagesQuery:
2803
+ """
2804
+ Query class for MetafieldProductImages entity operations.
2805
+ """
2806
+
2807
+ def __init__(self, connector: ShopifyConnector):
2808
+ """Initialize query with connector reference."""
2809
+ self._connector = connector
2810
+
2811
+ async def list(
2812
+ self,
2813
+ product_id: str,
2814
+ image_id: str,
2815
+ limit: int | None = None,
2816
+ since_id: int | None = None,
2817
+ namespace: str | None = None,
2818
+ key: str | None = None,
2819
+ **kwargs
2820
+ ) -> MetafieldProductImagesListResult:
2821
+ """
2822
+ Returns a list of metafields for a product image
2823
+
2824
+ Args:
2825
+ product_id: The product ID
2826
+ image_id: The image ID
2827
+ limit: Maximum number of results to return (max 250)
2828
+ since_id: Restrict results to after the specified ID
2829
+ namespace: Filter by namespace
2830
+ key: Filter by key
2831
+ **kwargs: Additional parameters
2832
+
2833
+ Returns:
2834
+ MetafieldProductImagesListResult
2835
+ """
2836
+ params = {k: v for k, v in {
2837
+ "product_id": product_id,
2838
+ "image_id": image_id,
2839
+ "limit": limit,
2840
+ "since_id": since_id,
2841
+ "namespace": namespace,
2842
+ "key": key,
2843
+ **kwargs
2844
+ }.items() if v is not None}
2845
+
2846
+ result = await self._connector.execute("metafield_product_images", "list", params)
2847
+ # Cast generic envelope to concrete typed result
2848
+ return MetafieldProductImagesListResult(
2849
+ data=result.data,
2850
+ meta=result.meta
2851
+ )
2852
+
2853
+
2854
+
2855
+ class CustomerAddressQuery:
2856
+ """
2857
+ Query class for CustomerAddress entity operations.
2858
+ """
2859
+
2860
+ def __init__(self, connector: ShopifyConnector):
2861
+ """Initialize query with connector reference."""
2862
+ self._connector = connector
2863
+
2864
+ async def list(
2865
+ self,
2866
+ customer_id: str,
2867
+ limit: int | None = None,
2868
+ **kwargs
2869
+ ) -> CustomerAddressListResult:
2870
+ """
2871
+ Returns a list of addresses for a customer
2872
+
2873
+ Args:
2874
+ customer_id: The customer ID
2875
+ limit: Maximum number of results to return (max 250)
2876
+ **kwargs: Additional parameters
2877
+
2878
+ Returns:
2879
+ CustomerAddressListResult
2880
+ """
2881
+ params = {k: v for k, v in {
2882
+ "customer_id": customer_id,
2883
+ "limit": limit,
2884
+ **kwargs
2885
+ }.items() if v is not None}
2886
+
2887
+ result = await self._connector.execute("customer_address", "list", params)
2888
+ # Cast generic envelope to concrete typed result
2889
+ return CustomerAddressListResult(
2890
+ data=result.data,
2891
+ meta=result.meta
2892
+ )
2893
+
2894
+
2895
+
2896
+ async def get(
2897
+ self,
2898
+ customer_id: str,
2899
+ address_id: str,
2900
+ **kwargs
2901
+ ) -> CustomerAddress:
2902
+ """
2903
+ Retrieves a single customer address by ID
2904
+
2905
+ Args:
2906
+ customer_id: The customer ID
2907
+ address_id: The address ID
2908
+ **kwargs: Additional parameters
2909
+
2910
+ Returns:
2911
+ CustomerAddress
2912
+ """
2913
+ params = {k: v for k, v in {
2914
+ "customer_id": customer_id,
2915
+ "address_id": address_id,
2916
+ **kwargs
2917
+ }.items() if v is not None}
2918
+
2919
+ result = await self._connector.execute("customer_address", "get", params)
2920
+ return result
2921
+
2922
+
2923
+
2924
+ class FulfillmentOrdersQuery:
2925
+ """
2926
+ Query class for FulfillmentOrders entity operations.
2927
+ """
2928
+
2929
+ def __init__(self, connector: ShopifyConnector):
2930
+ """Initialize query with connector reference."""
2931
+ self._connector = connector
2932
+
2933
+ async def list(
2934
+ self,
2935
+ order_id: str,
2936
+ **kwargs
2937
+ ) -> FulfillmentOrdersListResult:
2938
+ """
2939
+ Returns a list of fulfillment orders for a specific order
2940
+
2941
+ Args:
2942
+ order_id: The order ID
2943
+ **kwargs: Additional parameters
2944
+
2945
+ Returns:
2946
+ FulfillmentOrdersListResult
2947
+ """
2948
+ params = {k: v for k, v in {
2949
+ "order_id": order_id,
2950
+ **kwargs
2951
+ }.items() if v is not None}
2952
+
2953
+ result = await self._connector.execute("fulfillment_orders", "list", params)
2954
+ # Cast generic envelope to concrete typed result
2955
+ return FulfillmentOrdersListResult(
2956
+ data=result.data,
2957
+ meta=result.meta
2958
+ )
2959
+
2960
+
2961
+
2962
+ async def get(
2963
+ self,
2964
+ fulfillment_order_id: str,
2965
+ **kwargs
2966
+ ) -> FulfillmentOrder:
2967
+ """
2968
+ Retrieves a single fulfillment order by ID
2969
+
2970
+ Args:
2971
+ fulfillment_order_id: The fulfillment order ID
2972
+ **kwargs: Additional parameters
2973
+
2974
+ Returns:
2975
+ FulfillmentOrder
2976
+ """
2977
+ params = {k: v for k, v in {
2978
+ "fulfillment_order_id": fulfillment_order_id,
2979
+ **kwargs
2980
+ }.items() if v is not None}
2981
+
2982
+ result = await self._connector.execute("fulfillment_orders", "get", params)
2983
+ return result
2984
+
2985
+