airbyte-cdk 6.8.3rc1__py3-none-any.whl → 6.9.0.dev0__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_cdk/sources/declarative/concurrent_declarative_source.py +7 -3
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml +186 -2
- airbyte_cdk/sources/declarative/manifest_declarative_source.py +53 -2
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +137 -6
- airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +10 -0
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +167 -21
- airbyte_cdk/sources/declarative/partition_routers/__init__.py +2 -1
- airbyte_cdk/sources/declarative/resolvers/__init__.py +13 -0
- airbyte_cdk/sources/declarative/resolvers/components_resolver.py +55 -0
- airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py +106 -0
- airbyte_cdk/sources/declarative/schema/__init__.py +2 -1
- airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +219 -0
- airbyte_cdk-6.9.0.dev0.dist-info/METADATA +111 -0
- {airbyte_cdk-6.8.3rc1.dist-info → airbyte_cdk-6.9.0.dev0.dist-info}/RECORD +17 -14
- airbyte_cdk/test/utils/manifest_only_fixtures.py +0 -55
- airbyte_cdk-6.8.3rc1.dist-info/METADATA +0 -306
- {airbyte_cdk-6.8.3rc1.dist-info → airbyte_cdk-6.9.0.dev0.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.8.3rc1.dist-info → airbyte_cdk-6.9.0.dev0.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.8.3rc1.dist-info → airbyte_cdk-6.9.0.dev0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,219 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
from copy import deepcopy
|
7
|
+
from dataclasses import InitVar, dataclass
|
8
|
+
from typing import Any, List, Mapping, MutableMapping, Optional, Union
|
9
|
+
|
10
|
+
import dpath
|
11
|
+
from typing_extensions import deprecated
|
12
|
+
|
13
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
14
|
+
from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever
|
15
|
+
from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader
|
16
|
+
from airbyte_cdk.sources.source import ExperimentalClassWarning
|
17
|
+
from airbyte_cdk.sources.types import Config
|
18
|
+
|
19
|
+
AIRBYTE_DATA_TYPES: Mapping[str, Mapping[str, Any]] = {
|
20
|
+
"string": {"type": ["null", "string"]},
|
21
|
+
"boolean": {"type": ["null", "boolean"]},
|
22
|
+
"date": {"type": ["null", "string"], "format": "date"},
|
23
|
+
"timestamp_without_timezone": {
|
24
|
+
"type": ["null", "string"],
|
25
|
+
"format": "date-time",
|
26
|
+
"airbyte_type": "timestamp_without_timezone",
|
27
|
+
},
|
28
|
+
"timestamp_with_timezone": {"type": ["null", "string"], "format": "date-time"},
|
29
|
+
"time_without_timezone": {
|
30
|
+
"type": ["null", "string"],
|
31
|
+
"format": "time",
|
32
|
+
"airbyte_type": "time_without_timezone",
|
33
|
+
},
|
34
|
+
"time_with_timezone": {
|
35
|
+
"type": ["null", "string"],
|
36
|
+
"format": "time",
|
37
|
+
"airbyte_type": "time_with_timezone",
|
38
|
+
},
|
39
|
+
"integer": {"type": ["null", "integer"]},
|
40
|
+
"number": {"type": ["null", "number"]},
|
41
|
+
"array": {"type": ["null", "array"]},
|
42
|
+
"object": {"type": ["null", "object"]},
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning)
|
47
|
+
@dataclass(frozen=True)
|
48
|
+
class TypesMap:
|
49
|
+
"""
|
50
|
+
Represents a mapping between a current type and its corresponding target type.
|
51
|
+
"""
|
52
|
+
|
53
|
+
target_type: Union[List[str], str]
|
54
|
+
current_type: Union[List[str], str]
|
55
|
+
|
56
|
+
|
57
|
+
@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning)
|
58
|
+
@dataclass
|
59
|
+
class SchemaTypeIdentifier:
|
60
|
+
"""
|
61
|
+
Identifies schema details for dynamic schema extraction and processing.
|
62
|
+
"""
|
63
|
+
|
64
|
+
key_pointer: List[Union[InterpolatedString, str]]
|
65
|
+
parameters: InitVar[Mapping[str, Any]]
|
66
|
+
type_pointer: Optional[List[Union[InterpolatedString, str]]] = None
|
67
|
+
types_mapping: Optional[List[TypesMap]] = None
|
68
|
+
schema_pointer: Optional[List[Union[InterpolatedString, str]]] = None
|
69
|
+
|
70
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
71
|
+
self.schema_pointer = (
|
72
|
+
self._update_pointer(self.schema_pointer, parameters) if self.schema_pointer else []
|
73
|
+
) # type: ignore[assignment] # This is reqired field in model
|
74
|
+
self.key_pointer = self._update_pointer(self.key_pointer, parameters) # type: ignore[assignment] # This is reqired field in model
|
75
|
+
self.type_pointer = (
|
76
|
+
self._update_pointer(self.type_pointer, parameters) if self.type_pointer else None
|
77
|
+
)
|
78
|
+
|
79
|
+
@staticmethod
|
80
|
+
def _update_pointer(
|
81
|
+
pointer: Optional[List[Union[InterpolatedString, str]]], parameters: Mapping[str, Any]
|
82
|
+
) -> Optional[List[Union[InterpolatedString, str]]]:
|
83
|
+
return (
|
84
|
+
[
|
85
|
+
InterpolatedString.create(path, parameters=parameters)
|
86
|
+
if isinstance(path, str)
|
87
|
+
else path
|
88
|
+
for path in pointer
|
89
|
+
]
|
90
|
+
if pointer
|
91
|
+
else None
|
92
|
+
)
|
93
|
+
|
94
|
+
|
95
|
+
@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning)
|
96
|
+
@dataclass
|
97
|
+
class DynamicSchemaLoader(SchemaLoader):
|
98
|
+
"""
|
99
|
+
Dynamically loads a JSON Schema by extracting data from retrieved records.
|
100
|
+
"""
|
101
|
+
|
102
|
+
retriever: Retriever
|
103
|
+
config: Config
|
104
|
+
parameters: InitVar[Mapping[str, Any]]
|
105
|
+
schema_type_identifier: SchemaTypeIdentifier
|
106
|
+
|
107
|
+
def get_json_schema(self) -> Mapping[str, Any]:
|
108
|
+
"""
|
109
|
+
Constructs a JSON Schema based on retrieved data.
|
110
|
+
"""
|
111
|
+
properties = {}
|
112
|
+
retrieved_record = next(self.retriever.read_records({}), None) # type: ignore[call-overload] # read_records return Iterable data type
|
113
|
+
|
114
|
+
raw_schema = (
|
115
|
+
self._extract_data(
|
116
|
+
retrieved_record, # type: ignore[arg-type] # Expected that retrieved_record will be only Mapping[str, Any]
|
117
|
+
self.schema_type_identifier.schema_pointer,
|
118
|
+
)
|
119
|
+
if retrieved_record
|
120
|
+
else []
|
121
|
+
)
|
122
|
+
|
123
|
+
for property_definition in raw_schema:
|
124
|
+
key = self._get_key(property_definition, self.schema_type_identifier.key_pointer)
|
125
|
+
value = self._get_type(
|
126
|
+
property_definition,
|
127
|
+
self.schema_type_identifier.type_pointer,
|
128
|
+
)
|
129
|
+
properties[key] = value
|
130
|
+
|
131
|
+
return {
|
132
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
133
|
+
"type": "object",
|
134
|
+
"properties": properties,
|
135
|
+
}
|
136
|
+
|
137
|
+
def _get_key(
|
138
|
+
self,
|
139
|
+
raw_schema: MutableMapping[str, Any],
|
140
|
+
field_key_path: List[Union[InterpolatedString, str]],
|
141
|
+
) -> str:
|
142
|
+
"""
|
143
|
+
Extracts the key field from the schema using the specified path.
|
144
|
+
"""
|
145
|
+
field_key = self._extract_data(raw_schema, field_key_path)
|
146
|
+
if not isinstance(field_key, str):
|
147
|
+
raise ValueError(f"Expected key to be a string. Got {field_key}")
|
148
|
+
return field_key
|
149
|
+
|
150
|
+
def _get_type(
|
151
|
+
self,
|
152
|
+
raw_schema: MutableMapping[str, Any],
|
153
|
+
field_type_path: Optional[List[Union[InterpolatedString, str]]],
|
154
|
+
) -> Union[Mapping[str, Any], List[Mapping[str, Any]]]:
|
155
|
+
"""
|
156
|
+
Determines the JSON Schema type for a field, supporting nullable and combined types.
|
157
|
+
"""
|
158
|
+
raw_field_type = (
|
159
|
+
self._extract_data(raw_schema, field_type_path, default="string")
|
160
|
+
if field_type_path
|
161
|
+
else "string"
|
162
|
+
)
|
163
|
+
mapped_field_type = self._replace_type_if_not_valid(raw_field_type)
|
164
|
+
if (
|
165
|
+
isinstance(mapped_field_type, list)
|
166
|
+
and len(mapped_field_type) == 2
|
167
|
+
and all(isinstance(item, str) for item in mapped_field_type)
|
168
|
+
):
|
169
|
+
first_type = self._get_airbyte_type(mapped_field_type[0])
|
170
|
+
second_type = self._get_airbyte_type(mapped_field_type[1])
|
171
|
+
return {"oneOf": [first_type, second_type]}
|
172
|
+
elif isinstance(mapped_field_type, str):
|
173
|
+
return self._get_airbyte_type(mapped_field_type)
|
174
|
+
else:
|
175
|
+
raise ValueError(
|
176
|
+
f"Invalid data type. Available string or two items list of string. Got {mapped_field_type}."
|
177
|
+
)
|
178
|
+
|
179
|
+
def _replace_type_if_not_valid(
|
180
|
+
self, field_type: Union[List[str], str]
|
181
|
+
) -> Union[List[str], str]:
|
182
|
+
"""
|
183
|
+
Replaces a field type if it matches a type mapping in `types_map`.
|
184
|
+
"""
|
185
|
+
if self.schema_type_identifier.types_mapping:
|
186
|
+
for types_map in self.schema_type_identifier.types_mapping:
|
187
|
+
if field_type == types_map.current_type:
|
188
|
+
return types_map.target_type
|
189
|
+
return field_type
|
190
|
+
|
191
|
+
@staticmethod
|
192
|
+
def _get_airbyte_type(field_type: str) -> Mapping[str, Any]:
|
193
|
+
"""
|
194
|
+
Maps a field type to its corresponding Airbyte type definition.
|
195
|
+
"""
|
196
|
+
if field_type not in AIRBYTE_DATA_TYPES:
|
197
|
+
raise ValueError(f"Invalid Airbyte data type: {field_type}")
|
198
|
+
|
199
|
+
return deepcopy(AIRBYTE_DATA_TYPES[field_type])
|
200
|
+
|
201
|
+
def _extract_data(
|
202
|
+
self,
|
203
|
+
body: Mapping[str, Any],
|
204
|
+
extraction_path: Optional[List[Union[InterpolatedString, str]]] = None,
|
205
|
+
default: Any = None,
|
206
|
+
) -> Any:
|
207
|
+
"""
|
208
|
+
Extracts data from the body based on the provided extraction path.
|
209
|
+
"""
|
210
|
+
|
211
|
+
if not extraction_path:
|
212
|
+
return body
|
213
|
+
|
214
|
+
path = [
|
215
|
+
node.eval(self.config) if not isinstance(node, str) else node
|
216
|
+
for node in extraction_path
|
217
|
+
]
|
218
|
+
|
219
|
+
return dpath.get(body, path, default=default) # type: ignore # extracted will be a MutableMapping, given input data structure
|
@@ -0,0 +1,111 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: airbyte-cdk
|
3
|
+
Version: 6.9.0.dev0
|
4
|
+
Summary: A framework for writing Airbyte Connectors.
|
5
|
+
Home-page: https://airbyte.com
|
6
|
+
License: MIT
|
7
|
+
Keywords: airbyte,connector-development-kit,cdk
|
8
|
+
Author: Airbyte
|
9
|
+
Author-email: contact@airbyte.io
|
10
|
+
Requires-Python: >=3.10,<3.13
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
12
|
+
Classifier: Intended Audience :: Developers
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
20
|
+
Provides-Extra: file-based
|
21
|
+
Provides-Extra: sphinx-docs
|
22
|
+
Provides-Extra: sql
|
23
|
+
Provides-Extra: vector-db-based
|
24
|
+
Requires-Dist: Jinja2 (>=3.1.2,<3.2.0)
|
25
|
+
Requires-Dist: PyYAML (>=6.0.1,<7.0.0)
|
26
|
+
Requires-Dist: Sphinx (>=4.2,<4.3) ; extra == "sphinx-docs"
|
27
|
+
Requires-Dist: airbyte-protocol-models-dataclasses (>=0.14,<0.15)
|
28
|
+
Requires-Dist: avro (>=1.11.2,<1.12.0) ; extra == "file-based"
|
29
|
+
Requires-Dist: backoff
|
30
|
+
Requires-Dist: cachetools
|
31
|
+
Requires-Dist: cohere (==4.21) ; extra == "vector-db-based"
|
32
|
+
Requires-Dist: cryptography (>=42.0.5,<44.0.0)
|
33
|
+
Requires-Dist: dpath (>=2.1.6,<3.0.0)
|
34
|
+
Requires-Dist: dunamai (>=1.22.0,<2.0.0)
|
35
|
+
Requires-Dist: fastavro (>=1.8.0,<1.9.0) ; extra == "file-based"
|
36
|
+
Requires-Dist: genson (==1.3.0)
|
37
|
+
Requires-Dist: isodate (>=0.6.1,<0.7.0)
|
38
|
+
Requires-Dist: jsonref (>=0.2,<0.3)
|
39
|
+
Requires-Dist: jsonschema (>=4.17.3,<4.18.0)
|
40
|
+
Requires-Dist: langchain (==0.1.16) ; extra == "vector-db-based"
|
41
|
+
Requires-Dist: langchain_core (==0.1.42)
|
42
|
+
Requires-Dist: markdown ; extra == "file-based"
|
43
|
+
Requires-Dist: nltk (==3.9.1)
|
44
|
+
Requires-Dist: numpy (<2)
|
45
|
+
Requires-Dist: openai[embeddings] (==0.27.9) ; extra == "vector-db-based"
|
46
|
+
Requires-Dist: orjson (>=3.10.7,<4.0.0)
|
47
|
+
Requires-Dist: pandas (==2.2.2)
|
48
|
+
Requires-Dist: pdf2image (==1.16.3) ; extra == "file-based"
|
49
|
+
Requires-Dist: pdfminer.six (==20221105) ; extra == "file-based"
|
50
|
+
Requires-Dist: pendulum (<3.0.0)
|
51
|
+
Requires-Dist: psutil (==6.1.0)
|
52
|
+
Requires-Dist: pyarrow (>=15.0.0,<15.1.0) ; extra == "file-based"
|
53
|
+
Requires-Dist: pydantic (>=2.7,<3.0)
|
54
|
+
Requires-Dist: pyjwt (>=2.8.0,<3.0.0)
|
55
|
+
Requires-Dist: pyrate-limiter (>=3.1.0,<3.2.0)
|
56
|
+
Requires-Dist: pytesseract (==0.3.10) ; extra == "file-based"
|
57
|
+
Requires-Dist: python-calamine (==0.2.3) ; extra == "file-based"
|
58
|
+
Requires-Dist: python-dateutil
|
59
|
+
Requires-Dist: python-snappy (==0.7.3) ; extra == "file-based"
|
60
|
+
Requires-Dist: python-ulid (>=3.0.0,<4.0.0)
|
61
|
+
Requires-Dist: pytz (==2024.1)
|
62
|
+
Requires-Dist: rapidfuzz (>=3.10.1,<4.0.0)
|
63
|
+
Requires-Dist: requests
|
64
|
+
Requires-Dist: requests_cache
|
65
|
+
Requires-Dist: serpyco-rs (>=1.10.2,<2.0.0)
|
66
|
+
Requires-Dist: sphinx-rtd-theme (>=1.0,<1.1) ; extra == "sphinx-docs"
|
67
|
+
Requires-Dist: sqlalchemy (>=2.0,<3.0,!=2.0.36) ; extra == "sql"
|
68
|
+
Requires-Dist: tiktoken (==0.8.0) ; extra == "vector-db-based"
|
69
|
+
Requires-Dist: unstructured.pytesseract (>=0.3.12) ; extra == "file-based"
|
70
|
+
Requires-Dist: unstructured[docx,pptx] (==0.10.27) ; extra == "file-based"
|
71
|
+
Requires-Dist: wcmatch (==10.0)
|
72
|
+
Requires-Dist: xmltodict (>=0.13.0,<0.14.0)
|
73
|
+
Project-URL: Documentation, https://docs.airbyte.io/
|
74
|
+
Project-URL: Repository, https://github.com/airbytehq/airbyte-python-cdk
|
75
|
+
Description-Content-Type: text/markdown
|
76
|
+
|
77
|
+
# Airbyte Python CDK and Low-Code CDK
|
78
|
+
|
79
|
+
Airbyte Python CDK is a framework for building Airbyte API Source Connectors. It provides a set of
|
80
|
+
classes and helpers that make it easy to build a connector against an HTTP API (REST, GraphQL, etc),
|
81
|
+
or a generic Python source connector.
|
82
|
+
|
83
|
+
## Building Connectors with the CDK
|
84
|
+
|
85
|
+
If you're looking to build a connector, we highly recommend that you first
|
86
|
+
[start with the Connector Builder](https://docs.airbyte.com/connector-development/connector-builder-ui/overview).
|
87
|
+
It should be enough for 90% connectors out there. For more flexible and complex connectors, use the
|
88
|
+
[low-code CDK and `SourceDeclarativeManifest`](https://docs.airbyte.com/connector-development/config-based/low-code-cdk-overview).
|
89
|
+
|
90
|
+
For more information on building connectors, please see the [Connector Development](https://docs.airbyte.com/connector-development/) guide on [docs.airbyte.com](https://docs.airbyte.com).
|
91
|
+
|
92
|
+
## Python CDK Overview
|
93
|
+
|
94
|
+
Airbyte CDK code is within `airbyte_cdk` directory. Here's a high level overview of what's inside:
|
95
|
+
|
96
|
+
- `airbyte_cdk/connector_builder`. Internal wrapper that helps the Connector Builder platform run a declarative manifest (low-code connector). You should not use this code directly. If you need to run a `SourceDeclarativeManifest`, take a look at [`source-declarative-manifest`](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-declarative-manifest) connector implementation instead.
|
97
|
+
- `airbyte_cdk/cli/source_declarative_manifest`. This module defines the `source-declarative-manifest` (aka "SDM") connector execution logic and associated CLI.
|
98
|
+
- `airbyte_cdk/destinations`. Basic Destination connector support! If you're building a Destination connector in Python, try that. Some of our vector DB destinations like `destination-pinecone` are using that code.
|
99
|
+
- `airbyte_cdk/models` expose `airbyte_protocol.models` as a part of `airbyte_cdk` package.
|
100
|
+
- `airbyte_cdk/sources/concurrent_source` is the Concurrent CDK implementation. It supports reading data from streams concurrently per slice / partition, useful for connectors with high throughput and high number of records.
|
101
|
+
- `airbyte_cdk/sources/declarative` is the low-code CDK. It works on top of Airbyte Python CDK, but provides a declarative manifest language to define streams, operations, etc. This makes it easier to build connectors without writing Python code.
|
102
|
+
- `airbyte_cdk/sources/file_based` is the CDK for file-based sources. Examples include S3, Azure, GCS, etc.
|
103
|
+
|
104
|
+
## Contributing
|
105
|
+
|
106
|
+
For instructions on how to contribute, please see our [Contributing Guide](docs/CONTRIBUTING.md).
|
107
|
+
|
108
|
+
## Release Management
|
109
|
+
|
110
|
+
Please see the [Release Management](docs/RELEASES.md) guide for information on how to perform releases and pre-releases.
|
111
|
+
|
@@ -62,11 +62,11 @@ airbyte_cdk/sources/declarative/checks/check_stream.py,sha256=dAA-UhmMj0WLXCkRQr
|
|
62
62
|
airbyte_cdk/sources/declarative/checks/connection_checker.py,sha256=MBRJo6WJlZQHpIfOGaNOkkHUmgUl_4wDM6VPo41z5Ss,1383
|
63
63
|
airbyte_cdk/sources/declarative/concurrency_level/__init__.py,sha256=5XUqrmlstYlMM0j6crktlKQwALek0uiz2D3WdM46MyA,191
|
64
64
|
airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py,sha256=YIwCTCpOr_QSNW4ltQK0yUGWInI8PKNY216HOOegYLk,2101
|
65
|
-
airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=
|
65
|
+
airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=hgKamhOh1B8RA4Fx8FmCl4ORc7eO2h_RhxbkQovh3FM,23724
|
66
66
|
airbyte_cdk/sources/declarative/datetime/__init__.py,sha256=l9LG7Qm6e5r_qgqfVKnx3mXYtg1I9MmMjomVIPfU4XA,177
|
67
67
|
airbyte_cdk/sources/declarative/datetime/datetime_parser.py,sha256=SX9JjdesN1edN2WVUVMzU_ptqp2QB1OnsnjZ4mwcX7w,2579
|
68
68
|
airbyte_cdk/sources/declarative/datetime/min_max_datetime.py,sha256=0BHBtDNQZfvwM45-tY5pNlTcKAFSGGNxemoi0Jic-0E,5785
|
69
|
-
airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=
|
69
|
+
airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=ZCYl6v0miacvpIt6M8FakkGZpEsY8SmB4_436sHEw9Y,126841
|
70
70
|
airbyte_cdk/sources/declarative/declarative_source.py,sha256=nF7wBqFd3AQmEKAm4CnIo29CJoQL562cJGSCeL8U8bA,1531
|
71
71
|
airbyte_cdk/sources/declarative/declarative_stream.py,sha256=JRyNeOIpsFu4ztVZsN6sncqUEIqIE-bUkD2TPgbMgk0,10375
|
72
72
|
airbyte_cdk/sources/declarative/decoders/__init__.py,sha256=hNlhaB5FjNC6IfJyglj5ZJWkYD2nEAukMDmzRz5PC6o,671
|
@@ -99,18 +99,18 @@ airbyte_cdk/sources/declarative/interpolation/interpolated_string.py,sha256=LYEZ
|
|
99
99
|
airbyte_cdk/sources/declarative/interpolation/interpolation.py,sha256=-V5UddGm69UKEB6o_O1EIES9kfY8FV_X4Ji8w1yOuSA,981
|
100
100
|
airbyte_cdk/sources/declarative/interpolation/jinja.py,sha256=gcihTEnfD_6sUivxOomoY5r7VMAGqVVnK_HEsid9Y5k,6605
|
101
101
|
airbyte_cdk/sources/declarative/interpolation/macros.py,sha256=jf24RK-1fBhTYDpcGEakZtGNNJfG5NS8CCF5bEgNmRo,3977
|
102
|
-
airbyte_cdk/sources/declarative/manifest_declarative_source.py,sha256
|
102
|
+
airbyte_cdk/sources/declarative/manifest_declarative_source.py,sha256=-v3GvuTVHwUonrfUwDj3wYKaZjX6hTyKmMBRgEzj-j0,15201
|
103
103
|
airbyte_cdk/sources/declarative/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
104
104
|
airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py,sha256=iemy3fKLczcU0-Aor7tx5jcT6DRedKMqyK7kCOp01hg,3924
|
105
105
|
airbyte_cdk/sources/declarative/migrations/state_migration.py,sha256=KWPjealMLKSMtajXgkdGgKg7EmTLR-CqqD7UIh0-eDU,794
|
106
106
|
airbyte_cdk/sources/declarative/models/__init__.py,sha256=nUFxNCiKeYRVXuZEKA7GD-lTHxsiKcQ8FitZjKhPIvE,100
|
107
|
-
airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=
|
107
|
+
airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=qjzXe162aUcaq1n6B8KhA6Z9B8boM9yY8dAsLXll5-g,89872
|
108
108
|
airbyte_cdk/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
|
109
109
|
airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=Rir9_z3Kcd5Es0-LChrzk-0qubAsiK_RSEnLmK2OXm8,553
|
110
|
-
airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=
|
110
|
+
airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=KflzFl_ZKRSW9XkH16sfr5-9HnAAI0T5s8CVBrJK2Ao,8958
|
111
111
|
airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py,sha256=IWUOdF03o-aQn0Occo1BJCxU0Pz-QILk5L67nzw2thw,6803
|
112
|
-
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=
|
113
|
-
airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=
|
112
|
+
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=kGU0re3R-Ujtn6Gp96KpEVRHJB5P-B8sRa0aMR_jDdk,102536
|
113
|
+
airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=1NjaZoGAIefvWwj6wx-LOKIXXWS-UnBlZFnuR7y6uYA,745
|
114
114
|
airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py,sha256=c5cuVFM6NFkuQqG8Z5IwkBuwDrvXZN1CunUOM_L0ezg,6892
|
115
115
|
airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py,sha256=t7pRdFWfFWJtQQG19c9PVeMODyO2BknRTakpM5U9N-8,4844
|
116
116
|
airbyte_cdk/sources/declarative/partition_routers/partition_router.py,sha256=YyEIzdmLd1FjbVP3QbQ2VFCLW_P-OGbVh6VpZShp54k,2218
|
@@ -152,12 +152,16 @@ airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_
|
|
152
152
|
airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py,sha256=8YRiDzjYvqJ-aMmKFcjqzv_-e8OZ5QG_TbpZ-nuCu6s,2590
|
153
153
|
airbyte_cdk/sources/declarative/requesters/request_path.py,sha256=S3MeFvcaQrMbOkSY2W2VbXLNomqt_3eXqVd9ZhgNwUs,299
|
154
154
|
airbyte_cdk/sources/declarative/requesters/requester.py,sha256=iVVpXQ4KEd9OyZNwmOofMvx7_06i8ZRxGo3aNTrEQLM,4946
|
155
|
+
airbyte_cdk/sources/declarative/resolvers/__init__.py,sha256=8cL--3WCJvtKVIIAqKWoIEhmmf3FemB7PlsnO0Mx_cY,688
|
156
|
+
airbyte_cdk/sources/declarative/resolvers/components_resolver.py,sha256=KPjKc0yb9artL4ZkeqN8RmEykHH6FJgqXD7fCEnh1X0,1936
|
157
|
+
airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py,sha256=ZA2vrHQKfXNMcH3x1iuyFOTGNzYDhUFT2qcaiOzSK0A,4271
|
155
158
|
airbyte_cdk/sources/declarative/retrievers/__init__.py,sha256=FVQpUGVwp2Gibk4gp07VmLKX5AafUlsZWFSrDpUDuJM,443
|
156
159
|
airbyte_cdk/sources/declarative/retrievers/async_retriever.py,sha256=WDFnjrXLz3-YEjFhmlMkWAn9AJvnZ0mk9FyC8DAhEYk,4976
|
157
160
|
airbyte_cdk/sources/declarative/retrievers/retriever.py,sha256=XPLs593Xv8c5cKMc37XzUAYmzlXd1a7eSsspM-CMuWA,1696
|
158
161
|
airbyte_cdk/sources/declarative/retrievers/simple_retriever.py,sha256=N4swGw5mfuTXJ2R7AKX18CHzizsr69pXwt5uSHLPi48,24172
|
159
|
-
airbyte_cdk/sources/declarative/schema/__init__.py,sha256=
|
162
|
+
airbyte_cdk/sources/declarative/schema/__init__.py,sha256=Io9vninzlEjQ2uFmWklxfwNM0cXfljtzOz5zL1OVyT4,701
|
160
163
|
airbyte_cdk/sources/declarative/schema/default_schema_loader.py,sha256=KTACrIE23a83wsm3Rd9Eb4K6-20lrGqYxTHNp9yxsso,1820
|
164
|
+
airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py,sha256=tP5DIEMn-k2JshWeXmo53ZEudDAVb4AJ50Z5tfme_ZU,8063
|
161
165
|
airbyte_cdk/sources/declarative/schema/inline_schema_loader.py,sha256=bVETE10hRsatRJq3R3BeyRR0wIoK3gcP1gcpVRQ_P5U,464
|
162
166
|
airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py,sha256=5Wl-fqW-pVf_dxJ4yGHMAFfC4JjKHYJhqFJT1xA57F4,4177
|
163
167
|
airbyte_cdk/sources/declarative/schema/schema_loader.py,sha256=kjt8v0N5wWKA5zyLnrDLxf1PJKdUqvQq2RVnAOAzNSY,379
|
@@ -313,7 +317,6 @@ airbyte_cdk/test/state_builder.py,sha256=kLPql9lNzUJaBg5YYRLJlY_Hy5JLHJDVyKPMZMo
|
|
313
317
|
airbyte_cdk/test/utils/__init__.py,sha256=Hu-1XT2KDoYjDF7-_ziDwv5bY3PueGjANOCbzeOegDg,57
|
314
318
|
airbyte_cdk/test/utils/data.py,sha256=CkCR1_-rujWNmPXFR1IXTMwx1rAl06wAyIKWpDcN02w,820
|
315
319
|
airbyte_cdk/test/utils/http_mocking.py,sha256=F2hpm2q4ijojQN5u2XtgTAp8aNgHgJ64eZNkZ9BW0ig,550
|
316
|
-
airbyte_cdk/test/utils/manifest_only_fixtures.py,sha256=kGg8kSmEouHPDCJf8GKkKqEAQaCLYfgdPEvRTb64dCI,1898
|
317
320
|
airbyte_cdk/test/utils/reading.py,sha256=SOTDYlps6Te9KumfTJ3vVDSm9EUXhvKtE8aD7gvdPlg,965
|
318
321
|
airbyte_cdk/utils/__init__.py,sha256=gHjOCoUkolS_nKtgFSudXUY-ObK2vUo6aNQLvW7o8q8,347
|
319
322
|
airbyte_cdk/utils/airbyte_secrets_utils.py,sha256=wEtRnl5KRhN6eLJwrDrC4FJjyqt_4vkA1F65mdl8c24,3142
|
@@ -331,8 +334,8 @@ airbyte_cdk/utils/slice_hasher.py,sha256=-pHexlNYoWYPnXNH-M7HEbjmeJe9Zk7SJijdQ7d
|
|
331
334
|
airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
|
332
335
|
airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
|
333
336
|
airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
|
334
|
-
airbyte_cdk-6.
|
335
|
-
airbyte_cdk-6.
|
336
|
-
airbyte_cdk-6.
|
337
|
-
airbyte_cdk-6.
|
338
|
-
airbyte_cdk-6.
|
337
|
+
airbyte_cdk-6.9.0.dev0.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
|
338
|
+
airbyte_cdk-6.9.0.dev0.dist-info/METADATA,sha256=VS_vbZgaobGxk6eCGkFZuQgCR-xzMrHzJWL2FpCnyM8,6112
|
339
|
+
airbyte_cdk-6.9.0.dev0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
340
|
+
airbyte_cdk-6.9.0.dev0.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
|
341
|
+
airbyte_cdk-6.9.0.dev0.dist-info/RECORD,,
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
2
|
-
|
3
|
-
|
4
|
-
import importlib.util
|
5
|
-
from pathlib import Path
|
6
|
-
from types import ModuleType
|
7
|
-
from typing import Optional
|
8
|
-
|
9
|
-
import pytest
|
10
|
-
|
11
|
-
# The following fixtures are used to load a manifest-only connector's components module and manifest file.
|
12
|
-
# They can be accessed from any test file in the connector's unit_tests directory by importing them as follows:
|
13
|
-
|
14
|
-
# from airbyte_cdk.test.utils.manifest_only_fixtures import components_module, connector_dir, manifest_path
|
15
|
-
|
16
|
-
# individual components can then be referenced as: components_module.<CustomComponentClass>
|
17
|
-
|
18
|
-
|
19
|
-
@pytest.fixture(scope="session")
|
20
|
-
def connector_dir(request: pytest.FixtureRequest) -> Path:
|
21
|
-
"""Return the connector's root directory.
|
22
|
-
|
23
|
-
This assumes tests are being run from the unit_tests directory,
|
24
|
-
and that it is a direct child of the connector directory.
|
25
|
-
"""
|
26
|
-
test_dir = Path(request.config.invocation_params.dir)
|
27
|
-
return test_dir.parent
|
28
|
-
|
29
|
-
|
30
|
-
@pytest.fixture(scope="session")
|
31
|
-
def components_module(connector_dir: Path) -> Optional[ModuleType]:
|
32
|
-
"""Load and return the components module from the connector directory.
|
33
|
-
|
34
|
-
This assumes the components module is located at <connector_dir>/components.py.
|
35
|
-
"""
|
36
|
-
components_path = connector_dir / "components.py"
|
37
|
-
if not components_path.exists():
|
38
|
-
return None
|
39
|
-
|
40
|
-
components_spec = importlib.util.spec_from_file_location("components", components_path)
|
41
|
-
if components_spec is None:
|
42
|
-
return None
|
43
|
-
|
44
|
-
components_module = importlib.util.module_from_spec(components_spec)
|
45
|
-
if components_spec.loader is None:
|
46
|
-
return None
|
47
|
-
|
48
|
-
components_spec.loader.exec_module(components_module)
|
49
|
-
return components_module
|
50
|
-
|
51
|
-
|
52
|
-
@pytest.fixture(scope="session")
|
53
|
-
def manifest_path(connector_dir: Path) -> Path:
|
54
|
-
"""Return the path to the connector's manifest file."""
|
55
|
-
return connector_dir / "manifest.yaml"
|