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.

Files changed (58) hide show
  1. airbyte_agent_airtable/__init__.py +81 -0
  2. airbyte_agent_airtable/_vendored/__init__.py +1 -0
  3. airbyte_agent_airtable/_vendored/connector_sdk/__init__.py +82 -0
  4. airbyte_agent_airtable/_vendored/connector_sdk/auth_strategies.py +1171 -0
  5. airbyte_agent_airtable/_vendored/connector_sdk/auth_template.py +135 -0
  6. airbyte_agent_airtable/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
  7. airbyte_agent_airtable/_vendored/connector_sdk/cloud_utils/client.py +338 -0
  8. airbyte_agent_airtable/_vendored/connector_sdk/connector_model_loader.py +1121 -0
  9. airbyte_agent_airtable/_vendored/connector_sdk/constants.py +78 -0
  10. airbyte_agent_airtable/_vendored/connector_sdk/exceptions.py +23 -0
  11. airbyte_agent_airtable/_vendored/connector_sdk/executor/__init__.py +31 -0
  12. airbyte_agent_airtable/_vendored/connector_sdk/executor/hosted_executor.py +230 -0
  13. airbyte_agent_airtable/_vendored/connector_sdk/executor/local_executor.py +1848 -0
  14. airbyte_agent_airtable/_vendored/connector_sdk/executor/models.py +202 -0
  15. airbyte_agent_airtable/_vendored/connector_sdk/extensions.py +693 -0
  16. airbyte_agent_airtable/_vendored/connector_sdk/http/__init__.py +37 -0
  17. airbyte_agent_airtable/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
  18. airbyte_agent_airtable/_vendored/connector_sdk/http/adapters/httpx_adapter.py +260 -0
  19. airbyte_agent_airtable/_vendored/connector_sdk/http/config.py +98 -0
  20. airbyte_agent_airtable/_vendored/connector_sdk/http/exceptions.py +119 -0
  21. airbyte_agent_airtable/_vendored/connector_sdk/http/protocols.py +114 -0
  22. airbyte_agent_airtable/_vendored/connector_sdk/http/response.py +104 -0
  23. airbyte_agent_airtable/_vendored/connector_sdk/http_client.py +693 -0
  24. airbyte_agent_airtable/_vendored/connector_sdk/introspection.py +481 -0
  25. airbyte_agent_airtable/_vendored/connector_sdk/logging/__init__.py +11 -0
  26. airbyte_agent_airtable/_vendored/connector_sdk/logging/logger.py +273 -0
  27. airbyte_agent_airtable/_vendored/connector_sdk/logging/types.py +93 -0
  28. airbyte_agent_airtable/_vendored/connector_sdk/observability/__init__.py +11 -0
  29. airbyte_agent_airtable/_vendored/connector_sdk/observability/config.py +179 -0
  30. airbyte_agent_airtable/_vendored/connector_sdk/observability/models.py +19 -0
  31. airbyte_agent_airtable/_vendored/connector_sdk/observability/redactor.py +81 -0
  32. airbyte_agent_airtable/_vendored/connector_sdk/observability/session.py +103 -0
  33. airbyte_agent_airtable/_vendored/connector_sdk/performance/__init__.py +6 -0
  34. airbyte_agent_airtable/_vendored/connector_sdk/performance/instrumentation.py +57 -0
  35. airbyte_agent_airtable/_vendored/connector_sdk/performance/metrics.py +93 -0
  36. airbyte_agent_airtable/_vendored/connector_sdk/schema/__init__.py +75 -0
  37. airbyte_agent_airtable/_vendored/connector_sdk/schema/base.py +212 -0
  38. airbyte_agent_airtable/_vendored/connector_sdk/schema/components.py +244 -0
  39. airbyte_agent_airtable/_vendored/connector_sdk/schema/connector.py +120 -0
  40. airbyte_agent_airtable/_vendored/connector_sdk/schema/extensions.py +301 -0
  41. airbyte_agent_airtable/_vendored/connector_sdk/schema/operations.py +156 -0
  42. airbyte_agent_airtable/_vendored/connector_sdk/schema/security.py +241 -0
  43. airbyte_agent_airtable/_vendored/connector_sdk/secrets.py +182 -0
  44. airbyte_agent_airtable/_vendored/connector_sdk/telemetry/__init__.py +10 -0
  45. airbyte_agent_airtable/_vendored/connector_sdk/telemetry/config.py +32 -0
  46. airbyte_agent_airtable/_vendored/connector_sdk/telemetry/events.py +59 -0
  47. airbyte_agent_airtable/_vendored/connector_sdk/telemetry/tracker.py +155 -0
  48. airbyte_agent_airtable/_vendored/connector_sdk/types.py +274 -0
  49. airbyte_agent_airtable/_vendored/connector_sdk/utils.py +127 -0
  50. airbyte_agent_airtable/_vendored/connector_sdk/validation.py +997 -0
  51. airbyte_agent_airtable/_vendored/connector_sdk/validation_replication.py +970 -0
  52. airbyte_agent_airtable/connector.py +834 -0
  53. airbyte_agent_airtable/connector_model.py +365 -0
  54. airbyte_agent_airtable/models.py +219 -0
  55. airbyte_agent_airtable/types.py +367 -0
  56. airbyte_agent_airtable-0.1.5.dist-info/METADATA +140 -0
  57. airbyte_agent_airtable-0.1.5.dist-info/RECORD +58 -0
  58. 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