airbyte-agent-shopify 0.1.1__py3-none-any.whl → 0.1.13__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.
@@ -4,8 +4,11 @@ Shopify connector.
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import inspect
8
+ import json
7
9
  import logging
8
- from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
10
+ from functools import wraps
11
+ from typing import TYPE_CHECKING, Any, Callable, Mapping, TypeVar, overload
9
12
  try:
10
13
  from typing import Literal
11
14
  except ImportError:
@@ -133,6 +136,38 @@ from .models import (
133
136
  # TypeVar for decorator type preservation
134
137
  _F = TypeVar("_F", bound=Callable[..., Any])
135
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
+
136
171
 
137
172
 
138
173
  class ShopifyConnector:
@@ -143,7 +178,7 @@ class ShopifyConnector:
143
178
  """
144
179
 
145
180
  connector_name = "shopify"
146
- connector_version = "0.1.1"
181
+ connector_version = "0.1.2"
147
182
  vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
148
183
 
149
184
  # Map of (entity, action) -> needs_envelope for envelope wrapping decision
@@ -795,15 +830,15 @@ class ShopifyConnector:
795
830
  async def execute(
796
831
  self,
797
832
  entity: str,
798
- action: str,
799
- params: dict[str, Any]
833
+ action: Literal["list", "get"],
834
+ params: Mapping[str, Any]
800
835
  ) -> ShopifyExecuteResult[Any] | ShopifyExecuteResultWithMeta[Any, Any] | Any: ...
801
836
 
802
837
  async def execute(
803
838
  self,
804
839
  entity: str,
805
- action: str,
806
- params: dict[str, Any] | None = None
840
+ action: Literal["list", "get"],
841
+ params: Mapping[str, Any] | None = None
807
842
  ) -> Any:
808
843
  """
809
844
  Execute an entity operation with full type safety.
@@ -831,16 +866,17 @@ class ShopifyConnector:
831
866
  from ._vendored.connector_sdk.executor import ExecutionConfig
832
867
 
833
868
  # Remap parameter names from snake_case (TypedDict keys) to API parameter names
834
- if params:
869
+ resolved_params = dict(params) if params is not None else None
870
+ if resolved_params:
835
871
  param_map = self._PARAM_MAP.get((entity, action), {})
836
872
  if param_map:
837
- params = {param_map.get(k, k): v for k, v in params.items()}
873
+ resolved_params = {param_map.get(k, k): v for k, v in resolved_params.items()}
838
874
 
839
875
  # Use ExecutionConfig for both local and hosted executors
840
876
  config = ExecutionConfig(
841
877
  entity=entity,
842
878
  action=action,
843
- params=params
879
+ params=resolved_params
844
880
  )
845
881
 
846
882
  result = await self._executor.execute(config)
@@ -867,41 +903,67 @@ class ShopifyConnector:
867
903
  # ===== INTROSPECTION METHODS =====
868
904
 
869
905
  @classmethod
870
- def describe(cls, func: _F) -> _F:
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]:
871
913
  """
872
- Decorator that populates a function's docstring with connector capabilities.
873
-
874
- This class method can be used as a decorator to automatically generate
875
- comprehensive documentation for AI tool functions.
914
+ Decorator that adds tool utilities like docstring augmentation and output limits.
876
915
 
877
916
  Usage:
878
917
  @mcp.tool()
879
- @ShopifyConnector.describe
918
+ @ShopifyConnector.tool_utils
880
919
  async def execute(entity: str, action: str, params: dict):
881
- '''Execute operations.'''
882
920
  ...
883
921
 
884
- The decorated function's __doc__ will be updated with:
885
- - Available entities and their actions
886
- - Parameter signatures with required (*) and optional (?) markers
887
- - Response structure documentation
888
- - Example questions (if available in OpenAPI spec)
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
+ ...
889
926
 
890
927
  Args:
891
- func: The function to decorate
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 = ""
892
942
 
893
- Returns:
894
- The same function with updated __doc__
895
- """
896
- description = generate_tool_description(ShopifyConnectorModel)
943
+ if inspect.iscoroutinefunction(inner):
897
944
 
898
- original_doc = func.__doc__ or ""
899
- if original_doc.strip():
900
- func.__doc__ = f"{original_doc.strip()}\n{description}"
901
- else:
902
- func.__doc__ = description
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]
903
963
 
904
- return func
964
+ if func is not None:
965
+ return decorate(func)
966
+ return decorate
905
967
 
906
968
  def list_entities(self) -> list[dict[str, Any]]:
907
969
  """
@@ -26,7 +26,7 @@ from uuid import (
26
26
  ShopifyConnectorModel: ConnectorModel = ConnectorModel(
27
27
  id=UUID('9da77001-af33-4bcd-be46-6252bf9342b9'),
28
28
  name='shopify',
29
- version='0.1.1',
29
+ version='0.1.2',
30
30
  base_url='https://{shop}.myshopify.com/admin/api/2025-01',
31
31
  auth=AuthConfig(
32
32
  type=AuthType.API_KEY,
@@ -39,7 +39,6 @@ ShopifyConnectorModel: ConnectorModel = ConnectorModel(
39
39
  'api_key': AuthConfigFieldSpec(
40
40
  title='Access Token',
41
41
  description='Your Shopify Admin API access token',
42
- airbyte_secret=True,
43
42
  ),
44
43
  'shop': AuthConfigFieldSpec(
45
44
  title='Shop Name',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airbyte-agent-shopify
3
- Version: 0.1.1
3
+ Version: 0.1.13
4
4
  Summary: Airbyte Shopify Connector for AI platforms
5
5
  Project-URL: Homepage, https://github.com/airbytehq/airbyte-agent-connectors
6
6
  Project-URL: Documentation, https://docs.airbyte.com/ai-agents/
@@ -75,16 +75,48 @@ uv pip install airbyte-agent-shopify
75
75
 
76
76
  ## Usage
77
77
 
78
+ Connectors can run in open source or hosted mode.
79
+
80
+ ### Open source
81
+
82
+ In open source mode, you provide API credentials directly to the connector.
83
+
78
84
  ```python
79
- from airbyte_agent_shopify import ShopifyConnector, ShopifyAuthConfig
85
+ from airbyte_agent_shopify import ShopifyConnector
86
+ from airbyte_agent_shopify.models import ShopifyAuthConfig
80
87
 
81
88
  connector = ShopifyConnector(
82
- auth_config=ShopifyAuthConfig(
83
- api_key="...",
84
- shop="..."
85
- )
89
+ auth_config=ShopifyAuthConfig(
90
+ api_key="<Your Shopify Admin API access token>",
91
+ shop="<Your Shopify store name (e.g., 'my-store' from my-store.myshopify.com)>"
92
+ )
86
93
  )
87
- result = await connector.customers.list()
94
+
95
+ @agent.tool_plain # assumes you're using Pydantic AI
96
+ @ShopifyConnector.tool_utils
97
+ async def shopify_execute(entity: str, action: str, params: dict | None = None):
98
+ return await connector.execute(entity, action, params or {})
99
+ ```
100
+
101
+ ### Hosted
102
+
103
+ In hosted mode, API credentials are stored securely in Airbyte Cloud. You provide your Airbyte credentials instead.
104
+
105
+ This example assumes you've already authenticated your connector with Airbyte. See [Authentication](AUTH.md) to learn more about authenticating. If you need a step-by-step guide, see the [hosted execution tutorial](https://docs.airbyte.com/ai-agents/quickstarts/tutorial-hosted).
106
+
107
+ ```python
108
+ from airbyte_agent_shopify import ShopifyConnector
109
+
110
+ connector = ShopifyConnector(
111
+ external_user_id="<your_external_user_id>",
112
+ airbyte_client_id="<your-client-id>",
113
+ airbyte_client_secret="<your-client-secret>"
114
+ )
115
+
116
+ @agent.tool_plain # assumes you're using Pydantic AI
117
+ @ShopifyConnector.tool_utils
118
+ async def shopify_execute(entity: str, action: str, params: dict | None = None):
119
+ return await connector.execute(entity, action, params or {})
88
120
  ```
89
121
 
90
122
 
@@ -128,12 +160,14 @@ This connector supports the following entities and actions.
128
160
  | Fulfillment Orders | [List](./REFERENCE.md#fulfillment-orders-list), [Get](./REFERENCE.md#fulfillment-orders-get) |
129
161
 
130
162
 
163
+ For all authentication options, see the connector's [authentication documentation](AUTH.md).
164
+
131
165
  For detailed documentation on available actions and parameters, see this connector's [full reference documentation](./REFERENCE.md).
132
166
 
133
167
  For the service's official API docs, see the [Shopify API reference](https://shopify.dev/docs/api/admin-rest).
134
168
 
135
169
  ## Version information
136
170
 
137
- - **Package version:** 0.1.1
138
- - **Connector version:** 0.1.1
139
- - **Generated with Connector SDK commit SHA:** c46670b9e4ca5238c0372e143b44088a0d1a68ee
171
+ - **Package version:** 0.1.13
172
+ - **Connector version:** 0.1.2
173
+ - **Generated with Connector SDK commit SHA:** c9b05509eb899e313055660f378d9c1f1e9129c7
@@ -1,27 +1,27 @@
1
1
  airbyte_agent_shopify/__init__.py,sha256=uFn4x1bUldfWTPBITTIGYrjD5bRufgEVvKVviDOUd_0,9661
2
- airbyte_agent_shopify/connector.py,sha256=Cax_d6uRrhn8h6H6uyPSe2crZCGDv-9UzNRF3vwbxgI,91544
3
- airbyte_agent_shopify/connector_model.py,sha256=xZDsz1CqmSkPTrlvK7hheWLs2RCDsIFD4JiZTu5ll-s,691051
2
+ airbyte_agent_shopify/connector.py,sha256=uDA7DNbgXNQQ94sp2Kinq2Rgu2FgBZEWzbgKTLEteZM,93793
3
+ airbyte_agent_shopify/connector_model.py,sha256=AVa7n--wns14y5tdsiKymVUMS7HboqVD8sdzvKPlBRM,691010
4
4
  airbyte_agent_shopify/models.py,sha256=hBMmLBLBlmqU8TdcJGpm3fQyyDVP3BEpDJ5C2cInBso,60917
5
5
  airbyte_agent_shopify/types.py,sha256=AwQ4PR2wZmHNuryriCFdRxf9q48J1mnPwspUB1b-L_o,10221
6
6
  airbyte_agent_shopify/_vendored/__init__.py,sha256=ILl7AHXMui__swyrjxrh9yRa4dLiwBvV6axPWFWty80,38
7
7
  airbyte_agent_shopify/_vendored/connector_sdk/__init__.py,sha256=T5o7roU6NSpH-lCAGZ338sE5dlh4ZU6i6IkeG1zpems,1949
8
- airbyte_agent_shopify/_vendored/connector_sdk/auth_strategies.py,sha256=BdjAzFRTwXCmLFqYWqZ4Dx9RsqtI7pAkw-8NynSK4sQ,39914
8
+ airbyte_agent_shopify/_vendored/connector_sdk/auth_strategies.py,sha256=5Sb9moUp623o67Q2wMa8iZldJH08y4gQdoutoO_75Iw,42088
9
9
  airbyte_agent_shopify/_vendored/connector_sdk/auth_template.py,sha256=nju4jqlFC_KI82ILNumNIyiUtRJcy7J94INIZ0QraI4,4454
10
- airbyte_agent_shopify/_vendored/connector_sdk/connector_model_loader.py,sha256=b88aoMynHxtG2dhzclkWrLiJbefTiKMzReyj3lOiwJI,34940
10
+ airbyte_agent_shopify/_vendored/connector_sdk/connector_model_loader.py,sha256=AW9bsdggzuc3ydy2bYYF33L6LxLKLQer9Wm47IOuQw0,41492
11
11
  airbyte_agent_shopify/_vendored/connector_sdk/constants.py,sha256=AtzOvhDMWbRJgpsQNWl5tkogHD6mWgEY668PgRmgtOY,2737
12
12
  airbyte_agent_shopify/_vendored/connector_sdk/exceptions.py,sha256=ss5MGv9eVPmsbLcLWetuu3sDmvturwfo6Pw3M37Oq5k,481
13
13
  airbyte_agent_shopify/_vendored/connector_sdk/extensions.py,sha256=XWRRoJOOrwUHSKbuQt5DU7CCu8ePzhd_HuP7c_uD77w,21376
14
14
  airbyte_agent_shopify/_vendored/connector_sdk/http_client.py,sha256=yucwu3OvJh5wLQa1mk-gTKjtqjKKucMw5ltmlE7mk1c,28000
15
- airbyte_agent_shopify/_vendored/connector_sdk/introspection.py,sha256=2CyKXZHT74-1Id97uw1RLeyOi6TV24_hoNbQ6-6y7uI,10335
15
+ airbyte_agent_shopify/_vendored/connector_sdk/introspection.py,sha256=kRVI4TDQDLdcCnTBUML8ycAtdqAQufVh-027sMkb4i8,19165
16
16
  airbyte_agent_shopify/_vendored/connector_sdk/secrets.py,sha256=J9ezMu4xNnLW11xY5RCre6DHP7YMKZCqwGJfk7ufHAM,6855
17
- airbyte_agent_shopify/_vendored/connector_sdk/types.py,sha256=CStkOsLtmZZdXylkdCsbYORDzughxygt1-Ucma0j-qE,8287
17
+ airbyte_agent_shopify/_vendored/connector_sdk/types.py,sha256=in8gHsn5nsScujOfHZmkOgNmqmJKiPyNNjg59m5fGWc,8807
18
18
  airbyte_agent_shopify/_vendored/connector_sdk/utils.py,sha256=G4LUXOC2HzPoND2v4tQW68R9uuPX9NQyCjaGxb7Kpl0,1958
19
19
  airbyte_agent_shopify/_vendored/connector_sdk/validation.py,sha256=4MPrxYmQh8TbCU0KdvvRKe35Lg1YYLEBd0u4aKySl_E,32122
20
20
  airbyte_agent_shopify/_vendored/connector_sdk/cloud_utils/__init__.py,sha256=4799Hv9f2zxDVj1aLyQ8JpTEuFTp_oOZMRz-NZCdBJg,134
21
21
  airbyte_agent_shopify/_vendored/connector_sdk/cloud_utils/client.py,sha256=YxdRpQr9XjDzih6csSseBVGn9kfMtaqbOCXP0TPuzFY,7189
22
22
  airbyte_agent_shopify/_vendored/connector_sdk/executor/__init__.py,sha256=EmG9YQNAjSuYCVB4D5VoLm4qpD1KfeiiOf7bpALj8p8,702
23
23
  airbyte_agent_shopify/_vendored/connector_sdk/executor/hosted_executor.py,sha256=ydHcG-biRS1ITT5ELwPShdJW-KYpvK--Fos1ipNgHho,6995
24
- airbyte_agent_shopify/_vendored/connector_sdk/executor/local_executor.py,sha256=oJDliuS7zU8GILJUjn7T_WNIu25sy5serJHxhnBKyB8,71411
24
+ airbyte_agent_shopify/_vendored/connector_sdk/executor/local_executor.py,sha256=tVbfstxOrm5qJt1NawTwjhIIpDgPCC4wSrKM5eALPSQ,74064
25
25
  airbyte_agent_shopify/_vendored/connector_sdk/executor/models.py,sha256=lYVT_bNcw-PoIks4WHNyl2VY-lJVf2FntzINSOBIheE,5845
26
26
  airbyte_agent_shopify/_vendored/connector_sdk/http/__init__.py,sha256=y8fbzZn-3yV9OxtYz8Dy6FFGI5v6TOqADd1G3xHH3Hw,911
27
27
  airbyte_agent_shopify/_vendored/connector_sdk/http/config.py,sha256=6J7YIIwHC6sRu9i-yKa5XvArwK2KU60rlnmxzDZq3lw,3283
@@ -42,16 +42,16 @@ airbyte_agent_shopify/_vendored/connector_sdk/performance/__init__.py,sha256=Sp5
42
42
  airbyte_agent_shopify/_vendored/connector_sdk/performance/instrumentation.py,sha256=_dXvNiqdndIBwDjeDKNViWzn_M5FkSUsMmJtFldrmsM,1504
43
43
  airbyte_agent_shopify/_vendored/connector_sdk/performance/metrics.py,sha256=FRff7dKt4iwt_A7pxV5n9kAGBR756PC7q8-weWygPSM,2817
44
44
  airbyte_agent_shopify/_vendored/connector_sdk/schema/__init__.py,sha256=Uymu-QuzGJuMxexBagIvUxpVAigIuIhz3KeBl_Vu4Ko,1638
45
- airbyte_agent_shopify/_vendored/connector_sdk/schema/base.py,sha256=4RYTkCWgyS5Z75z9TKj9vXySfO00HJ03QDtbdVYeHYM,5086
46
- airbyte_agent_shopify/_vendored/connector_sdk/schema/components.py,sha256=x3YCM1p2n_xHi50fMeOX0mXUiPqjGlLHs3Go8jXokb0,7895
45
+ airbyte_agent_shopify/_vendored/connector_sdk/schema/base.py,sha256=IoAucZQ0j0xTdm4VWotB636R4jsrkYnppMQhXE0uoyU,6541
46
+ airbyte_agent_shopify/_vendored/connector_sdk/schema/components.py,sha256=nJIPieavwX3o3ODvdtLHPk84d_V229xmg6LDfwEHjzc,8119
47
47
  airbyte_agent_shopify/_vendored/connector_sdk/schema/connector.py,sha256=mSZk1wr2YSdRj9tTRsPAuIlCzd_xZLw-Bzl1sMwE0rE,3731
48
- airbyte_agent_shopify/_vendored/connector_sdk/schema/extensions.py,sha256=f7VhHrcIYxaPOJHMc4g0lpy04pZTbx5nlroNzAu5B9Q,7135
48
+ airbyte_agent_shopify/_vendored/connector_sdk/schema/extensions.py,sha256=5hgpFHK7fzpzegCkJk882DeIP79bCx_qairKJhvPMZ8,9590
49
49
  airbyte_agent_shopify/_vendored/connector_sdk/schema/operations.py,sha256=RpzGtAI4yvAtMHAfMUMcUwgHv_qJojnKlNb75_agUF8,5729
50
- airbyte_agent_shopify/_vendored/connector_sdk/schema/security.py,sha256=zQ9RRuF3LBgLQi_4cItmjXbG_5WKlmCNM3nCil30H90,8470
50
+ airbyte_agent_shopify/_vendored/connector_sdk/schema/security.py,sha256=1CVCavrPdHHyk7B6JtUD75yRS_hWLCemZF1zwGbdqxg,9036
51
51
  airbyte_agent_shopify/_vendored/connector_sdk/telemetry/__init__.py,sha256=RaLgkBU4dfxn1LC5Y0Q9rr2PJbrwjxvPgBLmq8_WafE,211
52
52
  airbyte_agent_shopify/_vendored/connector_sdk/telemetry/config.py,sha256=tLmQwAFD0kP1WyBGWBS3ysaudN9H3e-3EopKZi6cGKg,885
53
53
  airbyte_agent_shopify/_vendored/connector_sdk/telemetry/events.py,sha256=8Y1NbXiwISX-V_wRofY7PqcwEXD0dLMnntKkY6XFU2s,1328
54
54
  airbyte_agent_shopify/_vendored/connector_sdk/telemetry/tracker.py,sha256=Ftrk0_ddfM7dZG8hF9xBuPwhbc9D6JZ7Q9qs5o3LEyA,5579
55
- airbyte_agent_shopify-0.1.1.dist-info/METADATA,sha256=2Ga2iG1_reqk8QEA80pjdxraqVp9R3NqW3_2ZCwHVOQ,6381
56
- airbyte_agent_shopify-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
57
- airbyte_agent_shopify-0.1.1.dist-info/RECORD,,
55
+ airbyte_agent_shopify-0.1.13.dist-info/METADATA,sha256=srNNoLgB5qbfylUD6eNQh3hJkjs51CIeSEYio99nbbg,7842
56
+ airbyte_agent_shopify-0.1.13.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
57
+ airbyte_agent_shopify-0.1.13.dist-info/RECORD,,