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,244 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Component models for OpenAPI 3.1: Schema, Parameter, RequestBody, Response, Components.
|
|
3
|
+
|
|
4
|
+
References:
|
|
5
|
+
- https://spec.openapis.org/oas/v3.1.0#components-object
|
|
6
|
+
- https://spec.openapis.org/oas/v3.1.0#schema-object
|
|
7
|
+
- https://spec.openapis.org/oas/v3.1.0#parameter-object
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, List, Literal, Union
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
13
|
+
|
|
14
|
+
from .security import SecurityScheme
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Schema(BaseModel):
|
|
18
|
+
"""
|
|
19
|
+
JSON Schema definition for data models.
|
|
20
|
+
|
|
21
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#schema-object
|
|
22
|
+
|
|
23
|
+
Note: Uses Dict[str, Any] for properties to support nested schemas and $ref.
|
|
24
|
+
Reference resolution happens at runtime in config_loader.py.
|
|
25
|
+
|
|
26
|
+
Extensions:
|
|
27
|
+
- x-airbyte-resource-name: Name of the resource this schema represents (Airbyte extension)
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
31
|
+
|
|
32
|
+
# Core JSON Schema fields
|
|
33
|
+
type: str | None = None
|
|
34
|
+
format: str | None = None
|
|
35
|
+
title: str | None = None
|
|
36
|
+
description: str | None = None
|
|
37
|
+
default: Any | None = None
|
|
38
|
+
example: Any | None = None
|
|
39
|
+
|
|
40
|
+
# Object properties
|
|
41
|
+
properties: Dict[str, Any] = Field(default_factory=dict) # May contain $ref
|
|
42
|
+
required: List[str] = Field(default_factory=list)
|
|
43
|
+
additional_properties: Any | None = Field(None, alias="additionalProperties")
|
|
44
|
+
|
|
45
|
+
# Array properties
|
|
46
|
+
items: Any | None = None # May be Schema or $ref
|
|
47
|
+
|
|
48
|
+
# Validation
|
|
49
|
+
enum: List[Any] | None = None
|
|
50
|
+
min_length: int | None = Field(None, alias="minLength")
|
|
51
|
+
max_length: int | None = Field(None, alias="maxLength")
|
|
52
|
+
minimum: float | None = None
|
|
53
|
+
maximum: float | None = None
|
|
54
|
+
pattern: str | None = None
|
|
55
|
+
|
|
56
|
+
# Composition
|
|
57
|
+
all_of: List[Any] | None = Field(None, alias="allOf")
|
|
58
|
+
any_of: List[Any] | None = Field(None, alias="anyOf")
|
|
59
|
+
one_of: List[Any] | None = Field(None, alias="oneOf")
|
|
60
|
+
not_: Any | None = Field(None, alias="not")
|
|
61
|
+
|
|
62
|
+
# Metadata
|
|
63
|
+
nullable: bool | None = Field(None, deprecated="Use type union with null instead (OpenAPI 3.1)")
|
|
64
|
+
read_only: bool | None = Field(None, alias="readOnly")
|
|
65
|
+
write_only: bool | None = Field(None, alias="writeOnly")
|
|
66
|
+
deprecated: bool | None = None
|
|
67
|
+
|
|
68
|
+
# Airbyte extensions
|
|
69
|
+
x_airbyte_entity_name: str | None = Field(None, alias="x-airbyte-entity-name")
|
|
70
|
+
x_airbyte_stream_name: str | None = Field(None, alias="x-airbyte-stream-name")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class Parameter(BaseModel):
|
|
74
|
+
"""
|
|
75
|
+
Operation parameter definition.
|
|
76
|
+
|
|
77
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#parameter-object
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
81
|
+
|
|
82
|
+
name: str
|
|
83
|
+
in_: Literal["query", "header", "path", "cookie"] = Field(alias="in")
|
|
84
|
+
description: str | None = None
|
|
85
|
+
required: bool | None = None
|
|
86
|
+
deprecated: bool | None = None
|
|
87
|
+
allow_empty_value: bool | None = Field(None, alias="allowEmptyValue")
|
|
88
|
+
|
|
89
|
+
# Schema can be inline or reference
|
|
90
|
+
schema_: Dict[str, Any] | None = Field(None, alias="schema")
|
|
91
|
+
|
|
92
|
+
# Style and examples
|
|
93
|
+
style: str | None = None
|
|
94
|
+
explode: bool | None = None
|
|
95
|
+
example: Any | None = None
|
|
96
|
+
examples: Dict[str, Any] | None = None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class MediaType(BaseModel):
|
|
100
|
+
"""
|
|
101
|
+
Media type object for request/response content.
|
|
102
|
+
|
|
103
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#media-type-object
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
107
|
+
|
|
108
|
+
schema_: Dict[str, Any] | None = Field(None, alias="schema")
|
|
109
|
+
example: Any | None = None
|
|
110
|
+
examples: Dict[str, Any] | None = None
|
|
111
|
+
encoding: Dict[str, Any] | None = None
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class GraphQLBodyConfig(BaseModel):
|
|
115
|
+
"""
|
|
116
|
+
GraphQL body type configuration for x-airbyte-body-type extension.
|
|
117
|
+
|
|
118
|
+
Used when x-airbyte-body-type.type = "graphql"
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
122
|
+
|
|
123
|
+
type: Literal["graphql"] = Field(..., description="Body type identifier (must be 'graphql')")
|
|
124
|
+
query: str = Field(
|
|
125
|
+
...,
|
|
126
|
+
description="GraphQL query or mutation string with optional template placeholders (e.g., {{ variable }})",
|
|
127
|
+
)
|
|
128
|
+
variables: Dict[str, Any] | None = Field(
|
|
129
|
+
None,
|
|
130
|
+
description="Variables to substitute in the GraphQL query using template syntax (e.g., {{ param_name }})",
|
|
131
|
+
)
|
|
132
|
+
operationName: str | None = Field(None, description="Operation name for queries with multiple operations")
|
|
133
|
+
default_fields: Union[str, List[str]] | None = Field(
|
|
134
|
+
None,
|
|
135
|
+
description="Default fields to select if not provided in request parameters. Can be a string or array of field names.",
|
|
136
|
+
)
|
|
137
|
+
nullable_variables: List[str] | None = Field(
|
|
138
|
+
default=None,
|
|
139
|
+
alias="x-airbyte-nullable-variables",
|
|
140
|
+
description="Variable names that can be explicitly set to null (e.g., to unassign a user)",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# Union type for all body type configs (extensible for future types like XML, SOAP, etc.)
|
|
145
|
+
BodyTypeConfig = Union[GraphQLBodyConfig]
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class PathOverrideConfig(BaseModel):
|
|
149
|
+
"""
|
|
150
|
+
Path override configuration for x-airbyte-path-override extension.
|
|
151
|
+
|
|
152
|
+
Used when the OpenAPI path differs from the actual HTTP endpoint path.
|
|
153
|
+
Common for GraphQL APIs where multiple resources share the same endpoint (e.g., /graphql).
|
|
154
|
+
|
|
155
|
+
Example:
|
|
156
|
+
OpenAPI path: /graphql:repositories (for uniqueness)
|
|
157
|
+
Actual HTTP path: /graphql (configured here)
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
161
|
+
|
|
162
|
+
path: str = Field(
|
|
163
|
+
...,
|
|
164
|
+
description=("Actual HTTP path to use for requests (e.g., '/graphql'). Must start with '/'"),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class RequestBody(BaseModel):
|
|
169
|
+
"""
|
|
170
|
+
Request body definition.
|
|
171
|
+
|
|
172
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#request-body-object
|
|
173
|
+
|
|
174
|
+
Airbyte Extensions:
|
|
175
|
+
See connector_sdk.extensions for documentation:
|
|
176
|
+
- AIRBYTE_BODY_TYPE: Body type and configuration (nested structure)
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
180
|
+
|
|
181
|
+
description: str | None = None
|
|
182
|
+
content: Dict[str, MediaType] = Field(default_factory=dict)
|
|
183
|
+
required: bool | None = None
|
|
184
|
+
|
|
185
|
+
# Airbyte extensions for GraphQL support
|
|
186
|
+
# See connector_sdk.extensions for AIRBYTE_BODY_TYPE constant
|
|
187
|
+
x_airbyte_body_type: BodyTypeConfig | None = Field(
|
|
188
|
+
None,
|
|
189
|
+
alias="x-airbyte-body-type", # AIRBYTE_BODY_TYPE
|
|
190
|
+
description=(
|
|
191
|
+
"Body type and configuration. Contains 'type' field (e.g., 'graphql') and type-specific configuration (query, variables, etc.)."
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
class Header(BaseModel):
|
|
197
|
+
"""
|
|
198
|
+
Header definition.
|
|
199
|
+
|
|
200
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#header-object
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
204
|
+
|
|
205
|
+
description: str | None = None
|
|
206
|
+
required: bool | None = None
|
|
207
|
+
deprecated: bool | None = None
|
|
208
|
+
schema_: Dict[str, Any] | None = Field(None, alias="schema")
|
|
209
|
+
example: Any | None = None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class Response(BaseModel):
|
|
213
|
+
"""
|
|
214
|
+
Response definition.
|
|
215
|
+
|
|
216
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#response-object
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
220
|
+
|
|
221
|
+
description: str
|
|
222
|
+
headers: Dict[str, Header] | None = None
|
|
223
|
+
content: Dict[str, MediaType] | None = None
|
|
224
|
+
links: Dict[str, Any] | None = None
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class Components(BaseModel):
|
|
228
|
+
"""
|
|
229
|
+
Reusable component definitions.
|
|
230
|
+
|
|
231
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#components-object
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
235
|
+
|
|
236
|
+
schemas: Dict[str, Schema] = Field(default_factory=dict)
|
|
237
|
+
responses: Dict[str, Response] = Field(default_factory=dict)
|
|
238
|
+
parameters: Dict[str, Parameter] = Field(default_factory=dict)
|
|
239
|
+
examples: Dict[str, Any] | None = None
|
|
240
|
+
request_bodies: Dict[str, RequestBody] = Field(default_factory=dict, alias="requestBodies")
|
|
241
|
+
headers: Dict[str, Header] | None = None
|
|
242
|
+
security_schemes: Dict[str, SecurityScheme] = Field(default_factory=dict, alias="securitySchemes")
|
|
243
|
+
links: Dict[str, Any] | None = None
|
|
244
|
+
callbacks: Dict[str, Any] | None = None
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Root OpenAPI 3.1 connector specification model.
|
|
3
|
+
|
|
4
|
+
References:
|
|
5
|
+
- https://spec.openapis.org/oas/v3.1.0#openapi-object
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Iterator
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
14
|
+
|
|
15
|
+
from ..constants import OPENAPI_VERSION_PREFIX
|
|
16
|
+
|
|
17
|
+
from .base import Info, Server
|
|
18
|
+
from .components import Components
|
|
19
|
+
from .operations import Operation, PathItem
|
|
20
|
+
from .security import SecurityRequirement
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Tag(BaseModel):
|
|
24
|
+
"""
|
|
25
|
+
Tag metadata for grouping operations.
|
|
26
|
+
|
|
27
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#tag-object
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
31
|
+
|
|
32
|
+
name: str
|
|
33
|
+
description: str | None = None
|
|
34
|
+
external_docs: dict[str, Any] | None = Field(None, alias="externalDocs")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# HTTP methods supported by OpenAPI operations
|
|
38
|
+
HTTP_METHODS = frozenset({"get", "post", "put", "patch", "delete", "options", "head", "trace"})
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ExternalDocs(BaseModel):
|
|
42
|
+
"""
|
|
43
|
+
External documentation reference.
|
|
44
|
+
|
|
45
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#external-documentation-object
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
49
|
+
|
|
50
|
+
description: str | None = None
|
|
51
|
+
url: str
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class OpenAPIConnector(BaseModel):
|
|
55
|
+
"""
|
|
56
|
+
Root OpenAPI 3.1 connector specification.
|
|
57
|
+
|
|
58
|
+
OpenAPI Reference: https://spec.openapis.org/oas/v3.1.0#openapi-object
|
|
59
|
+
|
|
60
|
+
This is the top-level model that represents a complete OpenAPI 3.1 specification
|
|
61
|
+
for an Airbyte connector. It enforces strict validation (extra='forbid') to catch
|
|
62
|
+
typos and unknown extensions.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid", validate_default=True)
|
|
66
|
+
|
|
67
|
+
# Required fields
|
|
68
|
+
openapi: str
|
|
69
|
+
info: Info
|
|
70
|
+
paths: dict[str, PathItem] = Field(default_factory=dict)
|
|
71
|
+
|
|
72
|
+
# Optional fields
|
|
73
|
+
servers: list[Server] = Field(default_factory=list)
|
|
74
|
+
components: Components | None = None
|
|
75
|
+
security: list[SecurityRequirement] | None = None
|
|
76
|
+
tags: list[Tag] | None = None
|
|
77
|
+
external_docs: ExternalDocs | None = Field(None, alias="externalDocs")
|
|
78
|
+
|
|
79
|
+
@field_validator("openapi")
|
|
80
|
+
@classmethod
|
|
81
|
+
def validate_openapi_version(cls, v: str) -> str:
|
|
82
|
+
"""Validate that OpenAPI version is 3.1.x."""
|
|
83
|
+
if not v.startswith(OPENAPI_VERSION_PREFIX):
|
|
84
|
+
raise ValueError(f"OpenAPI version must be {OPENAPI_VERSION_PREFIX}x, got: {v}")
|
|
85
|
+
return v
|
|
86
|
+
|
|
87
|
+
def get_entity_operations(self, entity_name: str) -> list[tuple[str, str, Operation]]:
|
|
88
|
+
"""
|
|
89
|
+
Get all operations for a specific entity.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
entity_name: The x-airbyte-entity value to filter by
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
List of tuples: (path, method, operation)
|
|
96
|
+
"""
|
|
97
|
+
return [(path, method, op) for path, method, op in self._iter_operations() if op.x_airbyte_entity == entity_name]
|
|
98
|
+
|
|
99
|
+
def list_entities(self) -> list[str]:
|
|
100
|
+
"""
|
|
101
|
+
List all unique entity names defined in x-airbyte-entity extensions.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Sorted list of unique entity names
|
|
105
|
+
"""
|
|
106
|
+
entities = {op.x_airbyte_entity for _, _, op in self._iter_operations() if op.x_airbyte_entity}
|
|
107
|
+
return sorted(entities)
|
|
108
|
+
|
|
109
|
+
def _iter_operations(self) -> Iterator[tuple[str, str, Operation]]:
|
|
110
|
+
"""
|
|
111
|
+
Iterate over all operations in the spec.
|
|
112
|
+
|
|
113
|
+
Yields:
|
|
114
|
+
Tuples of (path, method, operation) for each defined operation
|
|
115
|
+
"""
|
|
116
|
+
for path, path_item in self.paths.items():
|
|
117
|
+
for method in HTTP_METHODS:
|
|
118
|
+
operation = getattr(path_item, method, None)
|
|
119
|
+
if operation:
|
|
120
|
+
yield path, method, operation
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Extension models for future features.
|
|
3
|
+
|
|
4
|
+
These models are defined but NOT yet added to the main schema models.
|
|
5
|
+
They serve as:
|
|
6
|
+
1. Type hints for future use
|
|
7
|
+
2. Documentation of planned extensions
|
|
8
|
+
3. Ready-to-use structures when features are implemented
|
|
9
|
+
|
|
10
|
+
NOTE: These are not currently active in the schema. They will be added
|
|
11
|
+
to Operation, Schema, or other models when their respective features
|
|
12
|
+
are implemented.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Literal
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class PaginationConfig(BaseModel):
|
|
21
|
+
"""
|
|
22
|
+
Configuration for pagination support.
|
|
23
|
+
|
|
24
|
+
NOT YET USED - Defined for future implementation.
|
|
25
|
+
|
|
26
|
+
When active, will be added to Operation model as:
|
|
27
|
+
x_pagination: Optional[PaginationConfig] = Field(None, alias="x-pagination")
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
31
|
+
|
|
32
|
+
style: Literal["cursor", "offset", "page", "link"]
|
|
33
|
+
limit_param: str = "limit"
|
|
34
|
+
|
|
35
|
+
# Cursor-based pagination
|
|
36
|
+
cursor_param: str | None = None
|
|
37
|
+
cursor_source: Literal["body", "headers"] | None = "body"
|
|
38
|
+
cursor_path: str | None = None
|
|
39
|
+
|
|
40
|
+
# Offset-based pagination
|
|
41
|
+
offset_param: str | None = None
|
|
42
|
+
|
|
43
|
+
# Page-based pagination
|
|
44
|
+
page_param: str | None = None
|
|
45
|
+
|
|
46
|
+
# Response parsing
|
|
47
|
+
data_path: str = "data"
|
|
48
|
+
has_more_path: str | None = None
|
|
49
|
+
|
|
50
|
+
# Limits
|
|
51
|
+
max_page_size: int | None = None
|
|
52
|
+
default_page_size: int = 100
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class RateLimitConfig(BaseModel):
|
|
56
|
+
"""
|
|
57
|
+
Configuration for rate limiting.
|
|
58
|
+
|
|
59
|
+
NOT YET USED - Defined for future implementation.
|
|
60
|
+
|
|
61
|
+
When active, might be added to Server or root OpenAPIConnector as:
|
|
62
|
+
x_rate_limit: Optional[RateLimitConfig] = Field(None, alias="x-rate-limit")
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
66
|
+
|
|
67
|
+
max_requests: int
|
|
68
|
+
time_window_seconds: int
|
|
69
|
+
retry_after_header: str | None = "Retry-After"
|
|
70
|
+
respect_retry_after: bool = True
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class RetryConfig(BaseModel):
|
|
74
|
+
"""
|
|
75
|
+
Configuration for retry strategy with exponential backoff.
|
|
76
|
+
|
|
77
|
+
Used to configure automatic retries for transient errors (429, 5xx, timeouts, network errors).
|
|
78
|
+
Can be specified at the connector level via x-airbyte-retry-config in the OpenAPI spec's info section.
|
|
79
|
+
|
|
80
|
+
By default, retries are enabled with max_attempts=3. To disable retries, set max_attempts=1
|
|
81
|
+
in your connector's x-airbyte-retry-config.
|
|
82
|
+
|
|
83
|
+
Example YAML usage:
|
|
84
|
+
info:
|
|
85
|
+
title: My API
|
|
86
|
+
x-airbyte-retry-config:
|
|
87
|
+
max_attempts: 5
|
|
88
|
+
initial_delay_seconds: 2.0
|
|
89
|
+
retry_after_header: "X-RateLimit-Reset"
|
|
90
|
+
retry_after_format: "unix_timestamp"
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
94
|
+
|
|
95
|
+
# Core retry settings (max_attempts=3 enables retries by default)
|
|
96
|
+
max_attempts: int = 3
|
|
97
|
+
initial_delay_seconds: float = 1.0
|
|
98
|
+
max_delay_seconds: float = 60.0
|
|
99
|
+
exponential_base: float = 2.0
|
|
100
|
+
jitter: bool = True
|
|
101
|
+
|
|
102
|
+
# Which errors to retry
|
|
103
|
+
retry_on_status_codes: list[int] = [429, 500, 502, 503, 504]
|
|
104
|
+
retry_on_timeout: bool = True
|
|
105
|
+
retry_on_network_error: bool = True
|
|
106
|
+
|
|
107
|
+
# Header-based delay extraction
|
|
108
|
+
retry_after_header: str = "Retry-After"
|
|
109
|
+
retry_after_format: Literal["seconds", "milliseconds", "unix_timestamp"] = "seconds"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class CacheFieldProperty(BaseModel):
|
|
113
|
+
"""
|
|
114
|
+
Nested property definition for object-type cache fields.
|
|
115
|
+
|
|
116
|
+
Supports recursive nesting to represent complex nested schemas in cache field definitions.
|
|
117
|
+
Used when a cache field has type 'object' and needs to define its internal structure.
|
|
118
|
+
|
|
119
|
+
Example YAML usage:
|
|
120
|
+
- name: collaboration
|
|
121
|
+
type: ['null', 'object']
|
|
122
|
+
description: "Collaboration data"
|
|
123
|
+
properties:
|
|
124
|
+
brief:
|
|
125
|
+
type: ['null', 'string']
|
|
126
|
+
comments:
|
|
127
|
+
type: ['null', 'array']
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
131
|
+
|
|
132
|
+
type: str | list[str]
|
|
133
|
+
properties: dict[str, "CacheFieldProperty"] | None = None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class CacheFieldConfig(BaseModel):
|
|
137
|
+
"""
|
|
138
|
+
Field configuration for cache mapping.
|
|
139
|
+
|
|
140
|
+
Defines a single field in a cache entity, with optional name aliasing
|
|
141
|
+
to map between user-facing field names and cache storage names.
|
|
142
|
+
|
|
143
|
+
For object-type fields, supports nested properties to define the internal structure
|
|
144
|
+
of complex nested schemas.
|
|
145
|
+
|
|
146
|
+
Used in x-airbyte-cache extension for api_search operations.
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
150
|
+
|
|
151
|
+
name: str
|
|
152
|
+
x_airbyte_name: str | None = Field(default=None, alias="x-airbyte-name")
|
|
153
|
+
type: str | list[str]
|
|
154
|
+
description: str
|
|
155
|
+
properties: dict[str, CacheFieldProperty] | None = None
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def cache_name(self) -> str:
|
|
159
|
+
"""Return cache name, falling back to name if alias not specified."""
|
|
160
|
+
return self.x_airbyte_name or self.name
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class CacheEntityConfig(BaseModel):
|
|
164
|
+
"""
|
|
165
|
+
Entity configuration for cache mapping.
|
|
166
|
+
|
|
167
|
+
Defines a cache-enabled entity with its fields and optional name aliasing
|
|
168
|
+
to map between user-facing entity names and cache storage names.
|
|
169
|
+
|
|
170
|
+
Used in x-airbyte-cache extension for api_search operations.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
174
|
+
|
|
175
|
+
entity: str
|
|
176
|
+
x_airbyte_name: str | None = Field(default=None, alias="x-airbyte-name")
|
|
177
|
+
fields: list[CacheFieldConfig]
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def cache_name(self) -> str:
|
|
181
|
+
"""Return cache entity name, falling back to entity if alias not specified."""
|
|
182
|
+
return self.x_airbyte_name or self.entity
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class ReplicationConfigProperty(BaseModel):
|
|
186
|
+
"""
|
|
187
|
+
Property definition for replication configuration fields.
|
|
188
|
+
|
|
189
|
+
Defines a single field in the replication configuration with its type,
|
|
190
|
+
description, and optional default value.
|
|
191
|
+
|
|
192
|
+
Example YAML usage:
|
|
193
|
+
x-airbyte-replication-config:
|
|
194
|
+
properties:
|
|
195
|
+
start_date:
|
|
196
|
+
type: string
|
|
197
|
+
title: Start Date
|
|
198
|
+
description: UTC date and time from which to replicate data
|
|
199
|
+
format: date-time
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
203
|
+
|
|
204
|
+
type: str
|
|
205
|
+
title: str | None = None
|
|
206
|
+
description: str | None = None
|
|
207
|
+
format: str | None = None
|
|
208
|
+
default: str | int | float | bool | None = None
|
|
209
|
+
enum: list[str] | None = None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class ReplicationConfig(BaseModel):
|
|
213
|
+
"""
|
|
214
|
+
Replication configuration extension (x-airbyte-replication-config).
|
|
215
|
+
|
|
216
|
+
Defines replication-specific settings for MULTI mode connectors that need
|
|
217
|
+
to configure the underlying replication connector. This allows users who
|
|
218
|
+
use the direct-style API (credentials + environment) to also specify
|
|
219
|
+
replication settings like start_date, lookback_window, etc.
|
|
220
|
+
|
|
221
|
+
This extension is added to the Info model and provides field definitions
|
|
222
|
+
for replication configuration that gets merged into the source config
|
|
223
|
+
when creating sources.
|
|
224
|
+
|
|
225
|
+
Example YAML usage:
|
|
226
|
+
info:
|
|
227
|
+
title: HubSpot API
|
|
228
|
+
x-airbyte-replication-config:
|
|
229
|
+
title: Replication Configuration
|
|
230
|
+
description: Settings for data replication
|
|
231
|
+
properties:
|
|
232
|
+
start_date:
|
|
233
|
+
type: string
|
|
234
|
+
title: Start Date
|
|
235
|
+
description: UTC date and time from which to replicate data
|
|
236
|
+
format: date-time
|
|
237
|
+
required:
|
|
238
|
+
- start_date
|
|
239
|
+
replication_config_key_mapping:
|
|
240
|
+
start_date: start_date
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
244
|
+
|
|
245
|
+
title: str | None = None
|
|
246
|
+
description: str | None = None
|
|
247
|
+
properties: dict[str, ReplicationConfigProperty] = Field(default_factory=dict)
|
|
248
|
+
required: list[str] = Field(default_factory=list)
|
|
249
|
+
replication_config_key_mapping: dict[str, str] = Field(
|
|
250
|
+
default_factory=dict,
|
|
251
|
+
alias="replication_config_key_mapping",
|
|
252
|
+
description="Mapping from replication_config field names to source_config field names",
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class CacheConfig(BaseModel):
|
|
257
|
+
"""
|
|
258
|
+
Cache configuration extension (x-airbyte-cache).
|
|
259
|
+
|
|
260
|
+
Defines cache-enabled entities and their field mappings for api_search operations.
|
|
261
|
+
Supports optional name aliasing via x-airbyte-name for both entities and fields,
|
|
262
|
+
enabling bidirectional mapping between user-facing names and cache storage names.
|
|
263
|
+
|
|
264
|
+
This extension is added to the Info model and provides field-level mapping for
|
|
265
|
+
search operations that use cached data.
|
|
266
|
+
|
|
267
|
+
Example YAML usage:
|
|
268
|
+
info:
|
|
269
|
+
title: Stripe API
|
|
270
|
+
x-airbyte-cache:
|
|
271
|
+
entities:
|
|
272
|
+
- entity: customers
|
|
273
|
+
stream: customers
|
|
274
|
+
fields:
|
|
275
|
+
- name: email
|
|
276
|
+
type: ["null", "string"]
|
|
277
|
+
description: "Customer email address"
|
|
278
|
+
- name: customer_name
|
|
279
|
+
x-airbyte-name: name
|
|
280
|
+
type: ["null", "string"]
|
|
281
|
+
description: "Customer full name"
|
|
282
|
+
"""
|
|
283
|
+
|
|
284
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
285
|
+
|
|
286
|
+
entities: list[CacheEntityConfig]
|
|
287
|
+
|
|
288
|
+
def get_entity_mapping(self, user_entity: str) -> CacheEntityConfig | None:
|
|
289
|
+
"""
|
|
290
|
+
Get entity config by user-facing name.
|
|
291
|
+
|
|
292
|
+
Args:
|
|
293
|
+
user_entity: User-facing entity name to look up
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
CacheEntityConfig if found, None otherwise
|
|
297
|
+
"""
|
|
298
|
+
for entity in self.entities:
|
|
299
|
+
if entity.entity == user_entity:
|
|
300
|
+
return entity
|
|
301
|
+
return None
|