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