airbyte-cdk 0.67.0__py3-none-any.whl → 0.67.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. airbyte_cdk/sources/abstract_source.py +30 -69
  2. airbyte_cdk/sources/connector_state_manager.py +12 -26
  3. airbyte_cdk/sources/declarative/models/declarative_component_schema.py +552 -524
  4. airbyte_cdk/sources/file_based/config/csv_format.py +2 -0
  5. airbyte_cdk/sources/file_based/file_types/parquet_parser.py +32 -14
  6. airbyte_cdk/sources/file_based/stream/concurrent/adapters.py +3 -19
  7. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py +1 -3
  8. airbyte_cdk/sources/streams/__init__.py +2 -2
  9. airbyte_cdk/sources/streams/concurrent/adapters.py +3 -19
  10. airbyte_cdk/sources/streams/concurrent/cursor.py +1 -3
  11. airbyte_cdk/sources/streams/core.py +36 -34
  12. {airbyte_cdk-0.67.0.dist-info → airbyte_cdk-0.67.2.dist-info}/METADATA +3 -2
  13. {airbyte_cdk-0.67.0.dist-info → airbyte_cdk-0.67.2.dist-info}/RECORD +31 -31
  14. unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py +2 -1
  15. unit_tests/sources/file_based/config/test_csv_format.py +6 -1
  16. unit_tests/sources/file_based/file_types/test_parquet_parser.py +51 -6
  17. unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py +139 -199
  18. unit_tests/sources/file_based/scenarios/incremental_scenarios.py +91 -133
  19. unit_tests/sources/file_based/stream/concurrent/test_adapters.py +2 -13
  20. unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py +2 -2
  21. unit_tests/sources/file_based/test_scenarios.py +2 -2
  22. unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py +9 -9
  23. unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py +5 -5
  24. unit_tests/sources/streams/concurrent/test_adapters.py +2 -13
  25. unit_tests/sources/streams/test_stream_read.py +221 -11
  26. unit_tests/sources/test_abstract_source.py +142 -130
  27. unit_tests/sources/test_connector_state_manager.py +3 -124
  28. unit_tests/sources/test_source.py +18 -14
  29. {airbyte_cdk-0.67.0.dist-info → airbyte_cdk-0.67.2.dist-info}/LICENSE.txt +0 -0
  30. {airbyte_cdk-0.67.0.dist-info → airbyte_cdk-0.67.2.dist-info}/WHEEL +0 -0
  31. {airbyte_cdk-0.67.0.dist-info → airbyte_cdk-0.67.2.dist-info}/top_level.txt +0 -0
@@ -150,6 +150,8 @@ class CsvFormat(BaseModel):
150
150
 
151
151
  @validator("delimiter")
152
152
  def validate_delimiter(cls, v: str) -> str:
153
+ if v == r"\t":
154
+ return v
153
155
  if len(v) != 1:
154
156
  raise ValueError("delimiter should only be one character")
155
157
  if v in {"\r", "\n"}:
@@ -5,7 +5,7 @@
5
5
  import json
6
6
  import logging
7
7
  import os
8
- from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple
8
+ from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union
9
9
  from urllib.parse import unquote
10
10
 
11
11
  import pyarrow as pa
@@ -16,7 +16,7 @@ from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFile
16
16
  from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser
17
17
  from airbyte_cdk.sources.file_based.remote_file import RemoteFile
18
18
  from airbyte_cdk.sources.file_based.schema_helpers import SchemaType
19
- from pyarrow import Scalar
19
+ from pyarrow import DictionaryArray, Scalar
20
20
 
21
21
 
22
22
  class ParquetParser(FileTypeParser):
@@ -95,10 +95,23 @@ class ParquetParser(FileTypeParser):
95
95
  return FileReadMode.READ_BINARY
96
96
 
97
97
  @staticmethod
98
- def _to_output_value(parquet_value: Scalar, parquet_format: ParquetFormat) -> Any:
98
+ def _to_output_value(parquet_value: Union[Scalar, DictionaryArray], parquet_format: ParquetFormat) -> Any:
99
+ """
100
+ Convert an entry in a pyarrow table to a value that can be output by the source.
101
+ """
102
+ if isinstance(parquet_value, DictionaryArray):
103
+ return ParquetParser._dictionary_array_to_python_value(parquet_value)
104
+ else:
105
+ return ParquetParser._scalar_to_python_value(parquet_value, parquet_format)
106
+
107
+ @staticmethod
108
+ def _scalar_to_python_value(parquet_value: Scalar, parquet_format: ParquetFormat) -> Any:
99
109
  """
100
110
  Convert a pyarrow scalar to a value that can be output by the source.
101
111
  """
112
+ if parquet_value.as_py() is None:
113
+ return None
114
+
102
115
  # Convert date and datetime objects to isoformat strings
103
116
  if pa.types.is_time(parquet_value.type) or pa.types.is_timestamp(parquet_value.type) or pa.types.is_date(parquet_value.type):
104
117
  return parquet_value.as_py().isoformat()
@@ -109,23 +122,14 @@ class ParquetParser(FileTypeParser):
109
122
 
110
123
  # Decode binary strings to utf-8
111
124
  if ParquetParser._is_binary(parquet_value.type):
112
- py_value = parquet_value.as_py()
113
- if py_value is None:
114
- return py_value
115
- return py_value.decode("utf-8")
125
+ return parquet_value.as_py().decode("utf-8")
126
+
116
127
  if pa.types.is_decimal(parquet_value.type):
117
128
  if parquet_format.decimal_as_float:
118
129
  return parquet_value.as_py()
119
130
  else:
120
131
  return str(parquet_value.as_py())
121
132
 
122
- # Dictionaries are stored as two columns: indices and values
123
- # The indices column is an array of integers that maps to the values column
124
- if pa.types.is_dictionary(parquet_value.type):
125
- return {
126
- "indices": parquet_value.indices.tolist(),
127
- "values": parquet_value.dictionary.tolist(),
128
- }
129
133
  if pa.types.is_map(parquet_value.type):
130
134
  return {k: v for k, v in parquet_value.as_py()}
131
135
 
@@ -149,6 +153,20 @@ class ParquetParser(FileTypeParser):
149
153
  else:
150
154
  return parquet_value.as_py()
151
155
 
156
+ @staticmethod
157
+ def _dictionary_array_to_python_value(parquet_value: DictionaryArray) -> Dict[str, Any]:
158
+ """
159
+ Convert a pyarrow dictionary array to a value that can be output by the source.
160
+
161
+ Dictionaries are stored as two columns: indices and values
162
+ The indices column is an array of integers that maps to the values column
163
+ """
164
+
165
+ return {
166
+ "indices": parquet_value.indices.tolist(),
167
+ "values": parquet_value.dictionary.tolist(),
168
+ }
169
+
152
170
  @staticmethod
153
171
  def parquet_type_to_schema_type(parquet_type: pa.DataType, parquet_format: ParquetFormat) -> Mapping[str, str]:
154
172
  """
@@ -7,7 +7,7 @@ import logging
7
7
  from functools import lru_cache
8
8
  from typing import TYPE_CHECKING, Any, Iterable, List, Mapping, MutableMapping, Optional, Union
9
9
 
10
- from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, SyncMode, Type
10
+ from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, ConfiguredAirbyteStream, Level, SyncMode, Type
11
11
  from airbyte_cdk.sources import AbstractSource
12
12
  from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager
13
13
  from airbyte_cdk.sources.file_based.availability_strategy import (
@@ -156,29 +156,13 @@ class FileBasedStreamFacade(AbstractStreamFacade[DefaultStream], AbstractFileBas
156
156
  def get_underlying_stream(self) -> DefaultStream:
157
157
  return self._abstract_stream
158
158
 
159
- def read_full_refresh(
159
+ def read(
160
160
  self,
161
- cursor_field: Optional[List[str]],
162
- logger: logging.Logger,
163
- slice_logger: SliceLogger,
164
- ) -> Iterable[StreamData]:
165
- """
166
- Read full refresh. Delegate to the underlying AbstractStream, ignoring all the parameters
167
- :param cursor_field: (ignored)
168
- :param logger: (ignored)
169
- :param slice_logger: (ignored)
170
- :return: Iterable of StreamData
171
- """
172
- yield from self._read_records()
173
-
174
- def read_incremental(
175
- self,
176
- cursor_field: Optional[List[str]],
161
+ configured_stream: ConfiguredAirbyteStream,
177
162
  logger: logging.Logger,
178
163
  slice_logger: SliceLogger,
179
164
  stream_state: MutableMapping[str, Any],
180
165
  state_manager: ConnectorStateManager,
181
- per_stream_state_enabled: bool,
182
166
  internal_config: InternalConfig,
183
167
  ) -> Iterable[StreamData]:
184
168
  yield from self._read_records()
@@ -155,9 +155,7 @@ class FileBasedConcurrentCursor(AbstractConcurrentFileBasedCursor):
155
155
  self._stream_namespace,
156
156
  new_state,
157
157
  )
158
- state_message = self._connector_state_manager.create_state_message(
159
- self._stream_name, self._stream_namespace, send_per_stream_state=True
160
- )
158
+ state_message = self._connector_state_manager.create_state_message(self._stream_name, self._stream_namespace)
161
159
  self._message_repository.emit_message(state_message)
162
160
 
163
161
  def _get_new_cursor_value(self) -> str:
@@ -3,6 +3,6 @@
3
3
  #
4
4
 
5
5
  # Initialize Streams Package
6
- from .core import IncrementalMixin, Stream
6
+ from .core import FULL_REFRESH_SENTINEL_STATE_KEY, IncrementalMixin, Stream
7
7
 
8
- __all__ = ["IncrementalMixin", "Stream"]
8
+ __all__ = ["FULL_REFRESH_SENTINEL_STATE_KEY", "IncrementalMixin", "Stream"]
@@ -8,7 +8,7 @@ import logging
8
8
  from functools import lru_cache
9
9
  from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union
10
10
 
11
- from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteStream, Level, SyncMode, Type
11
+ from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteStream, ConfiguredAirbyteStream, Level, SyncMode, Type
12
12
  from airbyte_cdk.sources import AbstractSource, Source
13
13
  from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager
14
14
  from airbyte_cdk.sources.message import MessageRepository
@@ -116,29 +116,13 @@ class StreamFacade(AbstractStreamFacade[DefaultStream], Stream):
116
116
  self._slice_logger = slice_logger
117
117
  self._logger = logger
118
118
 
119
- def read_full_refresh(
119
+ def read(
120
120
  self,
121
- cursor_field: Optional[List[str]],
122
- logger: logging.Logger,
123
- slice_logger: SliceLogger,
124
- ) -> Iterable[StreamData]:
125
- """
126
- Read full refresh. Delegate to the underlying AbstractStream, ignoring all the parameters
127
- :param cursor_field: (ignored)
128
- :param logger: (ignored)
129
- :param slice_logger: (ignored)
130
- :return: Iterable of StreamData
131
- """
132
- yield from self._read_records()
133
-
134
- def read_incremental(
135
- self,
136
- cursor_field: Optional[List[str]],
121
+ configured_stream: ConfiguredAirbyteStream,
137
122
  logger: logging.Logger,
138
123
  slice_logger: SliceLogger,
139
124
  stream_state: MutableMapping[str, Any],
140
125
  state_manager: ConnectorStateManager,
141
- per_stream_state_enabled: bool,
142
126
  internal_config: InternalConfig,
143
127
  ) -> Iterable[StreamData]:
144
128
  yield from self._read_records()
@@ -184,9 +184,7 @@ class ConcurrentCursor(Cursor):
184
184
  # TODO: if we migrate stored state to the concurrent state format
185
185
  # (aka stop calling self._connector_state_converter.convert_to_sequential_state`), we'll need to cast datetimes to string or
186
186
  # int before emitting state
187
- state_message = self._connector_state_manager.create_state_message(
188
- self._stream_name, self._stream_namespace, send_per_stream_state=True
189
- )
187
+ state_message = self._connector_state_manager.create_state_message(self._stream_name, self._stream_namespace)
190
188
  self._message_repository.emit_message(state_message)
191
189
 
192
190
  def _merge_partitions(self) -> None:
@@ -11,7 +11,7 @@ from functools import lru_cache
11
11
  from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union
12
12
 
13
13
  import airbyte_cdk.sources.utils.casing as casing
14
- from airbyte_cdk.models import AirbyteMessage, AirbyteStream, SyncMode
14
+ from airbyte_cdk.models import AirbyteMessage, AirbyteStream, ConfiguredAirbyteStream, SyncMode
15
15
  from airbyte_cdk.models import Type as MessageType
16
16
 
17
17
  # list of all possible HTTP methods which can be used for sending of request bodies
@@ -31,6 +31,10 @@ StreamData = Union[Mapping[str, Any], AirbyteMessage]
31
31
 
32
32
  JsonSchema = Mapping[str, Any]
33
33
 
34
+ # Streams that only support full refresh don't have a suitable cursor so this sentinel
35
+ # value is used to indicate that stream should not load the incoming state value
36
+ FULL_REFRESH_SENTINEL_STATE_KEY = "__ab_full_refresh_state_message"
37
+
34
38
 
35
39
  def package_name_from_class(cls: object) -> str:
36
40
  """Find the package name given a class name"""
@@ -107,39 +111,24 @@ class Stream(ABC):
107
111
  """
108
112
  return None
109
113
 
110
- def read_full_refresh(
111
- self,
112
- cursor_field: Optional[List[str]],
113
- logger: logging.Logger,
114
- slice_logger: SliceLogger,
115
- ) -> Iterable[StreamData]:
116
- slices = self.stream_slices(sync_mode=SyncMode.full_refresh, cursor_field=cursor_field)
117
- logger.debug(f"Processing stream slices for {self.name} (sync_mode: full_refresh)", extra={"stream_slices": slices})
118
- for _slice in slices:
119
- if slice_logger.should_log_slice_message(logger):
120
- yield slice_logger.create_slice_log_message(_slice)
121
- yield from self.read_records(
122
- stream_slice=_slice,
123
- sync_mode=SyncMode.full_refresh,
124
- cursor_field=cursor_field,
125
- )
126
-
127
- def read_incremental( # type: ignore # ignoring typing for ConnectorStateManager because of circular dependencies
114
+ def read( # type: ignore # ignoring typing for ConnectorStateManager because of circular dependencies
128
115
  self,
129
- cursor_field: Optional[List[str]],
116
+ configured_stream: ConfiguredAirbyteStream,
130
117
  logger: logging.Logger,
131
118
  slice_logger: SliceLogger,
132
119
  stream_state: MutableMapping[str, Any],
133
120
  state_manager,
134
- per_stream_state_enabled: bool,
135
121
  internal_config: InternalConfig,
136
122
  ) -> Iterable[StreamData]:
123
+ sync_mode = configured_stream.sync_mode
124
+ cursor_field = configured_stream.cursor_field
125
+
137
126
  slices = self.stream_slices(
138
127
  cursor_field=cursor_field,
139
- sync_mode=SyncMode.incremental,
128
+ sync_mode=sync_mode, # todo: change this interface to no longer rely on sync_mode for behavior
140
129
  stream_state=stream_state,
141
130
  )
142
- logger.debug(f"Processing stream slices for {self.name} (sync_mode: incremental)", extra={"stream_slices": slices})
131
+ logger.debug(f"Processing stream slices for {self.name} (sync_mode: {sync_mode.name})", extra={"stream_slices": slices})
143
132
 
144
133
  has_slices = False
145
134
  record_counter = 0
@@ -148,7 +137,7 @@ class Stream(ABC):
148
137
  if slice_logger.should_log_slice_message(logger):
149
138
  yield slice_logger.create_slice_log_message(_slice)
150
139
  records = self.read_records(
151
- sync_mode=SyncMode.incremental,
140
+ sync_mode=sync_mode, # todo: change this interface to no longer rely on sync_mode for behavior
152
141
  stream_slice=_slice,
153
142
  stream_state=stream_state,
154
143
  cursor_field=cursor_field or None,
@@ -160,20 +149,34 @@ class Stream(ABC):
160
149
  ):
161
150
  record_data = record_data_or_message if isinstance(record_data_or_message, Mapping) else record_data_or_message.record
162
151
  stream_state = self.get_updated_state(stream_state, record_data)
163
- checkpoint_interval = self.state_checkpoint_interval
164
152
  record_counter += 1
165
- if checkpoint_interval and record_counter % checkpoint_interval == 0:
166
- yield self._checkpoint_state(stream_state, state_manager, per_stream_state_enabled)
153
+
154
+ if sync_mode == SyncMode.incremental:
155
+ # Checkpoint intervals are a bit controversial, but see below comment about why we're gating it right now
156
+ checkpoint_interval = self.state_checkpoint_interval
157
+ if checkpoint_interval and record_counter % checkpoint_interval == 0:
158
+ airbyte_state_message = self._checkpoint_state(stream_state, state_manager)
159
+ yield airbyte_state_message
167
160
 
168
161
  if internal_config.is_limit_reached(record_counter):
169
162
  break
170
163
 
171
- yield self._checkpoint_state(stream_state, state_manager, per_stream_state_enabled)
164
+ if sync_mode == SyncMode.incremental:
165
+ # Even though right now, only incremental streams running as incremental mode will emit periodic checkpoints. Rather than
166
+ # overhaul how refresh interacts with the platform, this positions the code so that once we want to start emitting
167
+ # periodic checkpoints in full refresh mode it can be done here
168
+ airbyte_state_message = self._checkpoint_state(stream_state, state_manager)
169
+ yield airbyte_state_message
170
+
171
+ if not has_slices or sync_mode == SyncMode.full_refresh:
172
+ if sync_mode == SyncMode.full_refresh:
173
+ # We use a dummy state if there is no suitable value provided by full_refresh streams that do not have a valid cursor.
174
+ # Incremental streams running full_refresh mode emit a meaningful state
175
+ stream_state = stream_state or {FULL_REFRESH_SENTINEL_STATE_KEY: True}
172
176
 
173
- if not has_slices:
174
- # Safety net to ensure we always emit at least one state message even if there are no slices
175
- checkpoint = self._checkpoint_state(stream_state, state_manager, per_stream_state_enabled)
176
- yield checkpoint
177
+ # We should always emit a final state message for full refresh sync or streams that do not have any slices
178
+ airbyte_state_message = self._checkpoint_state(stream_state, state_manager)
179
+ yield airbyte_state_message
177
180
 
178
181
  @abstractmethod
179
182
  def read_records(
@@ -361,7 +364,6 @@ class Stream(ABC):
361
364
  self,
362
365
  stream_state: Mapping[str, Any],
363
366
  state_manager,
364
- per_stream_state_enabled: bool,
365
367
  ) -> AirbyteMessage:
366
368
  # First attempt to retrieve the current state using the stream's state property. We receive an AttributeError if the state
367
369
  # property is not implemented by the stream instance and as a fallback, use the stream_state retrieved from the stream
@@ -373,4 +375,4 @@ class Stream(ABC):
373
375
 
374
376
  except AttributeError:
375
377
  state_manager.update_state_for_stream(self.name, self.namespace, stream_state)
376
- return state_manager.create_state_message(self.name, self.namespace, send_per_stream_state=per_stream_state_enabled)
378
+ return state_manager.create_state_message(self.name, self.namespace)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 0.67.0
3
+ Version: 0.67.2
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://github.com/airbytehq/airbyte
6
6
  Author: Airbyte
@@ -147,7 +147,8 @@ pip install -e ".[dev]" # [dev] installs development-only dependencies
147
147
  If the iteration you are working on includes changes to the models, you might want to regenerate them. In order to do that, you can run:
148
148
 
149
149
  ```bash
150
- ./gradlew :airbyte-cdk:python:build
150
+ cd airbyte-cdk/python
151
+ ./gradlew build
151
152
  ```
152
153
 
153
154
  This will generate the files based on the schemas, add the license information and format the code. If you want to only do the former and rely on
@@ -24,9 +24,9 @@ airbyte_cdk/models/__init__.py,sha256=Kg8YHBqUsNWHlAw-u3ZGdG4dxLh7qBlHhqMRfamNCR
24
24
  airbyte_cdk/models/airbyte_protocol.py,sha256=DoJvnmGM3xMAZFTwA6_RGMiKSFqfE3ib_Ru0KJ65Ag4,100
25
25
  airbyte_cdk/models/well_known_types.py,sha256=KKfNbow2gdLoC1Z4hcXy_JR8m_acsB2ol7gQuEgjobw,117
26
26
  airbyte_cdk/sources/__init__.py,sha256=Ov7Uf03KPSZUmMZqZfUAK3tQwsdKjDQUDvTb-H0JyfA,1141
27
- airbyte_cdk/sources/abstract_source.py,sha256=Gie6CY-WztnUtOahoyMRlV8ON48eDIzjVG6fUKwCqvw,16127
27
+ airbyte_cdk/sources/abstract_source.py,sha256=vcYtKYZkQnKQamj7lB11xU32yFkZSlCrN7Z1n2iGKXM,15033
28
28
  airbyte_cdk/sources/config.py,sha256=PYsY7y2u3EUwxLiEb96JnuKwH_E8CuxKggsRO2ZPSRc,856
29
- airbyte_cdk/sources/connector_state_manager.py,sha256=p9iwWbb5uqRbsrHsdZBMXKmyHgLVbsOcV3QQexBFnPE,11052
29
+ airbyte_cdk/sources/connector_state_manager.py,sha256=rMb8roMcupsKtTXbGsufVl6bq-XVGBTxyTqTOuluMQs,10003
30
30
  airbyte_cdk/sources/http_config.py,sha256=OBZeuyFilm6NlDlBhFQvHhTWabEvZww6OHDIlZujIS0,730
31
31
  airbyte_cdk/sources/http_logger.py,sha256=v0kkpDtA0GUOgj6_3AayrYaBrSHBqG4t3MGbrtxaNmU,1437
32
32
  airbyte_cdk/sources/source.py,sha256=dk50z8Roc28MJ8FxWe652B-GwItO__bTZqFm7WOtHnw,4412
@@ -80,7 +80,7 @@ airbyte_cdk/sources/declarative/interpolation/interpolation.py,sha256=dyIM-bzh54
80
80
  airbyte_cdk/sources/declarative/interpolation/jinja.py,sha256=8bUH6xJRkao8BanwzBFj-1CDj7RR2xPO5u_-FfyRNks,5128
81
81
  airbyte_cdk/sources/declarative/interpolation/macros.py,sha256=V6WGKJ9cXX1rjuM4bK3Cs9xEryMlkY2U3FMsSBhrgC8,3098
82
82
  airbyte_cdk/sources/declarative/models/__init__.py,sha256=EiYnzwCHZV7EYqMJqcy6xKSeHvTKZBsQndjbEwmiTW4,93
83
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=5KuQHvfjJGuHxS17kxv0WNDg6eIEpttbKljTcOg_CpQ,60726
83
+ airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=YBz0FIS8crj3bJ8sErWtCRol-6he1fewoMgQtAWj2XM,60991
84
84
  airbyte_cdk/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
85
85
  airbyte_cdk/sources/declarative/parsers/class_types_registry.py,sha256=5vOvMuyWlpALrOq2ehLxa7wO6tlFIlgUNtMYrMCKIjE,6092
86
86
  airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=y7_G5mM07zxT5YG975kdC2PAja-Uc83pYp8WrV3GNdo,522
@@ -164,7 +164,7 @@ airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availabi
164
164
  airbyte_cdk/sources/file_based/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
165
  airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py,sha256=dgOoQuoi7-7wdTMSP7wz4ENXIDT49Ew4FoAxnnplGGc,4956
166
166
  airbyte_cdk/sources/file_based/config/avro_format.py,sha256=q1I2G9bGNy3ADds35PfWT7Mss6fjYzUtYDkUYvh5v7s,712
167
- airbyte_cdk/sources/file_based/config/csv_format.py,sha256=L3JEgb91yrCob1oYrGl0088QEWblkOsRfDmMfWRQ0bg,7482
167
+ airbyte_cdk/sources/file_based/config/csv_format.py,sha256=XcKuM2xa0OZErSDdOdeAx79KZV52lKvVXXuRDYLKVuk,7526
168
168
  airbyte_cdk/sources/file_based/config/file_based_stream_config.py,sha256=l9DFyttYbxY9exwy67WzRXySEk_yKV2G_THRA_Sq1I4,4229
169
169
  airbyte_cdk/sources/file_based/config/jsonl_format.py,sha256=fAPzZnoghGgHjaDvx6Qo68C8j54mBxo1NTdpwSI0VZo,374
170
170
  airbyte_cdk/sources/file_based/config/parquet_format.py,sha256=yKHgXYu3zJWrGfBlJ3JQZ3gVFPumF-K4rjVPNoYTUZ0,737
@@ -177,7 +177,7 @@ airbyte_cdk/sources/file_based/file_types/avro_parser.py,sha256=FC3L6D32SzhAv4jy
177
177
  airbyte_cdk/sources/file_based/file_types/csv_parser.py,sha256=biq2Fi7Nw5K1hIX_MelctEfpC5BEbGRqHL8rkCjS9ng,18414
178
178
  airbyte_cdk/sources/file_based/file_types/file_type_parser.py,sha256=Gbn-8v1-jLhKpJXTNOOc5PZT1Jzah6G-INCZt4snLdQ,2819
179
179
  airbyte_cdk/sources/file_based/file_types/jsonl_parser.py,sha256=MkjK_J2OqzqRPyGeQFQFADxgwqsRaNtoawB7dwKxWb0,5666
180
- airbyte_cdk/sources/file_based/file_types/parquet_parser.py,sha256=8ZuuYnS2AzlJ-IaeBP6Pnjzu4Z2zzfBWw_x9Rt9a5Qs,9363
180
+ airbyte_cdk/sources/file_based/file_types/parquet_parser.py,sha256=xktrUFFzBD-mlnu0MMa0O6HIrZBmaQCAqDgi28tPzOc,9998
181
181
  airbyte_cdk/sources/file_based/file_types/unstructured_parser.py,sha256=omYdo6daIHI-YWF9WsKFdFHRXTFWgJjJ3OqegiN345k,16736
182
182
  airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py,sha256=sEVnRhZ8x9f7PNjo6lewxid9z0PI8eSj7gSoFC3MH1Y,527
183
183
  airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py,sha256=uwk6Ugf23xKG4PRPVVRVwpcNjTwPgxejl03vLSEzK0s,604
@@ -186,10 +186,10 @@ airbyte_cdk/sources/file_based/stream/__init__.py,sha256=QPDqdgjsabOQD93dSFqHGaF
186
186
  airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py,sha256=cmO1SQt5PIQRNNoh2KBv6aeY8NEY9x2dlmiRwGwU1vg,6557
187
187
  airbyte_cdk/sources/file_based/stream/default_file_based_stream.py,sha256=qS0DJzXlVew6armFDJ0eNcSxRCmkA7JWQYFl6gcv3dU,13113
188
188
  airbyte_cdk/sources/file_based/stream/concurrent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
189
- airbyte_cdk/sources/file_based/stream/concurrent/adapters.py,sha256=rjf8htUotdAXWSGcFA0jFHJfaai_EnmQxncnxMWTN2A,13320
189
+ airbyte_cdk/sources/file_based/stream/concurrent/adapters.py,sha256=G93wu1oo1OOUWrl3z16wISYN8JyqJitkpfeqv5016vc,12806
190
190
  airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py,sha256=4gi-_oETrHYZClD12okh13INBsI2OfugKhToXtohRTs,310
191
191
  airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py,sha256=UYLE2A2RdV-5FaQ70naZZWY34l5AEJkIRlTH05-e_-k,1961
192
- airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py,sha256=jHiej28aKQJ3UmWXQxHRCK8xkzY5H0-zxQiVqFs5rAI,14389
192
+ airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py,sha256=Bs8e05pbY1OhTUsklhIqrfeCataME_fkg0ToakifHgY,14331
193
193
  airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_noop_cursor.py,sha256=wblXBgNw-QLVPNOAL8DihlQBXbvPC1zCdDWMsPdZPzQ,1852
194
194
  airbyte_cdk/sources/file_based/stream/cursor/__init__.py,sha256=MhFB5hOo8sjwvCh8gangaymdg3EJWYt_72brFOZt068,191
195
195
  airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py,sha256=i-FPeK8lwCzX34GCcmvL5Yvdh8-uu7FeCVYDoFbD7IY,1920
@@ -199,16 +199,16 @@ airbyte_cdk/sources/message/repository.py,sha256=tQOmtWxrAp1CMiOKi5SdIEWzcmgnCUY
199
199
  airbyte_cdk/sources/singer/__init__.py,sha256=D3zQSiWT0B9t0kKE4JPZjrcDnP2YnFNJ3dfYqSaxo9w,246
200
200
  airbyte_cdk/sources/singer/singer_helpers.py,sha256=q1LmgjFxSnN-dobMy7nikUwcK-9FvW5QQfgTqiclbAE,15649
201
201
  airbyte_cdk/sources/singer/source.py,sha256=3YY8UTOXmctvMVUnYmIegmL3_IxF55iGP_bc_s2MZdY,8530
202
- airbyte_cdk/sources/streams/__init__.py,sha256=IztrWN5IU_N5GCKDyRSEuoWdZohFTcgIbAIkaCFkr_Q,176
202
+ airbyte_cdk/sources/streams/__init__.py,sha256=VBGcpSl-SdcY5ajsHe99GLNC4NXAYIm1k1MZxWYllAE,244
203
203
  airbyte_cdk/sources/streams/availability_strategy.py,sha256=7BM0qLvXS0QrlKvnVkBEw4Cw8i7PCENCBLcIAcuD3nY,1007
204
204
  airbyte_cdk/sources/streams/call_rate.py,sha256=5T4J8WxMNov76iXRUtD5KlM1CsROxuAQPwGQAZyvpHg,20555
205
- airbyte_cdk/sources/streams/core.py,sha256=bIuQV7Zs9JpIyNDcfPCbyzv-BWDr_2ictK7s5AihLZQ,16025
205
+ airbyte_cdk/sources/streams/core.py,sha256=UdJfpc1jwT6igY-e5w-ow5ciT5feHq8F79Dxvpc1Sss,16741
206
206
  airbyte_cdk/sources/streams/concurrent/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
207
207
  airbyte_cdk/sources/streams/concurrent/abstract_stream.py,sha256=HlnmAh-LcQbs9g1r0iUAUe3IN0RmUSZits5Nyers51g,3792
208
208
  airbyte_cdk/sources/streams/concurrent/abstract_stream_facade.py,sha256=QTry1QCBUwJDw1QSCEvz23s7zIEx_7QMxkPq9j-oPIQ,1358
209
- airbyte_cdk/sources/streams/concurrent/adapters.py,sha256=FokiPnhjn3IQpRyQ6rr0ABJKYU0Sd1kNulWlQV_nuX8,16781
209
+ airbyte_cdk/sources/streams/concurrent/adapters.py,sha256=ok68ZE2tYH3XR0Ti3mwSsCO_WQSGyqTCXTFI5Gc5WZk,16267
210
210
  airbyte_cdk/sources/streams/concurrent/availability_strategy.py,sha256=8xDRpfktnARBbRi_RwznvKuoGrpPF2b6tQyloMwogkM,2013
211
- airbyte_cdk/sources/streams/concurrent/cursor.py,sha256=6Z-PQWp1Jszryao4nSvHEUyKxX3Uur4Jk1MTsQ9AxQY,9782
211
+ airbyte_cdk/sources/streams/concurrent/cursor.py,sha256=KaLdNz5auNIOtLPF94g4un-BVUH9JHSvw3UrCwBUqAg,9732
212
212
  airbyte_cdk/sources/streams/concurrent/default_stream.py,sha256=qPhMaLxGdR29kyMeA-YrHg-XePgPNDjactQPKbp56RA,3009
213
213
  airbyte_cdk/sources/streams/concurrent/exceptions.py,sha256=-WETGIY5_QFmVeDFiqm4WhRJ_nNCkfcDwOQqx6cSqrI,365
214
214
  airbyte_cdk/sources/streams/concurrent/helpers.py,sha256=FPdGovWg0_hPxoTCAJnqs2SEqEq32pRGKlvPMP7hGWo,1290
@@ -282,16 +282,16 @@ unit_tests/singer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
282
282
  unit_tests/singer/test_singer_helpers.py,sha256=pZV6VxJuK-3-FICNGmoGbokrA_zkaFZEd4rYZCVpSRU,1762
283
283
  unit_tests/singer/test_singer_source.py,sha256=edN_kv7dnYAdBveWdUYOs74ak0dK6p8uaX225h_ZILA,4442
284
284
  unit_tests/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
285
- unit_tests/sources/test_abstract_source.py,sha256=Hi9TMKGs1KoxwchhG4Wa78MYt4Yyk6DOs_rJtanL80I,59719
285
+ unit_tests/sources/test_abstract_source.py,sha256=TZ9Mn_kT9A2A_CRJLS9OQjBnlWrPRqf8EyNd8eJ_ZrM,57197
286
286
  unit_tests/sources/test_concurrent_source.py,sha256=3i7pSRetKSoP6LBpXyuXpWi2_VOwta_aTm_kgnDaLqk,3704
287
287
  unit_tests/sources/test_config.py,sha256=lxjeaf48pOMF4Pf3-Z1ux_tHTyjRFCdG_hpnxw3e7uQ,2839
288
- unit_tests/sources/test_connector_state_manager.py,sha256=WLvNqUZafPp1o3OgRIlOtEgQhXhbx5jU899ACr0KQIE,24414
288
+ unit_tests/sources/test_connector_state_manager.py,sha256=PGvBh90FAtG7vp_4y8nZxcjx1mEcFn382PCdBH-r9-I,19588
289
289
  unit_tests/sources/test_http_logger.py,sha256=VT6DqgspI3DcRnoBQkkQX0z4dF_AOiYZ5P_zxmMW8oU,9004
290
290
  unit_tests/sources/test_integration_source.py,sha256=qcWld9evB1rAjALWX8SDshGz7seYkN3HCamQ6KQ2Idw,4269
291
- unit_tests/sources/test_source.py,sha256=W0I4umL_d_OToLYYiRkjkJR6e-cCYjdV8zKc3uLvF0k,27999
291
+ unit_tests/sources/test_source.py,sha256=zwyU7pLwQaEzeozxPJzNeRvZXb2xddeWO4bLqdMt9BM,28343
292
292
  unit_tests/sources/test_source_read.py,sha256=n9XpVQLfsQH8eh6D99MDiNVBBKcf6UtouThDJcGH6SU,17186
293
293
  unit_tests/sources/concurrent_source/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
294
- unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py,sha256=zsGnMcEsBedjW8wahil6LNqniil-3NXhyZd5W-80Km0,3665
294
+ unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py,sha256=ZEJzOm9pVFHrXBS3cT43XdK_vopICZmoqzFsTE2E8Tk,3675
295
295
  unit_tests/sources/declarative/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
296
296
  unit_tests/sources/declarative/external_component.py,sha256=lU2gL736bLEWtmrGm1B2k83RXt_3XkROimLIahZd5dg,293
297
297
  unit_tests/sources/declarative/test_create_partial.py,sha256=s_KIywQqt8RlauOCWNJVk3HC3KBTAtSwFTN6JVQgu80,2636
@@ -373,13 +373,13 @@ unit_tests/sources/file_based/helpers.py,sha256=JSKXrPL7iSBSH7nkKde-jcylVuDohJid
373
373
  unit_tests/sources/file_based/in_memory_files_source.py,sha256=1UCfRMgaovPdhkORT5k5Izj6e0ldPp802iiaffG2ghk,8550
374
374
  unit_tests/sources/file_based/test_file_based_scenarios.py,sha256=llrPRotbYvUrORrqOFH8nMqQZ_QSs4sYwwgvqzkQsvc,15355
375
375
  unit_tests/sources/file_based/test_file_based_stream_reader.py,sha256=P6yTp7tbPfREzi5SXg4SSSql5nxiRV571YdOmwb_SzY,9219
376
- unit_tests/sources/file_based/test_scenarios.py,sha256=yGKsGkhp8l9Ut8L0VaQYRCRSVZO1twYKnm-xRPEqtmw,9361
376
+ unit_tests/sources/file_based/test_scenarios.py,sha256=85qb_CXTGNTS7pk-N73EGd55J0Cnky8i1G900cs4sek,9405
377
377
  unit_tests/sources/file_based/test_schema_helpers.py,sha256=IYIDdLRK41RkSG_ZW2cagAt9krV4QLbkzu6r7vPx9Js,12047
378
378
  unit_tests/sources/file_based/availability_strategy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
379
379
  unit_tests/sources/file_based/availability_strategy/test_default_file_based_availability_strategy.py,sha256=14ffoRWC4RHPrmBFZpplnAd1Uezn8neuQrIyZqvjTK0,4964
380
380
  unit_tests/sources/file_based/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
381
381
  unit_tests/sources/file_based/config/test_abstract_file_based_spec.py,sha256=_9Gr1r0dR-dpqQlciG8VuS6ziuCYBjpPvGEiYvS7s7w,1169
382
- unit_tests/sources/file_based/config/test_csv_format.py,sha256=VYL-9Ec8hW_yO2Pj9F8pDfITcgEAFtSublYda7ut7QE,1132
382
+ unit_tests/sources/file_based/config/test_csv_format.py,sha256=zFgnyJnCQeqsqHH31ZerVeC_km32wU4Sbe-OKoR7wNY,1282
383
383
  unit_tests/sources/file_based/config/test_file_based_stream_config.py,sha256=aDVLvD5ngKJiLMyAO5tSJFCc026tVlqTUGGASnTeKBI,3320
384
384
  unit_tests/sources/file_based/discovery_policy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
385
385
  unit_tests/sources/file_based/discovery_policy/test_default_discovery_policy.py,sha256=RTbPxseKWNLzASeOSxxX72APJoIFm8VpQM9Ok7NE5C0,1132
@@ -387,15 +387,15 @@ unit_tests/sources/file_based/file_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
387
387
  unit_tests/sources/file_based/file_types/test_avro_parser.py,sha256=LCoGa0fvOberrnDu7-Ox_gVNHj_6ERLoWionz0sD0eU,11177
388
388
  unit_tests/sources/file_based/file_types/test_csv_parser.py,sha256=qgTT67wVgbhcvwuxbzr2UykRGIhsOYCTYdEcvgI4q_s,22615
389
389
  unit_tests/sources/file_based/file_types/test_jsonl_parser.py,sha256=foTf9U9LyAS8OR0BonwNgFWPqTrmzFV2lpPUfRMrioE,6134
390
- unit_tests/sources/file_based/file_types/test_parquet_parser.py,sha256=J66wfbAaflSe5y3ixCZ4tLPEQdU62eYj-pNXycCtK0U,14159
390
+ unit_tests/sources/file_based/file_types/test_parquet_parser.py,sha256=HXNpISvdV0ePYj59c_EzczOj-ZqPWh7sOSEEaKKIEk8,18163
391
391
  unit_tests/sources/file_based/file_types/test_unstructured_parser.py,sha256=wJ9J9SbE6gq5ZEnGrDmtKNIimn9xwma06vKsIYa7SDc,23689
392
392
  unit_tests/sources/file_based/scenarios/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
393
393
  unit_tests/sources/file_based/scenarios/avro_scenarios.py,sha256=oeQUmCV7d2aTShreYc-PvVb4cWqLSsVwHfg-lcKjzPs,30554
394
394
  unit_tests/sources/file_based/scenarios/check_scenarios.py,sha256=0xkt21ASTnTAMP0RYJEsF3yMGsNN7wWOoG_tmzL9PYw,6750
395
- unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py,sha256=Mhu58OL3uqZXymr3_lflL7pjUPlopf4C4iCybXCnYwU,104328
395
+ unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py,sha256=EnVhPLSmUmB2lRc2ugb-HF7UkLFulj2EAHs4enAK5dI,102362
396
396
  unit_tests/sources/file_based/scenarios/csv_scenarios.py,sha256=2tyWtFOtbxPh24qAhKMZcVsoSsmnFT3k6MBGzRmx3lU,121727
397
397
  unit_tests/sources/file_based/scenarios/file_based_source_builder.py,sha256=3gAFkguYH87v_WpV0lUttTKu7LG8a-viokDW232ecUw,4123
398
- unit_tests/sources/file_based/scenarios/incremental_scenarios.py,sha256=eVU56mWt7X-JD1FSykE9DAc7ZETuuqaZxZofDr7Puh4,68691
398
+ unit_tests/sources/file_based/scenarios/incremental_scenarios.py,sha256=7ZYe0tsoJ85rNT-s4Z9toXRp2BKmA1pxpPTCyTnNd_8,67340
399
399
  unit_tests/sources/file_based/scenarios/jsonl_scenarios.py,sha256=quo_o8ofuv5LQ2eni6_HudbNq7IgAFQ5uzf_QTElLuY,31719
400
400
  unit_tests/sources/file_based/scenarios/parquet_scenarios.py,sha256=0DZbrb2wbaGSQ3OjD8gCH673dPqtVcLCR_LVkA_qVpA,26658
401
401
  unit_tests/sources/file_based/scenarios/scenario_builder.py,sha256=ynywaMWNvPnJ8Mg2h3vYZPLfaOzHcSFYj7e8bmY_0gY,9894
@@ -406,8 +406,8 @@ unit_tests/sources/file_based/stream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
406
406
  unit_tests/sources/file_based/stream/test_default_file_based_cursor.py,sha256=XhtCGvgSBFyeQwgqGciPsIB1HIlWqTcXROwnxrjutHc,13109
407
407
  unit_tests/sources/file_based/stream/test_default_file_based_stream.py,sha256=IuAnysO7s3MXm6JViPSrlfIlpIYcqWpsKokRpABX39c,10075
408
408
  unit_tests/sources/file_based/stream/concurrent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
409
- unit_tests/sources/file_based/stream/concurrent/test_adapters.py,sha256=TYOv9pQmZ4iHfkQMAaTw0Nyi3p6TnrQnCVOjaIzAFYY,15265
410
- unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py,sha256=Gt1TdiZ8aI8mvbk2CZh7Hi2r23_4GpTptdWFSgx_4PY,19866
409
+ unit_tests/sources/file_based/stream/concurrent/test_adapters.py,sha256=ptjPNSLh_2Z1GFN82gkC1lH4Ov5h5UyEr3AO7CO2fqM,14760
410
+ unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py,sha256=MuIE6y7b-7vF5vuwMozOxBDBLxSU_7dMmSwvK4vvm7U,19874
411
411
  unit_tests/sources/fixtures/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
412
412
  unit_tests/sources/fixtures/source_test_fixture.py,sha256=dvpISgio2sOp-U3bXudH_49vY4c68sO_PMs1JZTMaj0,5502
413
413
  unit_tests/sources/message/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -415,10 +415,10 @@ unit_tests/sources/message/test_repository.py,sha256=oiScwg4cAdnYDl7PPN1nZniDGpA
415
415
  unit_tests/sources/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
416
416
  unit_tests/sources/streams/test_availability_strategy.py,sha256=vJrSEk9NwRghu0YsSNoMYHKWzA9UFemwyClpke8Mk2s,2315
417
417
  unit_tests/sources/streams/test_call_rate.py,sha256=5QsokqxIFoR438QTd7p_eb0K-LW6awZXDtQiMTAb_Qo,13069
418
- unit_tests/sources/streams/test_stream_read.py,sha256=xxyYV5jPsAptmI0awPO_VGWMaE-y80XMDCB6u87IPaY,6875
418
+ unit_tests/sources/streams/test_stream_read.py,sha256=MpRVbr_uCnpEiVHGuKQzuOzCYVUPwhBwA-ISr4GxHm0,16571
419
419
  unit_tests/sources/streams/test_streams_core.py,sha256=YOC7XqWFJ13Z4YuO9Nh4AR4AwpJ-s111vqPplFfpxk4,5059
420
420
  unit_tests/sources/streams/concurrent/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
421
- unit_tests/sources/streams/concurrent/test_adapters.py,sha256=Y_c1vKCtGKEzrUSncmpgp0lgFnArmBrIrmLFaOIAxRg,15439
421
+ unit_tests/sources/streams/concurrent/test_adapters.py,sha256=rIGY_V7D7-2TOcNopGxQySIPZsj62n2saijN2kl3oZM,14934
422
422
  unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py,sha256=qsoSin6ILGhhztEWF-WRdO6nvXJ-MfBH5CNpApEyKSc,27026
423
423
  unit_tests/sources/streams/concurrent/test_cursor.py,sha256=9TmJUOHCsX8Acmm7yDvfcpB5WXwPBXP4d5dizRI-msw,5951
424
424
  unit_tests/sources/streams/concurrent/test_datetime_state_converter.py,sha256=BWEKIT3a6B1NYAiXLZ-STgRu2kJ1T3QzEwQpfgsZkHs,14177
@@ -427,9 +427,9 @@ unit_tests/sources/streams/concurrent/test_partition_enqueuer.py,sha256=Vj8-aOZU
427
427
  unit_tests/sources/streams/concurrent/test_partition_reader.py,sha256=bNFEQXqkSb1yBW5Nruar3HuVqx6r5hNXzU2VFtIRZgw,2544
428
428
  unit_tests/sources/streams/concurrent/test_thread_pool_manager.py,sha256=l0rwdDX79MRip0IKTXKGIqEZy2NptMTUTPYYQQU5yjQ,4203
429
429
  unit_tests/sources/streams/concurrent/scenarios/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
430
- unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py,sha256=oyYSiJVsY3VeiJPn9jZXQDEdIyfBpINjI8EDXBsWWtU,9975
430
+ unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py,sha256=pRbArlvAOglahwb_VHNqYOqfbn4DmJ3rtOCw-NyxJ2M,9858
431
431
  unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py,sha256=HKtWlCbx81CdS8hqCs-d43JndiLL6Tp4K0Yf8VdycDg,6239
432
- unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py,sha256=VllbqrCHTrxBe-tn8Tb6R6EnSgblus3L5cy_2fmW1fY,13992
432
+ unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py,sha256=XIXBunoVtRfCvc-cOGbRtO0t6_km0uoKMFrtvymr28Q,13927
433
433
  unit_tests/sources/streams/concurrent/scenarios/test_concurrent_scenarios.py,sha256=Z_4-ClsxBupmN7Pbl8lF9bkSA9wnjLtrgA9WR_8VRi8,3757
434
434
  unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py,sha256=Qa1z48QLKy8xOViyiqpkIEhREF4rZHqJh8FwJ8fzqiQ,13435
435
435
  unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py,sha256=dY9iAX8YlJcQ2nyPePPCjj6VXzUN_wmJ3bGz6wZQzFE,5734
@@ -456,8 +456,8 @@ unit_tests/utils/test_schema_inferrer.py,sha256=Z2jHBZ540wnYkylIdV_2xr75Vtwlxuyg
456
456
  unit_tests/utils/test_secret_utils.py,sha256=CdKK8A2-5XVxbXVtX22FK9dwwMeP5KNqDH6luWRXSNw,5256
457
457
  unit_tests/utils/test_stream_status_utils.py,sha256=Xr8MZ2HWgTVIyMbywDvuYkRaUF4RZLQOT8-JjvcfR24,2970
458
458
  unit_tests/utils/test_traced_exception.py,sha256=bDFP5zMBizFenz6V2WvEZTRCKGB5ijh3DBezjbfoYIs,4198
459
- airbyte_cdk-0.67.0.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
460
- airbyte_cdk-0.67.0.dist-info/METADATA,sha256=GtaFJMEEKf7V8auiHtCHICOALwLMl74JWHxSpxa8N9A,11072
461
- airbyte_cdk-0.67.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
462
- airbyte_cdk-0.67.0.dist-info/top_level.txt,sha256=edvsDKTnE6sD2wfCUaeTfKf5gQIL6CPVMwVL2sWZzqo,51
463
- airbyte_cdk-0.67.0.dist-info/RECORD,,
459
+ airbyte_cdk-0.67.2.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
460
+ airbyte_cdk-0.67.2.dist-info/METADATA,sha256=ZtTIvhUGdmrevYVp8JtOUbobpySWO91ui3_FzJd5Yfc,11074
461
+ airbyte_cdk-0.67.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
462
+ airbyte_cdk-0.67.2.dist-info/top_level.txt,sha256=edvsDKTnE6sD2wfCUaeTfKf5gQIL6CPVMwVL2sWZzqo,51
463
+ airbyte_cdk-0.67.2.dist-info/RECORD,,
@@ -81,13 +81,14 @@ def test_concurrent_source_adapter():
81
81
  def _mock_stream(name: str, data=[], available: bool = True):
82
82
  s = Mock()
83
83
  s.name = name
84
+ s.namespace = None
84
85
  s.as_airbyte_stream.return_value = AirbyteStream(
85
86
  name=name,
86
87
  json_schema={},
87
88
  supported_sync_modes=[SyncMode.full_refresh],
88
89
  )
89
90
  s.check_availability.return_value = (True, None) if available else (False, "not available")
90
- s.read_full_refresh.return_value = iter(data)
91
+ s.read.return_value = iter(data)
91
92
  s.primary_key = None
92
93
  return s
93
94
 
@@ -5,7 +5,7 @@
5
5
  import unittest
6
6
 
7
7
  import pytest
8
- from airbyte_cdk.sources.file_based.config.csv_format import CsvHeaderAutogenerated, CsvHeaderFromCsv, CsvHeaderUserProvided
8
+ from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat, CsvHeaderAutogenerated, CsvHeaderFromCsv, CsvHeaderUserProvided
9
9
  from pydantic import ValidationError
10
10
 
11
11
 
@@ -26,3 +26,8 @@ class CsvHeaderDefinitionTest(unittest.TestCase):
26
26
 
27
27
  def test_given_from_csv_then_csv_has_header_row(self) -> None:
28
28
  assert CsvHeaderFromCsv().has_header_row()
29
+
30
+
31
+ class CsvDelimiterTest(unittest.TestCase):
32
+ def test_tab_delimter(self):
33
+ assert CsvFormat(delimiter=r"\t").delimiter == '\\t'