airbyte-cdk 6.28.0__py3-none-any.whl → 6.28.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.
Potentially problematic release.
This version of airbyte-cdk might be problematic. Click here for more details.
- airbyte_cdk/sources/declarative/incremental/concurrent_partition_cursor.py +33 -4
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +17 -0
- {airbyte_cdk-6.28.0.dist-info → airbyte_cdk-6.28.0.dev0.dist-info}/METADATA +1 -1
- {airbyte_cdk-6.28.0.dist-info → airbyte_cdk-6.28.0.dev0.dist-info}/RECORD +8 -8
- {airbyte_cdk-6.28.0.dist-info → airbyte_cdk-6.28.0.dev0.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.28.0.dist-info → airbyte_cdk-6.28.0.dev0.dist-info}/LICENSE_SHORT +0 -0
- {airbyte_cdk-6.28.0.dist-info → airbyte_cdk-6.28.0.dev0.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.28.0.dist-info → airbyte_cdk-6.28.0.dev0.dist-info}/entry_points.txt +0 -0
| @@ -22,6 +22,9 @@ from airbyte_cdk.sources.streams.checkpoint.per_partition_key_serializer import | |
| 22 22 | 
             
            )
         | 
| 23 23 | 
             
            from airbyte_cdk.sources.streams.concurrent.cursor import ConcurrentCursor, Cursor, CursorField
         | 
| 24 24 | 
             
            from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition
         | 
| 25 | 
            +
            from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import (
         | 
| 26 | 
            +
                AbstractStreamStateConverter,
         | 
| 27 | 
            +
            )
         | 
| 25 28 | 
             
            from airbyte_cdk.sources.types import Record, StreamSlice, StreamState
         | 
| 26 29 |  | 
| 27 30 | 
             
            logger = logging.getLogger("airbyte")
         | 
| @@ -72,6 +75,7 @@ class ConcurrentPerPartitionCursor(Cursor): | |
| 72 75 | 
             
                    stream_state: Any,
         | 
| 73 76 | 
             
                    message_repository: MessageRepository,
         | 
| 74 77 | 
             
                    connector_state_manager: ConnectorStateManager,
         | 
| 78 | 
            +
                    connector_state_converter: AbstractStreamStateConverter,
         | 
| 75 79 | 
             
                    cursor_field: CursorField,
         | 
| 76 80 | 
             
                ) -> None:
         | 
| 77 81 | 
             
                    self._global_cursor: Optional[StreamState] = {}
         | 
| @@ -79,6 +83,7 @@ class ConcurrentPerPartitionCursor(Cursor): | |
| 79 83 | 
             
                    self._stream_namespace = stream_namespace
         | 
| 80 84 | 
             
                    self._message_repository = message_repository
         | 
| 81 85 | 
             
                    self._connector_state_manager = connector_state_manager
         | 
| 86 | 
            +
                    self._connector_state_converter = connector_state_converter
         | 
| 82 87 | 
             
                    self._cursor_field = cursor_field
         | 
| 83 88 |  | 
| 84 89 | 
             
                    self._cursor_factory = cursor_factory
         | 
| @@ -301,8 +306,7 @@ class ConcurrentPerPartitionCursor(Cursor): | |
| 301 306 | 
             
                    ):
         | 
| 302 307 | 
             
                        # We assume that `stream_state` is in a global format that can be applied to all partitions.
         | 
| 303 308 | 
             
                        # Example: {"global_state_format_key": "global_state_format_value"}
         | 
| 304 | 
            -
                        self. | 
| 305 | 
            -
                        self._new_global_cursor = deepcopy(stream_state)
         | 
| 309 | 
            +
                        self._set_global_state(stream_state)
         | 
| 306 310 |  | 
| 307 311 | 
             
                    else:
         | 
| 308 312 | 
             
                        self._use_global_cursor = stream_state.get("use_global_cursor", False)
         | 
| @@ -319,8 +323,7 @@ class ConcurrentPerPartitionCursor(Cursor): | |
| 319 323 |  | 
| 320 324 | 
             
                        # set default state for missing partitions if it is per partition with fallback to global
         | 
| 321 325 | 
             
                        if self._GLOBAL_STATE_KEY in stream_state:
         | 
| 322 | 
            -
                            self. | 
| 323 | 
            -
                            self._new_global_cursor = deepcopy(stream_state[self._GLOBAL_STATE_KEY])
         | 
| 326 | 
            +
                            self._set_global_state(stream_state[self._GLOBAL_STATE_KEY])
         | 
| 324 327 |  | 
| 325 328 | 
             
                    # Set initial parent state
         | 
| 326 329 | 
             
                    if stream_state.get("parent_state"):
         | 
| @@ -329,6 +332,27 @@ class ConcurrentPerPartitionCursor(Cursor): | |
| 329 332 | 
             
                    # Set parent state for partition routers based on parent streams
         | 
| 330 333 | 
             
                    self._partition_router.set_initial_state(stream_state)
         | 
| 331 334 |  | 
| 335 | 
            +
                def _set_global_state(self, stream_state: Mapping[str, Any]) -> None:
         | 
| 336 | 
            +
                    """
         | 
| 337 | 
            +
                    Initializes the global cursor state from the provided stream state.
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                    If the cursor field key is present in the stream state, its value is parsed,
         | 
| 340 | 
            +
                    formatted, and stored as the global cursor. This ensures consistency in state
         | 
| 341 | 
            +
                    representation across partitions.
         | 
| 342 | 
            +
                    """
         | 
| 343 | 
            +
                    if self.cursor_field.cursor_field_key in stream_state:
         | 
| 344 | 
            +
                        global_state_value = stream_state[self.cursor_field.cursor_field_key]
         | 
| 345 | 
            +
                        final_format_global_state_value = self._connector_state_converter.output_format(
         | 
| 346 | 
            +
                            self._connector_state_converter.parse_value(global_state_value)
         | 
| 347 | 
            +
                        )
         | 
| 348 | 
            +
             | 
| 349 | 
            +
                        fixed_global_state = {
         | 
| 350 | 
            +
                            self.cursor_field.cursor_field_key: final_format_global_state_value
         | 
| 351 | 
            +
                        }
         | 
| 352 | 
            +
             | 
| 353 | 
            +
                        self._global_cursor = deepcopy(fixed_global_state)
         | 
| 354 | 
            +
                        self._new_global_cursor = deepcopy(fixed_global_state)
         | 
| 355 | 
            +
             | 
| 332 356 | 
             
                def observe(self, record: Record) -> None:
         | 
| 333 357 | 
             
                    if not self._use_global_cursor and self.limit_reached():
         | 
| 334 358 | 
             
                        self._use_global_cursor = True
         | 
| @@ -372,5 +396,10 @@ class ConcurrentPerPartitionCursor(Cursor): | |
| 372 396 | 
             
                    cursor = self._cursor_per_partition[partition_key]
         | 
| 373 397 | 
             
                    return cursor
         | 
| 374 398 |  | 
| 399 | 
            +
                def _extract_cursor_value_from_state(self, state: StreamState) -> Any:
         | 
| 400 | 
            +
                    return self._connector_state_converter.parse_value(
         | 
| 401 | 
            +
                        state[self.cursor_field.cursor_field_key]
         | 
| 402 | 
            +
                    )
         | 
| 403 | 
            +
             | 
| 375 404 | 
             
                def limit_reached(self) -> bool:
         | 
| 376 405 | 
             
                    return self._over_limit > self.DEFAULT_MAX_PARTITIONS_NUMBER
         | 
| @@ -1202,6 +1202,22 @@ class ModelToComponentFactory: | |
| 1202 1202 | 
             
                    )
         | 
| 1203 1203 | 
             
                    cursor_field = CursorField(interpolated_cursor_field.eval(config=config))
         | 
| 1204 1204 |  | 
| 1205 | 
            +
                    datetime_format = datetime_based_cursor_model.datetime_format
         | 
| 1206 | 
            +
             | 
| 1207 | 
            +
                    cursor_granularity = (
         | 
| 1208 | 
            +
                        parse_duration(datetime_based_cursor_model.cursor_granularity)
         | 
| 1209 | 
            +
                        if datetime_based_cursor_model.cursor_granularity
         | 
| 1210 | 
            +
                        else None
         | 
| 1211 | 
            +
                    )
         | 
| 1212 | 
            +
             | 
| 1213 | 
            +
                    connector_state_converter: DateTimeStreamStateConverter
         | 
| 1214 | 
            +
                    connector_state_converter = CustomFormatConcurrentStreamStateConverter(
         | 
| 1215 | 
            +
                        datetime_format=datetime_format,
         | 
| 1216 | 
            +
                        input_datetime_formats=datetime_based_cursor_model.cursor_datetime_formats,
         | 
| 1217 | 
            +
                        is_sequential_state=True,  # ConcurrentPerPartitionCursor only works with sequential state
         | 
| 1218 | 
            +
                        cursor_granularity=cursor_granularity,
         | 
| 1219 | 
            +
                    )
         | 
| 1220 | 
            +
             | 
| 1205 1221 | 
             
                    # Create the cursor factory
         | 
| 1206 1222 | 
             
                    cursor_factory = ConcurrentCursorFactory(
         | 
| 1207 1223 | 
             
                        partial(
         | 
| @@ -1225,6 +1241,7 @@ class ModelToComponentFactory: | |
| 1225 1241 | 
             
                        stream_state=stream_state,
         | 
| 1226 1242 | 
             
                        message_repository=self._message_repository,  # type: ignore
         | 
| 1227 1243 | 
             
                        connector_state_manager=state_manager,
         | 
| 1244 | 
            +
                        connector_state_converter=connector_state_converter,
         | 
| 1228 1245 | 
             
                        cursor_field=cursor_field,
         | 
| 1229 1246 | 
             
                    )
         | 
| 1230 1247 |  | 
| @@ -88,7 +88,7 @@ airbyte_cdk/sources/declarative/extractors/record_selector.py,sha256=tjNwcURmlyD | |
| 88 88 | 
             
            airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py,sha256=LhqGDfX06_dDYLKsIVnwQ_nAWCln-v8PV7Wgt_QVeTI,6533
         | 
| 89 89 | 
             
            airbyte_cdk/sources/declarative/extractors/type_transformer.py,sha256=d6Y2Rfg8pMVEEnHllfVksWZdNVOU55yk34O03dP9muY,1626
         | 
| 90 90 | 
             
            airbyte_cdk/sources/declarative/incremental/__init__.py,sha256=U1oZKtBaEC6IACmvziY9Wzg7Z8EgF4ZuR7NwvjlB_Sk,1255
         | 
| 91 | 
            -
            airbyte_cdk/sources/declarative/incremental/concurrent_partition_cursor.py,sha256= | 
| 91 | 
            +
            airbyte_cdk/sources/declarative/incremental/concurrent_partition_cursor.py,sha256=maTJX48fXXbm3qZoX6DzRVujUTeF48eeyC1ii96BXj0,17951
         | 
| 92 92 | 
             
            airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py,sha256=_UzUnSIUsDbRgbFTXgSyZEFb4ws-KdhdQPWO8mFbV7U,22028
         | 
| 93 93 | 
             
            airbyte_cdk/sources/declarative/incremental/declarative_cursor.py,sha256=5Bhw9VRPyIuCaD0wmmq_L3DZsa-rJgtKSEUzSd8YYD0,536
         | 
| 94 94 | 
             
            airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py,sha256=9HO-QbL9akvjq2NP7l498RwLA4iQZlBMQW1tZbt34I8,15943
         | 
| @@ -115,7 +115,7 @@ airbyte_cdk/sources/declarative/parsers/custom_code_compiler.py,sha256=958MMX6_Z | |
| 115 115 | 
             
            airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=Rir9_z3Kcd5Es0-LChrzk-0qubAsiK_RSEnLmK2OXm8,553
         | 
| 116 116 | 
             
            airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=CXwTfD3wSQq3okcqwigpprbHhSURUokh4GK2OmOyKC8,9132
         | 
| 117 117 | 
             
            airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py,sha256=IWUOdF03o-aQn0Occo1BJCxU0Pz-QILk5L67nzw2thw,6803
         | 
| 118 | 
            -
            airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256= | 
| 118 | 
            +
            airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=x3QC5ECRX3gn9DeWwKR8ropQXPGbDN6inQueqpDkK-k,126044
         | 
| 119 119 | 
             
            airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=HJ-Syp3p7RpyR_OK0X_a2kSyISfu3W-PKrRI16iY0a8,957
         | 
| 120 120 | 
             
            airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py,sha256=n82J15S8bjeMZ5uROu--P3hnbQoxkY5v7RPHYx7g7ro,2929
         | 
| 121 121 | 
             
            airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py,sha256=c5cuVFM6NFkuQqG8Z5IwkBuwDrvXZN1CunUOM_L0ezg,6892
         | 
| @@ -351,9 +351,9 @@ airbyte_cdk/utils/slice_hasher.py,sha256=EDxgROHDbfG-QKQb59m7h_7crN1tRiawdf5uU7G | |
| 351 351 | 
             
            airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
         | 
| 352 352 | 
             
            airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
         | 
| 353 353 | 
             
            airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
         | 
| 354 | 
            -
            airbyte_cdk-6.28.0.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
         | 
| 355 | 
            -
            airbyte_cdk-6.28.0.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
         | 
| 356 | 
            -
            airbyte_cdk-6.28.0.dist-info/METADATA,sha256= | 
| 357 | 
            -
            airbyte_cdk-6.28.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
         | 
| 358 | 
            -
            airbyte_cdk-6.28.0.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
         | 
| 359 | 
            -
            airbyte_cdk-6.28.0.dist-info/RECORD,,
         | 
| 354 | 
            +
            airbyte_cdk-6.28.0.dev0.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
         | 
| 355 | 
            +
            airbyte_cdk-6.28.0.dev0.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
         | 
| 356 | 
            +
            airbyte_cdk-6.28.0.dev0.dist-info/METADATA,sha256=lOUTgiqxemt8MFagRsnNAwvwURmnoOV8WbRqSB97Kb8,6015
         | 
| 357 | 
            +
            airbyte_cdk-6.28.0.dev0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
         | 
| 358 | 
            +
            airbyte_cdk-6.28.0.dev0.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
         | 
| 359 | 
            +
            airbyte_cdk-6.28.0.dev0.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |