airbyte-agent-airtable 0.1.5__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.
Potentially problematic release.
This version of airbyte-agent-airtable might be problematic. Click here for more details.
- airbyte_agent_airtable/__init__.py +81 -0
- airbyte_agent_airtable/_vendored/__init__.py +1 -0
- airbyte_agent_airtable/_vendored/connector_sdk/__init__.py +82 -0
- airbyte_agent_airtable/_vendored/connector_sdk/auth_strategies.py +1171 -0
- airbyte_agent_airtable/_vendored/connector_sdk/auth_template.py +135 -0
- airbyte_agent_airtable/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
- airbyte_agent_airtable/_vendored/connector_sdk/cloud_utils/client.py +338 -0
- airbyte_agent_airtable/_vendored/connector_sdk/connector_model_loader.py +1121 -0
- airbyte_agent_airtable/_vendored/connector_sdk/constants.py +78 -0
- airbyte_agent_airtable/_vendored/connector_sdk/exceptions.py +23 -0
- airbyte_agent_airtable/_vendored/connector_sdk/executor/__init__.py +31 -0
- airbyte_agent_airtable/_vendored/connector_sdk/executor/hosted_executor.py +230 -0
- airbyte_agent_airtable/_vendored/connector_sdk/executor/local_executor.py +1848 -0
- airbyte_agent_airtable/_vendored/connector_sdk/executor/models.py +202 -0
- airbyte_agent_airtable/_vendored/connector_sdk/extensions.py +693 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/__init__.py +37 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/adapters/httpx_adapter.py +260 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/config.py +98 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/exceptions.py +119 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/protocols.py +114 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http/response.py +104 -0
- airbyte_agent_airtable/_vendored/connector_sdk/http_client.py +693 -0
- airbyte_agent_airtable/_vendored/connector_sdk/introspection.py +481 -0
- airbyte_agent_airtable/_vendored/connector_sdk/logging/__init__.py +11 -0
- airbyte_agent_airtable/_vendored/connector_sdk/logging/logger.py +273 -0
- airbyte_agent_airtable/_vendored/connector_sdk/logging/types.py +93 -0
- airbyte_agent_airtable/_vendored/connector_sdk/observability/__init__.py +11 -0
- airbyte_agent_airtable/_vendored/connector_sdk/observability/config.py +179 -0
- airbyte_agent_airtable/_vendored/connector_sdk/observability/models.py +19 -0
- airbyte_agent_airtable/_vendored/connector_sdk/observability/redactor.py +81 -0
- airbyte_agent_airtable/_vendored/connector_sdk/observability/session.py +103 -0
- airbyte_agent_airtable/_vendored/connector_sdk/performance/__init__.py +6 -0
- airbyte_agent_airtable/_vendored/connector_sdk/performance/instrumentation.py +57 -0
- airbyte_agent_airtable/_vendored/connector_sdk/performance/metrics.py +93 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/__init__.py +75 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/base.py +212 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/components.py +244 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/connector.py +120 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/extensions.py +301 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/operations.py +156 -0
- airbyte_agent_airtable/_vendored/connector_sdk/schema/security.py +241 -0
- airbyte_agent_airtable/_vendored/connector_sdk/secrets.py +182 -0
- airbyte_agent_airtable/_vendored/connector_sdk/telemetry/__init__.py +10 -0
- airbyte_agent_airtable/_vendored/connector_sdk/telemetry/config.py +32 -0
- airbyte_agent_airtable/_vendored/connector_sdk/telemetry/events.py +59 -0
- airbyte_agent_airtable/_vendored/connector_sdk/telemetry/tracker.py +155 -0
- airbyte_agent_airtable/_vendored/connector_sdk/types.py +274 -0
- airbyte_agent_airtable/_vendored/connector_sdk/utils.py +127 -0
- airbyte_agent_airtable/_vendored/connector_sdk/validation.py +997 -0
- airbyte_agent_airtable/_vendored/connector_sdk/validation_replication.py +970 -0
- airbyte_agent_airtable/connector.py +834 -0
- airbyte_agent_airtable/connector_model.py +365 -0
- airbyte_agent_airtable/models.py +219 -0
- airbyte_agent_airtable/types.py +367 -0
- airbyte_agent_airtable-0.1.5.dist-info/METADATA +140 -0
- airbyte_agent_airtable-0.1.5.dist-info/RECORD +58 -0
- airbyte_agent_airtable-0.1.5.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Constants used throughout the Airbyte SDK.
|
|
3
|
+
|
|
4
|
+
This module centralizes configuration defaults and commonly used values to improve
|
|
5
|
+
maintainability and consistency across the codebase.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
11
|
+
|
|
12
|
+
# ============================================================================
|
|
13
|
+
# HTTP Connection and Timeout Defaults
|
|
14
|
+
# ============================================================================
|
|
15
|
+
|
|
16
|
+
# Connection pooling limits
|
|
17
|
+
DEFAULT_MAX_CONNECTIONS = 100
|
|
18
|
+
"""Maximum number of concurrent HTTP connections to maintain in the pool."""
|
|
19
|
+
|
|
20
|
+
DEFAULT_MAX_KEEPALIVE_CONNECTIONS = 20
|
|
21
|
+
"""Maximum number of keepalive connections to maintain in the pool."""
|
|
22
|
+
|
|
23
|
+
# Timeout values (in seconds)
|
|
24
|
+
DEFAULT_CONNECT_TIMEOUT = 5.0
|
|
25
|
+
"""Default timeout for establishing a new connection (seconds)."""
|
|
26
|
+
|
|
27
|
+
DEFAULT_READ_TIMEOUT = 30.0
|
|
28
|
+
"""Default timeout for reading response data (seconds)."""
|
|
29
|
+
|
|
30
|
+
DEFAULT_WRITE_TIMEOUT = 30.0
|
|
31
|
+
"""Default timeout for writing request data (seconds)."""
|
|
32
|
+
|
|
33
|
+
DEFAULT_POOL_TIMEOUT = 5.0
|
|
34
|
+
"""Default timeout for acquiring a connection from the pool (seconds)."""
|
|
35
|
+
|
|
36
|
+
DEFAULT_REQUEST_TIMEOUT = 30.0
|
|
37
|
+
"""Default overall request timeout (seconds)."""
|
|
38
|
+
|
|
39
|
+
# ============================================================================
|
|
40
|
+
# OpenAPI Specification
|
|
41
|
+
# ============================================================================
|
|
42
|
+
|
|
43
|
+
OPENAPI_VERSION_PREFIX = "3.1."
|
|
44
|
+
"""Required OpenAPI version prefix. Only 3.1.x specifications are supported."""
|
|
45
|
+
|
|
46
|
+
OPENAPI_DEFAULT_VERSION = "1.0.0"
|
|
47
|
+
"""Default version string for connectors that don't specify a version."""
|
|
48
|
+
|
|
49
|
+
# ============================================================================
|
|
50
|
+
# Performance and Metrics
|
|
51
|
+
# ============================================================================
|
|
52
|
+
|
|
53
|
+
MILLISECONDS_PER_SECOND = 1000
|
|
54
|
+
"""Conversion factor from seconds to milliseconds."""
|
|
55
|
+
|
|
56
|
+
# ============================================================================
|
|
57
|
+
# Retry and Backoff Defaults
|
|
58
|
+
# ============================================================================
|
|
59
|
+
|
|
60
|
+
DEFAULT_INITIAL_DELAY_SECONDS = 1.0
|
|
61
|
+
"""Default initial delay for retry backoff (seconds)."""
|
|
62
|
+
|
|
63
|
+
DEFAULT_MAX_DELAY_SECONDS = 60.0
|
|
64
|
+
"""Default maximum delay for retry backoff (seconds)."""
|
|
65
|
+
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# SDK Version
|
|
68
|
+
# ============================================================================
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
SDK_VERSION = version("connector-sdk")
|
|
72
|
+
except PackageNotFoundError:
|
|
73
|
+
# Fallback for development when package isn't installed
|
|
74
|
+
SDK_VERSION = "0.0.0-dev"
|
|
75
|
+
"""Current version of the Airbyte SDK."""
|
|
76
|
+
|
|
77
|
+
MINIMUM_PYTHON_VERSION = "3.13"
|
|
78
|
+
"""Minimum Python version required to run the SDK."""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Exceptions for the Airbyte SDK.
|
|
2
|
+
|
|
3
|
+
DEPRECATED: HTTP exceptions have been moved to connector_sdk.http.exceptions.
|
|
4
|
+
This module re-exports them for backward compatibility.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .http.exceptions import (
|
|
8
|
+
AuthenticationError,
|
|
9
|
+
HTTPClientError,
|
|
10
|
+
HTTPStatusError,
|
|
11
|
+
NetworkError,
|
|
12
|
+
RateLimitError,
|
|
13
|
+
TimeoutError,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"HTTPClientError",
|
|
18
|
+
"HTTPStatusError",
|
|
19
|
+
"AuthenticationError",
|
|
20
|
+
"RateLimitError",
|
|
21
|
+
"NetworkError",
|
|
22
|
+
"TimeoutError",
|
|
23
|
+
]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Executor implementations for connector operations."""
|
|
2
|
+
|
|
3
|
+
from .hosted_executor import HostedExecutor
|
|
4
|
+
from .local_executor import LocalExecutor
|
|
5
|
+
from .models import (
|
|
6
|
+
ActionNotSupportedError,
|
|
7
|
+
EntityNotFoundError,
|
|
8
|
+
ExecutionConfig,
|
|
9
|
+
ExecutionResult,
|
|
10
|
+
ExecutorError,
|
|
11
|
+
ExecutorProtocol,
|
|
12
|
+
InvalidParameterError,
|
|
13
|
+
MissingParameterError,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
# Config and Result types
|
|
18
|
+
"ExecutionConfig",
|
|
19
|
+
"ExecutionResult",
|
|
20
|
+
# Protocol
|
|
21
|
+
"ExecutorProtocol",
|
|
22
|
+
# Executors
|
|
23
|
+
"LocalExecutor",
|
|
24
|
+
"HostedExecutor",
|
|
25
|
+
# Exceptions
|
|
26
|
+
"ExecutorError",
|
|
27
|
+
"EntityNotFoundError",
|
|
28
|
+
"ActionNotSupportedError",
|
|
29
|
+
"MissingParameterError",
|
|
30
|
+
"InvalidParameterError",
|
|
31
|
+
]
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""Hosted executor for proxying operations through the cloud API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from opentelemetry import trace
|
|
6
|
+
|
|
7
|
+
from ..cloud_utils import AirbyteCloudClient
|
|
8
|
+
|
|
9
|
+
from .models import (
|
|
10
|
+
ExecutionConfig,
|
|
11
|
+
ExecutionResult,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class HostedExecutor:
|
|
16
|
+
"""Executor that proxies execution through the Airbyte Cloud API.
|
|
17
|
+
|
|
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
|
|
20
|
+
connector logic, secrets management, and execution.
|
|
21
|
+
|
|
22
|
+
The executor uses the AirbyteCloudClient to:
|
|
23
|
+
1. Authenticate with the Airbyte Platform (bearer token with caching)
|
|
24
|
+
2. Look up the user's connector (if connector_id not provided)
|
|
25
|
+
3. Execute the connector operation via the cloud API
|
|
26
|
+
|
|
27
|
+
Implements ExecutorProtocol.
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
# Create executor with explicit connector_id (no lookup needed)
|
|
31
|
+
executor = HostedExecutor(
|
|
32
|
+
airbyte_client_id="client_abc123",
|
|
33
|
+
airbyte_client_secret="secret_xyz789",
|
|
34
|
+
connector_id="existing-source-uuid",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Or create executor with user ID for lookup
|
|
38
|
+
executor = HostedExecutor(
|
|
39
|
+
airbyte_client_id="client_abc123",
|
|
40
|
+
airbyte_client_secret="secret_xyz789",
|
|
41
|
+
external_user_id="user-123",
|
|
42
|
+
connector_definition_id="abc123-def456-ghi789",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Execute an operation
|
|
46
|
+
execution_config = ExecutionConfig(
|
|
47
|
+
entity="customers",
|
|
48
|
+
action="list",
|
|
49
|
+
params={"limit": 10}
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
result = await executor.execute(execution_config)
|
|
53
|
+
if result.success:
|
|
54
|
+
print(f"Data: {result.data}")
|
|
55
|
+
else:
|
|
56
|
+
print(f"Error: {result.error}")
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __init__(
|
|
60
|
+
self,
|
|
61
|
+
airbyte_client_id: str,
|
|
62
|
+
airbyte_client_secret: str,
|
|
63
|
+
connector_id: str | None = None,
|
|
64
|
+
external_user_id: str | None = None,
|
|
65
|
+
connector_definition_id: str | None = None,
|
|
66
|
+
):
|
|
67
|
+
"""Initialize hosted executor.
|
|
68
|
+
|
|
69
|
+
Either provide connector_id directly OR (external_user_id + connector_definition_id)
|
|
70
|
+
for lookup.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
airbyte_client_id: Airbyte client ID for authentication
|
|
74
|
+
airbyte_client_secret: Airbyte client secret for authentication
|
|
75
|
+
connector_id: Direct connector/source ID (skips lookup if provided)
|
|
76
|
+
external_user_id: User identifier in the Airbyte system (for lookup)
|
|
77
|
+
connector_definition_id: Connector definition ID (for lookup)
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
ValueError: If neither connector_id nor (external_user_id + connector_definition_id) provided
|
|
81
|
+
|
|
82
|
+
Example:
|
|
83
|
+
# With explicit connector_id (no lookup)
|
|
84
|
+
executor = HostedExecutor(
|
|
85
|
+
airbyte_client_id="client_abc123",
|
|
86
|
+
airbyte_client_secret="secret_xyz789",
|
|
87
|
+
connector_id="existing-source-uuid",
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# With lookup by user + definition
|
|
91
|
+
executor = HostedExecutor(
|
|
92
|
+
airbyte_client_id="client_abc123",
|
|
93
|
+
airbyte_client_secret="secret_xyz789",
|
|
94
|
+
external_user_id="user-123",
|
|
95
|
+
connector_definition_id="abc123-def456-ghi789",
|
|
96
|
+
)
|
|
97
|
+
"""
|
|
98
|
+
# Validate: either connector_id OR (external_user_id + connector_definition_id) required
|
|
99
|
+
if not connector_id and not (external_user_id and connector_definition_id):
|
|
100
|
+
raise ValueError("Either connector_id OR (external_user_id + connector_definition_id) must be provided")
|
|
101
|
+
|
|
102
|
+
self._connector_id = connector_id
|
|
103
|
+
self._external_user_id = external_user_id
|
|
104
|
+
self._connector_definition_id = connector_definition_id
|
|
105
|
+
|
|
106
|
+
# Create AirbyteCloudClient for API interactions
|
|
107
|
+
self._cloud_client = AirbyteCloudClient(
|
|
108
|
+
client_id=airbyte_client_id,
|
|
109
|
+
client_secret=airbyte_client_secret,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
async def execute(self, config: ExecutionConfig) -> ExecutionResult:
|
|
113
|
+
"""Execute connector via cloud API (ExecutorProtocol implementation).
|
|
114
|
+
|
|
115
|
+
Flow:
|
|
116
|
+
1. Use provided connector_id or look up from external_user_id + definition_id
|
|
117
|
+
2. Execute the connector operation via the cloud API
|
|
118
|
+
3. Parse the response into ExecutionResult
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
config: Execution configuration (entity, action, params)
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
ExecutionResult with success/failure status
|
|
125
|
+
|
|
126
|
+
Raises:
|
|
127
|
+
ValueError: If no connector or multiple connectors found for user (when doing lookup)
|
|
128
|
+
httpx.HTTPStatusError: If API returns 4xx/5xx status code
|
|
129
|
+
httpx.RequestError: If network request fails
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
config = ExecutionConfig(
|
|
133
|
+
entity="customers",
|
|
134
|
+
action="list",
|
|
135
|
+
params={"limit": 10}
|
|
136
|
+
)
|
|
137
|
+
result = await executor.execute(config)
|
|
138
|
+
"""
|
|
139
|
+
tracer = trace.get_tracer("airbyte.connector-sdk.executor.hosted")
|
|
140
|
+
|
|
141
|
+
with tracer.start_as_current_span("airbyte.hosted_executor.execute") as span:
|
|
142
|
+
# Add span attributes for observability
|
|
143
|
+
if self._connector_definition_id:
|
|
144
|
+
span.set_attribute("connector.definition_id", self._connector_definition_id)
|
|
145
|
+
span.set_attribute("connector.entity", config.entity)
|
|
146
|
+
span.set_attribute("connector.action", config.action)
|
|
147
|
+
if self._external_user_id:
|
|
148
|
+
span.set_attribute("user.external_id", self._external_user_id)
|
|
149
|
+
if config.params:
|
|
150
|
+
# Only add non-sensitive param keys
|
|
151
|
+
span.set_attribute("connector.param_keys", list(config.params.keys()))
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
# Use provided connector_id or look it up
|
|
155
|
+
if self._connector_id:
|
|
156
|
+
connector_id = self._connector_id
|
|
157
|
+
else:
|
|
158
|
+
# Look up connector by external_user_id + definition_id
|
|
159
|
+
connector_id = await self._cloud_client.get_connector_id(
|
|
160
|
+
external_user_id=self._external_user_id, # type: ignore[arg-type]
|
|
161
|
+
connector_definition_id=self._connector_definition_id, # type: ignore[arg-type]
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
span.set_attribute("connector.connector_id", connector_id)
|
|
165
|
+
|
|
166
|
+
# Step 3: Execute the connector via the cloud API
|
|
167
|
+
response = await self._cloud_client.execute_connector(
|
|
168
|
+
connector_id=connector_id,
|
|
169
|
+
entity=config.entity,
|
|
170
|
+
action=config.action,
|
|
171
|
+
params=config.params,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Step 4: Parse the response into ExecutionResult
|
|
175
|
+
result = self._parse_execution_result(response)
|
|
176
|
+
|
|
177
|
+
# Mark span as successful
|
|
178
|
+
span.set_attribute("connector.success", result.success)
|
|
179
|
+
|
|
180
|
+
return result
|
|
181
|
+
|
|
182
|
+
except ValueError as e:
|
|
183
|
+
# Connector lookup validation error (0 or >1 connectors)
|
|
184
|
+
span.set_attribute("connector.success", False)
|
|
185
|
+
span.set_attribute("connector.error_type", "ValueError")
|
|
186
|
+
span.record_exception(e)
|
|
187
|
+
raise
|
|
188
|
+
|
|
189
|
+
except Exception as e:
|
|
190
|
+
# HTTP errors and other exceptions
|
|
191
|
+
span.set_attribute("connector.success", False)
|
|
192
|
+
span.set_attribute("connector.error_type", type(e).__name__)
|
|
193
|
+
span.record_exception(e)
|
|
194
|
+
raise
|
|
195
|
+
|
|
196
|
+
async def check(self) -> ExecutionResult:
|
|
197
|
+
"""Perform a health check via the cloud API."""
|
|
198
|
+
config = ExecutionConfig(entity="*", action="check", params={})
|
|
199
|
+
return await self.execute(config)
|
|
200
|
+
|
|
201
|
+
def _parse_execution_result(self, response: dict) -> ExecutionResult:
|
|
202
|
+
"""Parse API response into ExecutionResult.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
response_data: Raw JSON response from the cloud API
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
ExecutionResult with parsed data
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
return ExecutionResult(
|
|
212
|
+
success=True,
|
|
213
|
+
data=response["result"],
|
|
214
|
+
meta=response.get("connector_metadata"),
|
|
215
|
+
error=None,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
async def close(self):
|
|
219
|
+
"""Close the cloud client and cleanup resources.
|
|
220
|
+
|
|
221
|
+
Call this when you're done using the executor to clean up HTTP connections.
|
|
222
|
+
|
|
223
|
+
Example:
|
|
224
|
+
executor = HostedExecutor(...)
|
|
225
|
+
try:
|
|
226
|
+
result = await executor.execute(config)
|
|
227
|
+
finally:
|
|
228
|
+
await executor.close()
|
|
229
|
+
"""
|
|
230
|
+
await self._cloud_client.close()
|