airbyte-agent-zendesk-support 0.18.18__py3-none-any.whl → 0.18.39__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/_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 +32 -6
- 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 +94 -25
- 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 +50 -43
- airbyte_agent_zendesk_support/_vendored/connector_sdk/introspection.py +262 -0
- airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/logger.py +9 -9
- airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/types.py +10 -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 +18 -17
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/components.py +59 -58
- airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/extensions.py +9 -9
- 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/connector.py +98 -15
- airbyte_agent_zendesk_support/connector_model.py +7 -1
- airbyte_agent_zendesk_support/types.py +1 -1
- {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.39.dist-info}/METADATA +47 -26
- {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.39.dist-info}/RECORD +33 -29
- {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.39.dist-info}/WHEEL +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
4
|
from contextlib import asynccontextmanager
|
|
5
|
-
from typing import Dict
|
|
5
|
+
from typing import Dict
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class PerformanceMonitor:
|
|
@@ -33,7 +33,7 @@ class PerformanceMonitor:
|
|
|
33
33
|
metrics["min"] = min(metrics["min"], duration)
|
|
34
34
|
metrics["max"] = max(metrics["max"], duration)
|
|
35
35
|
|
|
36
|
-
def get_stats(self, metric_name: str) ->
|
|
36
|
+
def get_stats(self, metric_name: str) -> Dict[str, float] | None:
|
|
37
37
|
"""Get statistics for a metric.
|
|
38
38
|
|
|
39
39
|
Args:
|
|
@@ -62,7 +62,7 @@ class PerformanceMonitor:
|
|
|
62
62
|
"""
|
|
63
63
|
return {name: self.get_stats(name) for name in self._metrics.keys()}
|
|
64
64
|
|
|
65
|
-
def reset(self, metric_name:
|
|
65
|
+
def reset(self, metric_name: str | None = None):
|
|
66
66
|
"""Reset metrics.
|
|
67
67
|
|
|
68
68
|
Args:
|
|
@@ -7,7 +7,8 @@ References:
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from enum import StrEnum
|
|
10
|
-
from typing import Dict
|
|
10
|
+
from typing import Dict
|
|
11
|
+
from uuid import UUID
|
|
11
12
|
|
|
12
13
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
13
14
|
from pydantic_core import Url
|
|
@@ -44,9 +45,9 @@ class Contact(BaseModel):
|
|
|
44
45
|
|
|
45
46
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
46
47
|
|
|
47
|
-
name:
|
|
48
|
-
url:
|
|
49
|
-
email:
|
|
48
|
+
name: str | None = None
|
|
49
|
+
url: str | None = None
|
|
50
|
+
email: str | None = None
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
class License(BaseModel):
|
|
@@ -59,7 +60,7 @@ class License(BaseModel):
|
|
|
59
60
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
60
61
|
|
|
61
62
|
name: str
|
|
62
|
-
url:
|
|
63
|
+
url: str | None = None
|
|
63
64
|
|
|
64
65
|
|
|
65
66
|
class DocUrlType(StrEnum):
|
|
@@ -84,7 +85,7 @@ class DocUrl(BaseModel):
|
|
|
84
85
|
|
|
85
86
|
url: str
|
|
86
87
|
type: DocUrlType
|
|
87
|
-
title:
|
|
88
|
+
title: str | None = None
|
|
88
89
|
|
|
89
90
|
@field_validator("url")
|
|
90
91
|
def validate_url(cls, v):
|
|
@@ -110,17 +111,17 @@ class Info(BaseModel):
|
|
|
110
111
|
|
|
111
112
|
title: str
|
|
112
113
|
version: str
|
|
113
|
-
description:
|
|
114
|
-
terms_of_service:
|
|
115
|
-
contact:
|
|
116
|
-
license:
|
|
114
|
+
description: str | None = None
|
|
115
|
+
terms_of_service: str | None = Field(None, alias="termsOfService")
|
|
116
|
+
contact: Contact | None = None
|
|
117
|
+
license: License | None = None
|
|
117
118
|
|
|
118
119
|
# Airbyte extension
|
|
119
|
-
x_airbyte_connector_name:
|
|
120
|
-
x_airbyte_connector_id:
|
|
120
|
+
x_airbyte_connector_name: str | None = Field(None, alias="x-airbyte-connector-name")
|
|
121
|
+
x_airbyte_connector_id: UUID | None = Field(None, alias="x-airbyte-connector-id")
|
|
121
122
|
x_airbyte_external_documentation_urls: list[DocUrl] = Field(..., alias="x-airbyte-external-documentation-urls")
|
|
122
|
-
x_airbyte_retry_config:
|
|
123
|
-
x_airbyte_example_questions:
|
|
123
|
+
x_airbyte_retry_config: RetryConfig | None = Field(None, alias="x-airbyte-retry-config")
|
|
124
|
+
x_airbyte_example_questions: ExampleQuestions | None = Field(None, alias="x-airbyte-example-questions")
|
|
124
125
|
|
|
125
126
|
|
|
126
127
|
class ServerVariable(BaseModel):
|
|
@@ -132,9 +133,9 @@ class ServerVariable(BaseModel):
|
|
|
132
133
|
|
|
133
134
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
134
135
|
|
|
135
|
-
enum:
|
|
136
|
+
enum: list[str] | None = None
|
|
136
137
|
default: str
|
|
137
|
-
description:
|
|
138
|
+
description: str | None = None
|
|
138
139
|
|
|
139
140
|
|
|
140
141
|
class Server(BaseModel):
|
|
@@ -147,7 +148,7 @@ class Server(BaseModel):
|
|
|
147
148
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
148
149
|
|
|
149
150
|
url: str
|
|
150
|
-
description:
|
|
151
|
+
description: str | None = None
|
|
151
152
|
variables: Dict[str, ServerVariable] = Field(default_factory=dict)
|
|
152
153
|
|
|
153
154
|
@field_validator("url")
|
|
@@ -7,7 +7,7 @@ References:
|
|
|
7
7
|
- https://spec.openapis.org/oas/v3.1.0#parameter-object
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
from typing import Any, Dict, List, Literal,
|
|
10
|
+
from typing import Any, Dict, List, Literal, Union
|
|
11
11
|
|
|
12
12
|
from pydantic import BaseModel, ConfigDict, Field
|
|
13
13
|
|
|
@@ -30,43 +30,44 @@ class Schema(BaseModel):
|
|
|
30
30
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
31
31
|
|
|
32
32
|
# Core JSON Schema fields
|
|
33
|
-
type:
|
|
34
|
-
format:
|
|
35
|
-
title:
|
|
36
|
-
description:
|
|
37
|
-
default:
|
|
38
|
-
example:
|
|
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
39
|
|
|
40
40
|
# Object properties
|
|
41
41
|
properties: Dict[str, Any] = Field(default_factory=dict) # May contain $ref
|
|
42
42
|
required: List[str] = Field(default_factory=list)
|
|
43
|
-
additional_properties:
|
|
43
|
+
additional_properties: Any | None = Field(None, alias="additionalProperties")
|
|
44
44
|
|
|
45
45
|
# Array properties
|
|
46
|
-
items:
|
|
46
|
+
items: Any | None = None # May be Schema or $ref
|
|
47
47
|
|
|
48
48
|
# Validation
|
|
49
|
-
enum:
|
|
50
|
-
min_length:
|
|
51
|
-
max_length:
|
|
52
|
-
minimum:
|
|
53
|
-
maximum:
|
|
54
|
-
pattern:
|
|
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
55
|
|
|
56
56
|
# Composition
|
|
57
|
-
all_of:
|
|
58
|
-
any_of:
|
|
59
|
-
one_of:
|
|
60
|
-
not_:
|
|
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
61
|
|
|
62
62
|
# Metadata
|
|
63
|
-
nullable:
|
|
64
|
-
read_only:
|
|
65
|
-
write_only:
|
|
66
|
-
deprecated:
|
|
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
67
|
|
|
68
|
-
# Airbyte
|
|
69
|
-
x_airbyte_entity_name:
|
|
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")
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
class Parameter(BaseModel):
|
|
@@ -80,19 +81,19 @@ class Parameter(BaseModel):
|
|
|
80
81
|
|
|
81
82
|
name: str
|
|
82
83
|
in_: Literal["query", "header", "path", "cookie"] = Field(alias="in")
|
|
83
|
-
description:
|
|
84
|
-
required:
|
|
85
|
-
deprecated:
|
|
86
|
-
allow_empty_value:
|
|
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")
|
|
87
88
|
|
|
88
89
|
# Schema can be inline or reference
|
|
89
|
-
schema_:
|
|
90
|
+
schema_: Dict[str, Any] | None = Field(None, alias="schema")
|
|
90
91
|
|
|
91
92
|
# Style and examples
|
|
92
|
-
style:
|
|
93
|
-
explode:
|
|
94
|
-
example:
|
|
95
|
-
examples:
|
|
93
|
+
style: str | None = None
|
|
94
|
+
explode: bool | None = None
|
|
95
|
+
example: Any | None = None
|
|
96
|
+
examples: Dict[str, Any] | None = None
|
|
96
97
|
|
|
97
98
|
|
|
98
99
|
class MediaType(BaseModel):
|
|
@@ -104,10 +105,10 @@ class MediaType(BaseModel):
|
|
|
104
105
|
|
|
105
106
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
106
107
|
|
|
107
|
-
schema_:
|
|
108
|
-
example:
|
|
109
|
-
examples:
|
|
110
|
-
encoding:
|
|
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
|
|
111
112
|
|
|
112
113
|
|
|
113
114
|
class GraphQLBodyConfig(BaseModel):
|
|
@@ -124,12 +125,12 @@ class GraphQLBodyConfig(BaseModel):
|
|
|
124
125
|
...,
|
|
125
126
|
description="GraphQL query or mutation string with optional template placeholders (e.g., {{ variable }})",
|
|
126
127
|
)
|
|
127
|
-
variables:
|
|
128
|
+
variables: Dict[str, Any] | None = Field(
|
|
128
129
|
None,
|
|
129
130
|
description="Variables to substitute in the GraphQL query using template syntax (e.g., {{ param_name }})",
|
|
130
131
|
)
|
|
131
|
-
operationName:
|
|
132
|
-
default_fields:
|
|
132
|
+
operationName: str | None = Field(None, description="Operation name for queries with multiple operations")
|
|
133
|
+
default_fields: Union[str, List[str]] | None = Field(
|
|
133
134
|
None,
|
|
134
135
|
description="Default fields to select if not provided in request parameters. Can be a string or array of field names.",
|
|
135
136
|
)
|
|
@@ -155,7 +156,7 @@ class PathOverrideConfig(BaseModel):
|
|
|
155
156
|
|
|
156
157
|
path: str = Field(
|
|
157
158
|
...,
|
|
158
|
-
description=("Actual HTTP path to use for requests (e.g., '/graphql').
|
|
159
|
+
description=("Actual HTTP path to use for requests (e.g., '/graphql'). Must start with '/'"),
|
|
159
160
|
)
|
|
160
161
|
|
|
161
162
|
|
|
@@ -172,17 +173,17 @@ class RequestBody(BaseModel):
|
|
|
172
173
|
|
|
173
174
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
174
175
|
|
|
175
|
-
description:
|
|
176
|
+
description: str | None = None
|
|
176
177
|
content: Dict[str, MediaType] = Field(default_factory=dict)
|
|
177
|
-
required:
|
|
178
|
+
required: bool | None = None
|
|
178
179
|
|
|
179
180
|
# Airbyte extensions for GraphQL support
|
|
180
181
|
# See connector_sdk.extensions for AIRBYTE_BODY_TYPE constant
|
|
181
|
-
x_airbyte_body_type:
|
|
182
|
+
x_airbyte_body_type: BodyTypeConfig | None = Field(
|
|
182
183
|
None,
|
|
183
184
|
alias="x-airbyte-body-type", # AIRBYTE_BODY_TYPE
|
|
184
185
|
description=(
|
|
185
|
-
"Body type and configuration. Contains 'type' field (e.g., 'graphql')
|
|
186
|
+
"Body type and configuration. Contains 'type' field (e.g., 'graphql') and type-specific configuration (query, variables, etc.)."
|
|
186
187
|
),
|
|
187
188
|
)
|
|
188
189
|
|
|
@@ -196,11 +197,11 @@ class Header(BaseModel):
|
|
|
196
197
|
|
|
197
198
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
198
199
|
|
|
199
|
-
description:
|
|
200
|
-
required:
|
|
201
|
-
deprecated:
|
|
202
|
-
schema_:
|
|
203
|
-
example:
|
|
200
|
+
description: str | None = None
|
|
201
|
+
required: bool | None = None
|
|
202
|
+
deprecated: bool | None = None
|
|
203
|
+
schema_: Dict[str, Any] | None = Field(None, alias="schema")
|
|
204
|
+
example: Any | None = None
|
|
204
205
|
|
|
205
206
|
|
|
206
207
|
class Response(BaseModel):
|
|
@@ -213,9 +214,9 @@ class Response(BaseModel):
|
|
|
213
214
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
214
215
|
|
|
215
216
|
description: str
|
|
216
|
-
headers:
|
|
217
|
-
content:
|
|
218
|
-
links:
|
|
217
|
+
headers: Dict[str, Header] | None = None
|
|
218
|
+
content: Dict[str, MediaType] | None = None
|
|
219
|
+
links: Dict[str, Any] | None = None
|
|
219
220
|
|
|
220
221
|
|
|
221
222
|
class Components(BaseModel):
|
|
@@ -230,9 +231,9 @@ class Components(BaseModel):
|
|
|
230
231
|
schemas: Dict[str, Schema] = Field(default_factory=dict)
|
|
231
232
|
responses: Dict[str, Response] = Field(default_factory=dict)
|
|
232
233
|
parameters: Dict[str, Parameter] = Field(default_factory=dict)
|
|
233
|
-
examples:
|
|
234
|
+
examples: Dict[str, Any] | None = None
|
|
234
235
|
request_bodies: Dict[str, RequestBody] = Field(default_factory=dict, alias="requestBodies")
|
|
235
|
-
headers:
|
|
236
|
+
headers: Dict[str, Header] | None = None
|
|
236
237
|
security_schemes: Dict[str, SecurityScheme] = Field(default_factory=dict, alias="securitySchemes")
|
|
237
|
-
links:
|
|
238
|
-
callbacks:
|
|
238
|
+
links: Dict[str, Any] | None = None
|
|
239
|
+
callbacks: Dict[str, Any] | None = None
|
|
@@ -12,7 +12,7 @@ to Operation, Schema, or other models when their respective features
|
|
|
12
12
|
are implemented.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
from typing import Literal
|
|
15
|
+
from typing import Literal
|
|
16
16
|
|
|
17
17
|
from pydantic import BaseModel, ConfigDict
|
|
18
18
|
|
|
@@ -33,22 +33,22 @@ class PaginationConfig(BaseModel):
|
|
|
33
33
|
limit_param: str = "limit"
|
|
34
34
|
|
|
35
35
|
# Cursor-based pagination
|
|
36
|
-
cursor_param:
|
|
37
|
-
cursor_source:
|
|
38
|
-
cursor_path:
|
|
36
|
+
cursor_param: str | None = None
|
|
37
|
+
cursor_source: Literal["body", "headers"] | None = "body"
|
|
38
|
+
cursor_path: str | None = None
|
|
39
39
|
|
|
40
40
|
# Offset-based pagination
|
|
41
|
-
offset_param:
|
|
41
|
+
offset_param: str | None = None
|
|
42
42
|
|
|
43
43
|
# Page-based pagination
|
|
44
|
-
page_param:
|
|
44
|
+
page_param: str | None = None
|
|
45
45
|
|
|
46
46
|
# Response parsing
|
|
47
47
|
data_path: str = "data"
|
|
48
|
-
has_more_path:
|
|
48
|
+
has_more_path: str | None = None
|
|
49
49
|
|
|
50
50
|
# Limits
|
|
51
|
-
max_page_size:
|
|
51
|
+
max_page_size: int | None = None
|
|
52
52
|
default_page_size: int = 100
|
|
53
53
|
|
|
54
54
|
|
|
@@ -66,7 +66,7 @@ class RateLimitConfig(BaseModel):
|
|
|
66
66
|
|
|
67
67
|
max_requests: int
|
|
68
68
|
time_window_seconds: int
|
|
69
|
-
retry_after_header:
|
|
69
|
+
retry_after_header: str | None = "Retry-After"
|
|
70
70
|
respect_retry_after: bool = True
|
|
71
71
|
|
|
72
72
|
|
|
@@ -6,7 +6,7 @@ References:
|
|
|
6
6
|
- https://spec.openapis.org/oas/v3.1.0#path-item-object
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from typing import Any, Dict, List
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
10
|
|
|
11
11
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
12
12
|
|
|
@@ -34,38 +34,38 @@ class Operation(BaseModel):
|
|
|
34
34
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
35
35
|
|
|
36
36
|
# Standard OpenAPI fields
|
|
37
|
-
tags:
|
|
38
|
-
summary:
|
|
39
|
-
description:
|
|
40
|
-
external_docs:
|
|
41
|
-
operation_id:
|
|
42
|
-
parameters:
|
|
43
|
-
request_body:
|
|
37
|
+
tags: List[str] | None = None
|
|
38
|
+
summary: str | None = None
|
|
39
|
+
description: str | None = None
|
|
40
|
+
external_docs: Dict[str, Any] | None = Field(None, alias="externalDocs")
|
|
41
|
+
operation_id: str | None = Field(None, alias="operationId")
|
|
42
|
+
parameters: List[Parameter] | None = None
|
|
43
|
+
request_body: RequestBody | None = Field(None, alias="requestBody")
|
|
44
44
|
responses: Dict[str, Response] = Field(default_factory=dict)
|
|
45
|
-
callbacks:
|
|
46
|
-
deprecated:
|
|
47
|
-
security:
|
|
48
|
-
servers:
|
|
45
|
+
callbacks: Dict[str, Any] | None = None
|
|
46
|
+
deprecated: bool | None = None
|
|
47
|
+
security: List[SecurityRequirement] | None = None
|
|
48
|
+
servers: List[Any] | None = None # Can override root servers
|
|
49
49
|
|
|
50
50
|
# Airbyte extensions
|
|
51
51
|
x_airbyte_entity: str = Field(..., alias="x-airbyte-entity")
|
|
52
52
|
x_airbyte_action: ActionTypeLiteral = Field(..., alias="x-airbyte-action")
|
|
53
|
-
x_airbyte_path_override:
|
|
53
|
+
x_airbyte_path_override: PathOverrideConfig | None = Field(
|
|
54
54
|
None,
|
|
55
55
|
alias="x-airbyte-path-override",
|
|
56
|
-
description=("Override path for HTTP requests when OpenAPI path
|
|
56
|
+
description=("Override path for HTTP requests when OpenAPI path differs from actual endpoint"),
|
|
57
57
|
)
|
|
58
|
-
x_airbyte_record_extractor:
|
|
58
|
+
x_airbyte_record_extractor: str | None = Field(
|
|
59
59
|
None,
|
|
60
60
|
alias="x-airbyte-record-extractor",
|
|
61
61
|
description=(
|
|
62
62
|
"JSONPath expression to extract records from API response envelopes. "
|
|
63
63
|
"When specified, executor extracts data at this path instead of returning "
|
|
64
|
-
"full response. Returns array for list/
|
|
64
|
+
"full response. Returns array for list/api_search actions, single record for "
|
|
65
65
|
"get/create/update/delete actions."
|
|
66
66
|
),
|
|
67
67
|
)
|
|
68
|
-
x_airbyte_meta_extractor:
|
|
68
|
+
x_airbyte_meta_extractor: Dict[str, str] | None = Field(
|
|
69
69
|
None,
|
|
70
70
|
alias="x-airbyte-meta-extractor",
|
|
71
71
|
description=(
|
|
@@ -76,8 +76,8 @@ class Operation(BaseModel):
|
|
|
76
76
|
"Example: {'pagination': '$.pagination', 'request_id': '$.requestId'}"
|
|
77
77
|
),
|
|
78
78
|
)
|
|
79
|
-
x_airbyte_file_url:
|
|
80
|
-
x_airbyte_untested:
|
|
79
|
+
x_airbyte_file_url: str | None = Field(None, alias="x-airbyte-file-url")
|
|
80
|
+
x_airbyte_untested: bool | None = Field(
|
|
81
81
|
None,
|
|
82
82
|
alias="x-airbyte-untested",
|
|
83
83
|
description=(
|
|
@@ -127,20 +127,20 @@ class PathItem(BaseModel):
|
|
|
127
127
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
128
128
|
|
|
129
129
|
# Common fields for all operations
|
|
130
|
-
summary:
|
|
131
|
-
description:
|
|
132
|
-
servers:
|
|
133
|
-
parameters:
|
|
130
|
+
summary: str | None = None
|
|
131
|
+
description: str | None = None
|
|
132
|
+
servers: List[Any] | None = None
|
|
133
|
+
parameters: List[Parameter] | None = None
|
|
134
134
|
|
|
135
135
|
# HTTP methods (all optional)
|
|
136
|
-
get:
|
|
137
|
-
put:
|
|
138
|
-
post:
|
|
139
|
-
delete:
|
|
140
|
-
options:
|
|
141
|
-
head:
|
|
142
|
-
patch:
|
|
143
|
-
trace:
|
|
136
|
+
get: Operation | None = None
|
|
137
|
+
put: Operation | None = None
|
|
138
|
+
post: Operation | None = None
|
|
139
|
+
delete: Operation | None = None
|
|
140
|
+
options: Operation | None = None
|
|
141
|
+
head: Operation | None = None
|
|
142
|
+
patch: Operation | None = None
|
|
143
|
+
trace: Operation | None = None
|
|
144
144
|
|
|
145
145
|
# Reference support
|
|
146
|
-
ref:
|
|
146
|
+
ref: str | None = Field(None, alias="$ref")
|
|
@@ -6,7 +6,7 @@ References:
|
|
|
6
6
|
- https://spec.openapis.org/oas/v3.1.0#oauth-flows-object
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from typing import Any, Dict, List, Literal
|
|
9
|
+
from typing import Any, Dict, List, Literal
|
|
10
10
|
|
|
11
11
|
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
12
12
|
|
|
@@ -20,9 +20,9 @@ class OAuth2Flow(BaseModel):
|
|
|
20
20
|
|
|
21
21
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
22
22
|
|
|
23
|
-
authorization_url:
|
|
24
|
-
token_url:
|
|
25
|
-
refresh_url:
|
|
23
|
+
authorization_url: str | None = Field(None, alias="authorizationUrl")
|
|
24
|
+
token_url: str | None = Field(None, alias="tokenUrl")
|
|
25
|
+
refresh_url: str | None = Field(None, alias="refreshUrl")
|
|
26
26
|
scopes: Dict[str, str] = Field(default_factory=dict)
|
|
27
27
|
|
|
28
28
|
|
|
@@ -35,10 +35,10 @@ class OAuth2Flows(BaseModel):
|
|
|
35
35
|
|
|
36
36
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
37
37
|
|
|
38
|
-
implicit:
|
|
39
|
-
password:
|
|
40
|
-
client_credentials:
|
|
41
|
-
authorization_code:
|
|
38
|
+
implicit: OAuth2Flow | None = None
|
|
39
|
+
password: OAuth2Flow | None = None
|
|
40
|
+
client_credentials: OAuth2Flow | None = Field(None, alias="clientCredentials")
|
|
41
|
+
authorization_code: OAuth2Flow | None = Field(None, alias="authorizationCode")
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class AuthConfigFieldSpec(BaseModel):
|
|
@@ -51,12 +51,12 @@ class AuthConfigFieldSpec(BaseModel):
|
|
|
51
51
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
52
52
|
|
|
53
53
|
type: Literal["string", "integer", "boolean", "number"] = "string"
|
|
54
|
-
title:
|
|
55
|
-
description:
|
|
56
|
-
format:
|
|
57
|
-
pattern:
|
|
54
|
+
title: str | None = None
|
|
55
|
+
description: str | None = None
|
|
56
|
+
format: str | None = None # e.g., "email", "uri"
|
|
57
|
+
pattern: str | None = None # Regex validation
|
|
58
58
|
airbyte_secret: bool = Field(False, alias="airbyte_secret")
|
|
59
|
-
default:
|
|
59
|
+
default: Any | None = None
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
class AuthConfigOption(BaseModel):
|
|
@@ -68,8 +68,8 @@ class AuthConfigOption(BaseModel):
|
|
|
68
68
|
|
|
69
69
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
70
70
|
|
|
71
|
-
title:
|
|
72
|
-
description:
|
|
71
|
+
title: str | None = None
|
|
72
|
+
description: str | None = None
|
|
73
73
|
type: Literal["object"] = "object"
|
|
74
74
|
required: List[str] = Field(default_factory=list)
|
|
75
75
|
properties: Dict[str, AuthConfigFieldSpec] = Field(default_factory=dict)
|
|
@@ -77,6 +77,10 @@ class AuthConfigOption(BaseModel):
|
|
|
77
77
|
default_factory=dict,
|
|
78
78
|
description="Mapping from auth parameters (e.g., 'username', 'password', 'token') to template strings using ${field} syntax",
|
|
79
79
|
)
|
|
80
|
+
replication_auth_key_mapping: Dict[str, str] | None = Field(
|
|
81
|
+
None,
|
|
82
|
+
description="Mapping from source config paths (e.g., 'credentials.api_key') to auth config keys for direct connectors",
|
|
83
|
+
)
|
|
80
84
|
|
|
81
85
|
|
|
82
86
|
class AirbyteAuthConfig(BaseModel):
|
|
@@ -92,15 +96,21 @@ class AirbyteAuthConfig(BaseModel):
|
|
|
92
96
|
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
93
97
|
|
|
94
98
|
# Single option fields
|
|
95
|
-
title:
|
|
96
|
-
description:
|
|
97
|
-
type:
|
|
98
|
-
required:
|
|
99
|
-
properties:
|
|
100
|
-
auth_mapping:
|
|
99
|
+
title: str | None = None
|
|
100
|
+
description: str | None = None
|
|
101
|
+
type: Literal["object"] | None = None
|
|
102
|
+
required: List[str] | None = None
|
|
103
|
+
properties: Dict[str, AuthConfigFieldSpec] | None = None
|
|
104
|
+
auth_mapping: Dict[str, str] | None = None
|
|
105
|
+
|
|
106
|
+
# Replication connector auth mapping
|
|
107
|
+
replication_auth_key_mapping: Dict[str, str] | None = Field(
|
|
108
|
+
None,
|
|
109
|
+
description="Mapping from source config paths (e.g., 'credentials.api_key') to auth config keys for direct connectors",
|
|
110
|
+
)
|
|
101
111
|
|
|
102
112
|
# Multiple options (oneOf)
|
|
103
|
-
one_of:
|
|
113
|
+
one_of: List[AuthConfigOption] | None = Field(None, alias="oneOf")
|
|
104
114
|
|
|
105
115
|
@model_validator(mode="after")
|
|
106
116
|
def validate_config_structure(self) -> "AirbyteAuthConfig":
|
|
@@ -151,27 +161,27 @@ class SecurityScheme(BaseModel):
|
|
|
151
161
|
|
|
152
162
|
# Standard OpenAPI fields
|
|
153
163
|
type: Literal["apiKey", "http", "oauth2", "openIdConnect"]
|
|
154
|
-
description:
|
|
164
|
+
description: str | None = None
|
|
155
165
|
|
|
156
166
|
# apiKey specific
|
|
157
|
-
name:
|
|
158
|
-
in_:
|
|
167
|
+
name: str | None = None
|
|
168
|
+
in_: Literal["query", "header", "cookie"] | None = Field(None, alias="in")
|
|
159
169
|
|
|
160
170
|
# http specific
|
|
161
|
-
scheme:
|
|
162
|
-
bearer_format:
|
|
171
|
+
scheme: str | None = None # e.g., "basic", "bearer", "digest"
|
|
172
|
+
bearer_format: str | None = Field(None, alias="bearerFormat")
|
|
163
173
|
|
|
164
174
|
# oauth2 specific
|
|
165
|
-
flows:
|
|
175
|
+
flows: OAuth2Flows | None = None
|
|
166
176
|
|
|
167
177
|
# openIdConnect specific
|
|
168
|
-
open_id_connect_url:
|
|
178
|
+
open_id_connect_url: str | None = Field(None, alias="openIdConnectUrl")
|
|
169
179
|
|
|
170
180
|
# Airbyte extensions
|
|
171
|
-
x_token_path:
|
|
172
|
-
x_token_refresh:
|
|
173
|
-
x_airbyte_auth_config:
|
|
174
|
-
x_airbyte_token_extract:
|
|
181
|
+
x_token_path: str | None = Field(None, alias="x-airbyte-token-path")
|
|
182
|
+
x_token_refresh: Dict[str, Any] | None = Field(None, alias="x-airbyte-token-refresh")
|
|
183
|
+
x_airbyte_auth_config: AirbyteAuthConfig | None = Field(None, alias="x-airbyte-auth-config")
|
|
184
|
+
x_airbyte_token_extract: List[str] | None = Field(
|
|
175
185
|
None,
|
|
176
186
|
alias="x-airbyte-token-extract",
|
|
177
187
|
description="List of fields to extract from OAuth2 token responses and use as server variables",
|
|
@@ -179,7 +189,7 @@ class SecurityScheme(BaseModel):
|
|
|
179
189
|
|
|
180
190
|
@field_validator("x_airbyte_token_extract", mode="after")
|
|
181
191
|
@classmethod
|
|
182
|
-
def validate_token_extract(cls, v:
|
|
192
|
+
def validate_token_extract(cls, v: List[str] | None) -> List[str] | None:
|
|
183
193
|
"""Validate x-airbyte-token-extract has no duplicates."""
|
|
184
194
|
if v is not None:
|
|
185
195
|
if len(v) != len(set(v)):
|
|
@@ -14,7 +14,7 @@ Example:
|
|
|
14
14
|
|
|
15
15
|
import os
|
|
16
16
|
import re
|
|
17
|
-
from typing import Any, Dict
|
|
17
|
+
from typing import Any, Dict
|
|
18
18
|
|
|
19
19
|
from pydantic import SecretStr
|
|
20
20
|
|
|
@@ -72,7 +72,7 @@ class SecretResolutionError(Exception):
|
|
|
72
72
|
def resolve_env_var_references(
|
|
73
73
|
secret_mappings: Dict[str, Any],
|
|
74
74
|
strict: bool = True,
|
|
75
|
-
env_vars:
|
|
75
|
+
env_vars: Dict[str, str] | None = None,
|
|
76
76
|
) -> Dict[str, str]:
|
|
77
77
|
"""Resolve environment variable references in secret values.
|
|
78
78
|
|