airbyte-agent-zendesk-support 0.18.18__py3-none-any.whl → 0.18.51__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.
- airbyte_agent_zendesk_support/__init__.py +239 -18
- airbyte_agent_zendesk_support/_vendored/connector_sdk/auth_strategies.py +2 -5
- airbyte_agent_zendesk_support/_vendored/connector_sdk/auth_template.py +1 -1
- airbyte_agent_zendesk_support/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
- airbyte_agent_zendesk_support/_vendored/connector_sdk/cloud_utils/client.py +213 -0
- airbyte_agent_zendesk_support/_vendored/connector_sdk/connector_model_loader.py +35 -8
- airbyte_agent_zendesk_support/_vendored/connector_sdk/constants.py +1 -1
- airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/hosted_executor.py +92 -84
- airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/local_executor.py +274 -54
- airbyte_agent_zendesk_support/_vendored/connector_sdk/extensions.py +43 -5
- airbyte_agent_zendesk_support/_vendored/connector_sdk/http/response.py +2 -0
- airbyte_agent_zendesk_support/_vendored/connector_sdk/http_client.py +63 -49
- airbyte_agent_zendesk_support/_vendored/connector_sdk/introspection.py +262 -0
- airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/logger.py +19 -10
- airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/types.py +11 -10
- airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/config.py +179 -0
- airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/models.py +6 -6
- airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/session.py +41 -32
- airbyte_agent_zendesk_support/_vendored/connector_sdk/performance/metrics.py +3 -3
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/base.py +22 -18
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/components.py +59 -58
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/connector.py +22 -33
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/extensions.py +131 -10
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/operations.py +32 -32
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/security.py +44 -34
- airbyte_agent_zendesk_support/_vendored/connector_sdk/secrets.py +2 -2
- airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/events.py +9 -8
- airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/tracker.py +9 -5
- airbyte_agent_zendesk_support/_vendored/connector_sdk/types.py +9 -3
- airbyte_agent_zendesk_support/_vendored/connector_sdk/validation.py +12 -6
- airbyte_agent_zendesk_support/connector.py +1170 -171
- airbyte_agent_zendesk_support/connector_model.py +7 -1
- airbyte_agent_zendesk_support/models.py +628 -69
- airbyte_agent_zendesk_support/types.py +3717 -1
- {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.51.dist-info}/METADATA +55 -31
- {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.51.dist-info}/RECORD +37 -33
- {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.51.dist-info}/WHEEL +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
"""Hosted executor for proxying operations through the
|
|
1
|
+
"""Hosted executor for proxying operations through the cloud API."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import os
|
|
6
|
-
|
|
7
|
-
import httpx
|
|
8
5
|
from opentelemetry import trace
|
|
9
6
|
|
|
7
|
+
from ..cloud_utils import AirbyteCloudClient
|
|
8
|
+
|
|
10
9
|
from .models import (
|
|
11
10
|
ExecutionConfig,
|
|
12
11
|
ExecutionResult,
|
|
@@ -14,30 +13,36 @@ from .models import (
|
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class HostedExecutor:
|
|
17
|
-
"""Executor that proxies execution through the
|
|
16
|
+
"""Executor that proxies execution through the Airbyte Cloud API.
|
|
18
17
|
|
|
19
|
-
This is the "hosted mode" executor that makes HTTP calls to the
|
|
20
|
-
instead of directly calling external services. The
|
|
18
|
+
This is the "hosted mode" executor that makes HTTP calls to the cloud API
|
|
19
|
+
instead of directly calling external services. The cloud API handles all
|
|
21
20
|
connector logic, secrets management, and execution.
|
|
22
21
|
|
|
23
|
-
The
|
|
24
|
-
|
|
22
|
+
The executor takes an external_user_id and uses the AirbyteCloudClient to:
|
|
23
|
+
1. Authenticate with the Airbyte Platform (bearer token with caching)
|
|
24
|
+
2. Look up the user's connector
|
|
25
|
+
3. Execute the connector operation via the cloud API
|
|
25
26
|
|
|
26
27
|
Implements ExecutorProtocol.
|
|
27
28
|
|
|
28
29
|
Example:
|
|
30
|
+
# Create executor with user ID, credentials, and connector definition ID
|
|
29
31
|
executor = HostedExecutor(
|
|
30
|
-
|
|
32
|
+
external_user_id="user-123",
|
|
31
33
|
airbyte_client_id="client_abc123",
|
|
32
|
-
airbyte_client_secret="secret_xyz789"
|
|
34
|
+
airbyte_client_secret="secret_xyz789",
|
|
35
|
+
connector_definition_id="abc123-def456-ghi789",
|
|
33
36
|
)
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
# Execute an operation
|
|
39
|
+
execution_config = ExecutionConfig(
|
|
36
40
|
entity="customers",
|
|
37
|
-
action="list"
|
|
41
|
+
action="list",
|
|
42
|
+
params={"limit": 10}
|
|
38
43
|
)
|
|
39
44
|
|
|
40
|
-
result = await executor.execute(
|
|
45
|
+
result = await executor.execute(execution_config)
|
|
41
46
|
if result.success:
|
|
42
47
|
print(f"Data: {result.data}")
|
|
43
48
|
else:
|
|
@@ -46,53 +51,45 @@ class HostedExecutor:
|
|
|
46
51
|
|
|
47
52
|
def __init__(
|
|
48
53
|
self,
|
|
49
|
-
|
|
54
|
+
external_user_id: str,
|
|
50
55
|
airbyte_client_id: str,
|
|
51
56
|
airbyte_client_secret: str,
|
|
52
|
-
|
|
57
|
+
connector_definition_id: str,
|
|
53
58
|
):
|
|
54
59
|
"""Initialize hosted executor.
|
|
55
60
|
|
|
56
61
|
Args:
|
|
57
|
-
|
|
62
|
+
external_user_id: User identifier in the Airbyte system
|
|
58
63
|
airbyte_client_id: Airbyte client ID for authentication
|
|
59
64
|
airbyte_client_secret: Airbyte client secret for authentication
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
connector_definition_id: Connector definition ID used to look up
|
|
66
|
+
the user's connector.
|
|
62
67
|
|
|
63
68
|
Example:
|
|
64
69
|
executor = HostedExecutor(
|
|
65
|
-
|
|
66
|
-
airbyte_client_id="client_abc123",
|
|
67
|
-
airbyte_client_secret="secret_xyz789"
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
# Or with custom API URL:
|
|
71
|
-
executor = HostedExecutor(
|
|
72
|
-
connector_id="my-connector-id",
|
|
70
|
+
external_user_id="user-123",
|
|
73
71
|
airbyte_client_id="client_abc123",
|
|
74
72
|
airbyte_client_secret="secret_xyz789",
|
|
75
|
-
|
|
73
|
+
connector_definition_id="abc123-def456-ghi789",
|
|
76
74
|
)
|
|
77
75
|
"""
|
|
78
|
-
self.
|
|
79
|
-
self.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# The async wrapper allows it to work with the protocol
|
|
86
|
-
self.client = httpx.Client(
|
|
87
|
-
timeout=httpx.Timeout(300.0), # 5 minute timeout
|
|
88
|
-
follow_redirects=True,
|
|
76
|
+
self._external_user_id = external_user_id
|
|
77
|
+
self._connector_definition_id = connector_definition_id
|
|
78
|
+
|
|
79
|
+
# Create AirbyteCloudClient for API interactions
|
|
80
|
+
self._cloud_client = AirbyteCloudClient(
|
|
81
|
+
client_id=airbyte_client_id,
|
|
82
|
+
client_secret=airbyte_client_secret,
|
|
89
83
|
)
|
|
90
84
|
|
|
91
85
|
async def execute(self, config: ExecutionConfig) -> ExecutionResult:
|
|
92
|
-
"""Execute connector via
|
|
86
|
+
"""Execute connector via cloud API (ExecutorProtocol implementation).
|
|
93
87
|
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
Flow:
|
|
89
|
+
1. Get connector definition id from executor config
|
|
90
|
+
2. Look up the user's connector ID
|
|
91
|
+
3. Execute the connector operation via the cloud API
|
|
92
|
+
4. Parse the response into ExecutionResult
|
|
96
93
|
|
|
97
94
|
Args:
|
|
98
95
|
config: Execution configuration (entity, action, params)
|
|
@@ -101,88 +98,99 @@ class HostedExecutor:
|
|
|
101
98
|
ExecutionResult with success/failure status
|
|
102
99
|
|
|
103
100
|
Raises:
|
|
101
|
+
ValueError: If no connector or multiple connectors found for user
|
|
104
102
|
httpx.HTTPStatusError: If API returns 4xx/5xx status code
|
|
105
103
|
httpx.RequestError: If network request fails
|
|
106
104
|
|
|
107
105
|
Example:
|
|
108
106
|
config = ExecutionConfig(
|
|
109
107
|
entity="customers",
|
|
110
|
-
action="list"
|
|
108
|
+
action="list",
|
|
109
|
+
params={"limit": 10}
|
|
111
110
|
)
|
|
112
111
|
result = await executor.execute(config)
|
|
113
112
|
"""
|
|
114
113
|
tracer = trace.get_tracer("airbyte.connector-sdk.executor.hosted")
|
|
115
114
|
|
|
116
115
|
with tracer.start_as_current_span("airbyte.hosted_executor.execute") as span:
|
|
117
|
-
# Add span attributes
|
|
118
|
-
span.set_attribute("connector.
|
|
116
|
+
# Add span attributes for observability
|
|
117
|
+
span.set_attribute("connector.definition_id", self._connector_definition_id)
|
|
119
118
|
span.set_attribute("connector.entity", config.entity)
|
|
120
119
|
span.set_attribute("connector.action", config.action)
|
|
121
|
-
span.set_attribute("
|
|
120
|
+
span.set_attribute("user.external_id", self._external_user_id)
|
|
122
121
|
if config.params:
|
|
123
122
|
# Only add non-sensitive param keys
|
|
124
123
|
span.set_attribute("connector.param_keys", list(config.params.keys()))
|
|
125
124
|
|
|
126
|
-
# Build API URL from instance api_url
|
|
127
|
-
url = f"{self.api_url}/connectors/{self.connector_id}/execute"
|
|
128
|
-
span.set_attribute("http.url", url)
|
|
129
|
-
|
|
130
|
-
# Build request body matching ExecutionRequest model
|
|
131
|
-
# Extract entity, action, and params from config attributes
|
|
132
|
-
request_body = {
|
|
133
|
-
"entity": config.entity,
|
|
134
|
-
"action": config.action,
|
|
135
|
-
"params": config.params,
|
|
136
|
-
}
|
|
137
|
-
|
|
138
125
|
try:
|
|
139
|
-
#
|
|
140
|
-
|
|
141
|
-
|
|
126
|
+
# Step 1: Get connector definition id
|
|
127
|
+
connector_definition_id = self._connector_definition_id
|
|
128
|
+
|
|
129
|
+
# Step 2: Get the connector ID for this user
|
|
130
|
+
connector_id = await self._cloud_client.get_connector_id(
|
|
131
|
+
external_user_id=self._external_user_id,
|
|
132
|
+
connector_definition_id=connector_definition_id,
|
|
133
|
+
)
|
|
142
134
|
|
|
143
|
-
|
|
144
|
-
span.set_attribute("http.status_code", response.status_code)
|
|
135
|
+
span.set_attribute("connector.connector_id", connector_id)
|
|
145
136
|
|
|
146
|
-
#
|
|
147
|
-
response.
|
|
137
|
+
# Step 3: Execute the connector via the cloud API
|
|
138
|
+
response = await self._cloud_client.execute_connector(
|
|
139
|
+
connector_id=connector_id,
|
|
140
|
+
entity=config.entity,
|
|
141
|
+
action=config.action,
|
|
142
|
+
params=config.params,
|
|
143
|
+
)
|
|
148
144
|
|
|
149
|
-
# Parse
|
|
150
|
-
|
|
145
|
+
# Step 4: Parse the response into ExecutionResult
|
|
146
|
+
result = self._parse_execution_result(response)
|
|
151
147
|
|
|
152
148
|
# Mark span as successful
|
|
153
|
-
span.set_attribute("connector.success",
|
|
149
|
+
span.set_attribute("connector.success", result.success)
|
|
154
150
|
|
|
155
|
-
|
|
156
|
-
return ExecutionResult(success=True, data=result_data, error=None)
|
|
151
|
+
return result
|
|
157
152
|
|
|
158
|
-
except
|
|
159
|
-
#
|
|
153
|
+
except ValueError as e:
|
|
154
|
+
# Connector lookup validation error (0 or >1 connectors)
|
|
160
155
|
span.set_attribute("connector.success", False)
|
|
161
|
-
span.set_attribute("connector.error_type", "
|
|
162
|
-
span.set_attribute("http.status_code", e.response.status_code)
|
|
156
|
+
span.set_attribute("connector.error_type", "ValueError")
|
|
163
157
|
span.record_exception(e)
|
|
164
158
|
raise
|
|
165
159
|
|
|
166
160
|
except Exception as e:
|
|
167
|
-
#
|
|
161
|
+
# HTTP errors and other exceptions
|
|
168
162
|
span.set_attribute("connector.success", False)
|
|
169
163
|
span.set_attribute("connector.error_type", type(e).__name__)
|
|
170
164
|
span.record_exception(e)
|
|
171
165
|
raise
|
|
172
166
|
|
|
173
|
-
def
|
|
174
|
-
"""
|
|
167
|
+
def _parse_execution_result(self, response: dict) -> ExecutionResult:
|
|
168
|
+
"""Parse API response into ExecutionResult.
|
|
175
169
|
|
|
176
|
-
|
|
170
|
+
Args:
|
|
171
|
+
response_data: Raw JSON response from the cloud API
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
ExecutionResult with parsed data
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
return ExecutionResult(
|
|
178
|
+
success=True,
|
|
179
|
+
data=response["result"],
|
|
180
|
+
meta=response.get("connector_metadata"),
|
|
181
|
+
error=None,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
async def close(self):
|
|
185
|
+
"""Close the cloud client and cleanup resources.
|
|
186
|
+
|
|
187
|
+
Call this when you're done using the executor to clean up HTTP connections.
|
|
177
188
|
|
|
178
189
|
Example:
|
|
179
|
-
executor = HostedExecutor(
|
|
180
|
-
workspace_id="workspace-123",
|
|
181
|
-
connector_id="my-connector"
|
|
182
|
-
)
|
|
190
|
+
executor = HostedExecutor(...)
|
|
183
191
|
try:
|
|
184
192
|
result = await executor.execute(config)
|
|
185
193
|
finally:
|
|
186
|
-
executor.close()
|
|
194
|
+
await executor.close()
|
|
187
195
|
"""
|
|
188
|
-
self.
|
|
196
|
+
await self._cloud_client.close()
|