airbyte-cdk 6.60.0.post14.dev16483785754__py3-none-any.whl → 6.60.0.post16.dev16484674380__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.
@@ -7,87 +7,3 @@ from dataclasses import InitVar, dataclass
7
7
  from typing import Annotated, Any, Dict, List, Mapping, Optional, Union
8
8
 
9
9
  from airbyte_protocol_dataclasses.models import * # noqa: F403 # Allow '*'
10
-
11
- if sys.platform == 'emscripten':
12
- from serpyco.metadata import Alias
13
- else:
14
- from serpyco_rs.metadata import Alias
15
-
16
- # ruff: noqa: F405 # ignore fuzzy import issues with 'import *'
17
-
18
-
19
- @dataclass
20
- class AirbyteStateBlob:
21
- """
22
- A dataclass that dynamically sets attributes based on provided keyword arguments and positional arguments.
23
- Used to "mimic" pydantic Basemodel with ConfigDict(extra='allow') option.
24
-
25
- The `AirbyteStateBlob` class allows for flexible instantiation by accepting any number of keyword arguments
26
- and positional arguments. These are used to dynamically update the instance's attributes. This class is useful
27
- in scenarios where the attributes of an object are not known until runtime and need to be set dynamically.
28
-
29
- Attributes:
30
- kwargs (InitVar[Mapping[str, Any]]): A dictionary of keyword arguments used to set attributes dynamically.
31
-
32
- Methods:
33
- __init__(*args: Any, **kwargs: Any) -> None:
34
- Initializes the `AirbyteStateBlob` by setting attributes from the provided arguments.
35
-
36
- __eq__(other: object) -> bool:
37
- Checks equality between two `AirbyteStateBlob` instances based on their internal dictionaries.
38
- Returns `False` if the other object is not an instance of `AirbyteStateBlob`.
39
- """
40
-
41
- kwargs: InitVar[Mapping[str, Any]]
42
-
43
- def __init__(self, *args: Any, **kwargs: Any) -> None:
44
- # Set any attribute passed in through kwargs
45
- for arg in args:
46
- self.__dict__.update(arg)
47
- for key, value in kwargs.items():
48
- setattr(self, key, value)
49
-
50
- def __eq__(self, other: object) -> bool:
51
- return (
52
- False
53
- if not isinstance(other, AirbyteStateBlob)
54
- else bool(self.__dict__ == other.__dict__)
55
- )
56
-
57
-
58
- # The following dataclasses have been redeclared to include the new version of AirbyteStateBlob
59
- @dataclass
60
- class AirbyteStreamState:
61
- stream_descriptor: StreamDescriptor # type: ignore [name-defined]
62
- stream_state: Optional[AirbyteStateBlob] = None
63
-
64
-
65
- @dataclass
66
- class AirbyteGlobalState:
67
- stream_states: List[AirbyteStreamState]
68
- shared_state: Optional[AirbyteStateBlob] = None
69
-
70
-
71
- @dataclass
72
- class AirbyteStateMessage:
73
- type: Optional[AirbyteStateType] = None # type: ignore [name-defined]
74
- stream: Optional[AirbyteStreamState] = None
75
- global_: Annotated[AirbyteGlobalState | None, Alias("global")] = (
76
- None # "global" is a reserved keyword in python ⇒ Alias is used for (de-)serialization
77
- )
78
- data: Optional[Dict[str, Any]] = None
79
- sourceStats: Optional[AirbyteStateStats] = None # type: ignore [name-defined]
80
- destinationStats: Optional[AirbyteStateStats] = None # type: ignore [name-defined]
81
-
82
-
83
- @dataclass
84
- class AirbyteMessage:
85
- type: Type # type: ignore [name-defined]
86
- log: Optional[AirbyteLogMessage] = None # type: ignore [name-defined]
87
- spec: Optional[ConnectorSpecification] = None # type: ignore [name-defined]
88
- connectionStatus: Optional[AirbyteConnectionStatus] = None # type: ignore [name-defined]
89
- catalog: Optional[AirbyteCatalog] = None # type: ignore [name-defined]
90
- record: Optional[AirbyteRecordMessage] = None # type: ignore [name-defined]
91
- state: Optional[AirbyteStateMessage] = None
92
- trace: Optional[AirbyteTraceMessage] = None # type: ignore [name-defined]
93
- control: Optional[AirbyteControlMessage] = None # type: ignore [name-defined]
@@ -1,6 +1,9 @@
1
1
  # Copyright (c) 2024 Airbyte, Inc., all rights reserved.
2
2
  import sys
3
- from typing import Any, Dict
3
+ from typing import Any, Dict, Type, TypeVar
4
+
5
+ import orjson
6
+ from pydantic import ValidationError
4
7
 
5
8
  from .airbyte_protocol import ( # type: ignore[attr-defined] # all classes are imported to airbyte_protocol via *
6
9
  AirbyteCatalog,
@@ -17,39 +20,98 @@ from .airbyte_protocol import ( # type: ignore[attr-defined] # all classes are
17
20
  USE_RUST_BACKEND = sys.platform != "emscripten"
18
21
  """When run in WASM, use the pure Python backend for serpyco."""
19
22
 
20
- if USE_RUST_BACKEND:
21
- from serpyco_rs import CustomType, Serializer
22
- else:
23
- from serpyco import CustomType, Serializer
24
23
 
24
+ T = TypeVar("T")
25
+
26
+ class CustomSerializer:
27
+ """Custom serializer that mimics serpyco-rs Serializer API"""
28
+
29
+ def __init__(
30
+ self,
31
+ model_class: Type[T],
32
+ omit_none: bool = False,
33
+ custom_type_resolver: Callable | None = None,
34
+ ):
35
+ self.model_class = model_class
36
+ self.omit_none = omit_none
37
+ self.custom_type_resolver = custom_type_resolver
38
+
39
+ def dump(self, obj: T) -> Dict[str, Any]:
40
+ """Convert dataclass to dictionary, omitting None values if configured"""
41
+ if hasattr(obj, "__dict__"):
42
+ result = {}
43
+ for key, value in obj.__dict__.items():
44
+ if self.omit_none and value is None:
45
+ continue
46
+ # Handle custom types like AirbyteStateBlob
47
+ if self.custom_type_resolver and hasattr(value, "__class__"):
48
+ custom_handler = self.custom_type_resolver(value.__class__)
49
+ if custom_handler:
50
+ value = custom_handler.serialize(value)
51
+ # Recursively handle nested objects
52
+ if hasattr(value, "__dict__"):
53
+ value = self._serialize_nested(value)
54
+ elif isinstance(value, list):
55
+ value = [
56
+ self._serialize_nested(item) if hasattr(item, "__dict__") else item
57
+ for item in value
58
+ ]
59
+ result[key] = value
60
+ return result
61
+ return obj.__dict__ if hasattr(obj, "__dict__") else {}
25
62
 
26
- class AirbyteStateBlobType(CustomType[AirbyteStateBlob, Dict[str, Any]]):
27
- def serialize(self, value: AirbyteStateBlob) -> Dict[str, Any]:
28
- # cant use orjson.dumps() directly because private attributes are excluded, e.g. "__ab_full_refresh_sync_complete"
29
- return {k: v for k, v in value.__dict__.items()}
63
+ def load(self, data: Dict[str, Any]) -> T:
64
+ """Convert dictionary to dataclass instance"""
65
+ # Handle custom types
66
+ return self.model_class(**data)
67
+
68
+ def _serialize_nested(self, obj: Any) -> Any:
69
+ """Helper to serialize nested objects"""
70
+ if hasattr(obj, "__dict__"):
71
+ result = {}
72
+ for key, value in obj.__dict__.items():
73
+ if self.omit_none and value is None:
74
+ continue
75
+ result[key] = value
76
+ return result
77
+ return obj
78
+
79
+
80
+ if USE_RUST_BACKEND:
81
+ from serpyco_rs import CustomType, Serializer # type: ignore[import]
30
82
 
31
- def deserialize(self, value: Dict[str, Any]) -> AirbyteStateBlob:
32
- return AirbyteStateBlob(value)
83
+ SERIALIZER = Serializer if USE_RUST_BACKEND else CustomSerializer
33
84
 
34
- def get_json_schema(self) -> Dict[str, Any]:
35
- return {"type": "object"}
85
+ # Making this a no-op for now:
86
+ custom_type_resolver = None
36
87
 
88
+ # No idea why this is here. Commenting out for now.
89
+ # def custom_type_resolver(t: type) -> AirbyteStateBlobType | None:
90
+ # return AirbyteStateBlobType() if t is AirbyteStateBlob else None
91
+ #
92
+ # class AirbyteStateBlobType(CustomType[AirbyteStateBlob, Dict[str, Any]]):
93
+ # def serialize(self, value: AirbyteStateBlob) -> Dict[str, Any]:
94
+ # # cant use orjson.dumps() directly because private attributes are excluded, e.g. "__ab_full_refresh_sync_complete"
95
+ # return {k: v for k, v in value.__dict__.items()}
37
96
 
38
- def custom_type_resolver(t: type) -> CustomType[AirbyteStateBlob, Dict[str, Any]] | None:
39
- return AirbyteStateBlobType() if t is AirbyteStateBlob else None
97
+ # def deserialize(self, value: Dict[str, Any]) -> AirbyteStateBlob:
98
+ # return AirbyteStateBlob(value)
40
99
 
100
+ # def get_json_schema(self) -> Dict[str, Any]:
101
+ # return {"type": "object"}
41
102
 
42
- AirbyteCatalogSerializer = Serializer(AirbyteCatalog, omit_none=True)
43
- AirbyteStreamSerializer = Serializer(AirbyteStream, omit_none=True)
44
- AirbyteStreamStateSerializer = Serializer(
103
+ # Create serializer instances maintaining the same API
104
+ AirbyteCatalogSerializer = SERIALIZER(AirbyteCatalog, omit_none=True)
105
+ AirbyteStreamSerializer = SERIALIZER(AirbyteStream, omit_none=True)
106
+ AirbyteStreamStateSerializer = SERIALIZER(
45
107
  AirbyteStreamState, omit_none=True, custom_type_resolver=custom_type_resolver
46
108
  )
47
- AirbyteStateMessageSerializer = Serializer(
109
+ AirbyteStateMessageSerializer = SERIALIZER(
48
110
  AirbyteStateMessage, omit_none=True, custom_type_resolver=custom_type_resolver
49
111
  )
50
- AirbyteMessageSerializer = Serializer(
112
+ AirbyteMessageSerializer = SERIALIZER(
51
113
  AirbyteMessage, omit_none=True, custom_type_resolver=custom_type_resolver
52
114
  )
53
- ConfiguredAirbyteCatalogSerializer = Serializer(ConfiguredAirbyteCatalog, omit_none=True)
54
- ConfiguredAirbyteStreamSerializer = Serializer(ConfiguredAirbyteStream, omit_none=True)
55
- ConnectorSpecificationSerializer = Serializer(ConnectorSpecification, omit_none=True)
115
+ ConfiguredAirbyteCatalogSerializer = SERIALIZER(ConfiguredAirbyteCatalog, omit_none=True)
116
+ ConfiguredAirbyteStreamSerializer = SERIALIZER(ConfiguredAirbyteStream, omit_none=True)
117
+ ConnectorSpecificationSerializer = SERIALIZER(ConnectorSpecification, omit_none=True)
@@ -30,11 +30,6 @@ from typing import Any, List, Literal, Optional, Union, final, overload
30
30
  import orjson
31
31
  from pydantic import ValidationError as V2ValidationError
32
32
 
33
- if sys.platform == 'emscripten':
34
- from serpyco import SchemaValidationError
35
- else:
36
- from serpyco_rs import SchemaValidationError
37
-
38
33
  from airbyte_cdk.entrypoint import AirbyteEntrypoint
39
34
  from airbyte_cdk.exception_handler import assemble_uncaught_exception
40
35
  from airbyte_cdk.logger import AirbyteLogFormatter
@@ -55,6 +50,13 @@ from airbyte_cdk.models import (
55
50
  from airbyte_cdk.sources import Source
56
51
  from airbyte_cdk.test.models.scenario import ExpectedOutcome
57
52
 
53
+ JsonValidationErrors: tuple[type[Exception], ...] = (orjson.JSONDecodeError,)
54
+ # Conditionally import and create a union type for exception handling
55
+ if sys.platform != "emscripten":
56
+ from serpyco_rs import SchemaValidationError
57
+
58
+ JsonValidationErrors = (orjson.JSONDecodeError, SchemaValidationError)
59
+
58
60
 
59
61
  class AirbyteEntrypointException(Exception):
60
62
  """Exception raised for errors in the AirbyteEntrypoint execution.
@@ -123,7 +125,7 @@ class EntrypointOutput:
123
125
  def _parse_message(message: str) -> AirbyteMessage:
124
126
  try:
125
127
  return AirbyteMessageSerializer.load(orjson.loads(message))
126
- except (orjson.JSONDecodeError, SchemaValidationError):
128
+ except JsonValidationErrors:
127
129
  # The platform assumes that logs that are not of AirbyteMessage format are log messages
128
130
  return AirbyteMessage(
129
131
  type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message=message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 6.60.0.post14.dev16483785754
3
+ Version: 6.60.0.post16.dev16484674380
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://airbyte.com
6
6
  License: MIT
@@ -49,8 +49,8 @@ airbyte_cdk/manifest_migrations/migrations/http_requester_url_base_to_url.py,sha
49
49
  airbyte_cdk/manifest_migrations/migrations/registry.yaml,sha256=F-hdapvl_vZnsI7CQsV00Rb7g7j4Nt2zaM83-Tbwgbg,956
50
50
  airbyte_cdk/manifest_migrations/migrations_registry.py,sha256=zly2fwaOxDukqC7eowzrDlvhA2v71FjW74kDzvRXhSY,2619
51
51
  airbyte_cdk/models/__init__.py,sha256=Et9wJWs5VOWynGbb-3aJRhsdAHAiLkNNLxdwqJAuqkw,2114
52
- airbyte_cdk/models/airbyte_protocol.py,sha256=KpKBePA74K_ay231JBIuQVePCwZa-b8qb0RKRdy-nGk,3707
53
- airbyte_cdk/models/airbyte_protocol_serializers.py,sha256=Rx7UXQOWckJ2BVkcM6vdVc3I4Tx17Ze4g5h75y8oY0Q,2129
52
+ airbyte_cdk/models/airbyte_protocol.py,sha256=R1G1lvnBDRCZDa9_9Mgy5OEeyMXbvGWsDOnwQkImRKA,266
53
+ airbyte_cdk/models/airbyte_protocol_serializers.py,sha256=4lJUZrnoLypM3BFagf4R64XyhRbsMfUffZ_1nHCDNKQ,4503
54
54
  airbyte_cdk/models/connector_metadata.py,sha256=BD6CO8c3mHavxRJAcwP29sHtNNVLVSNFNQLgHOVxrwA,3229
55
55
  airbyte_cdk/models/well_known_types.py,sha256=EquepbisGPuCSrs_D7YVVnMR9-ShhUr21wnFz3COiJs,156
56
56
  airbyte_cdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -380,7 +380,7 @@ airbyte_cdk/sql/shared/sql_processor.py,sha256=jR-hdLZsPf2sNBa_wvWKLvys8ZJ-SQCIi
380
380
  airbyte_cdk/sql/types.py,sha256=XEIhRAo_ASd0kVLBkdLf5bHiRhNple-IJrC9TibcDdY,5880
381
381
  airbyte_cdk/test/__init__.py,sha256=f_XdkOg4_63QT2k3BbKY34209lppwgw-svzfZstQEq4,199
382
382
  airbyte_cdk/test/catalog_builder.py,sha256=-y05Cz1x0Dlk6oE9LSKhCozssV2gYBNtMdV5YYOPOtk,3015
383
- airbyte_cdk/test/entrypoint_wrapper.py,sha256=RLWFMu01DnvAJr3wPcjQbMmb2OLNNKBEBPP0NTBhu44,18090
383
+ airbyte_cdk/test/entrypoint_wrapper.py,sha256=Ha1yhuKRpjlC_hRcHB_3y5dtnhygkl-VIX4_WtpNKnU,18235
384
384
  airbyte_cdk/test/mock_http/__init__.py,sha256=jE5kC6CQ0OXkTqKhciDnNVZHesBFVIA2YvkdFGwva7k,322
385
385
  airbyte_cdk/test/mock_http/matcher.py,sha256=4Qj8UnJKZIs-eodshryce3SN1Ayc8GZpBETmP6hTEyc,1446
386
386
  airbyte_cdk/test/mock_http/mocker.py,sha256=XgsjMtVoeMpRELPyALgrkHFauH9H5irxrz1Kcxh2yFY,8013
@@ -424,9 +424,9 @@ airbyte_cdk/utils/slice_hasher.py,sha256=EDxgROHDbfG-QKQb59m7h_7crN1tRiawdf5uU7G
424
424
  airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
425
425
  airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
426
426
  airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
427
- airbyte_cdk-6.60.0.post14.dev16483785754.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
428
- airbyte_cdk-6.60.0.post14.dev16483785754.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
429
- airbyte_cdk-6.60.0.post14.dev16483785754.dist-info/METADATA,sha256=FNr7dds6D131S9SVeA4PfdW9YpAVlU65oiMqhBUDJ-Y,6512
430
- airbyte_cdk-6.60.0.post14.dev16483785754.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
431
- airbyte_cdk-6.60.0.post14.dev16483785754.dist-info/entry_points.txt,sha256=AKWbEkHfpzzk9nF9tqBUaw1MbvTM4mGtEzmZQm0ZWvM,139
432
- airbyte_cdk-6.60.0.post14.dev16483785754.dist-info/RECORD,,
427
+ airbyte_cdk-6.60.0.post16.dev16484674380.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
428
+ airbyte_cdk-6.60.0.post16.dev16484674380.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
429
+ airbyte_cdk-6.60.0.post16.dev16484674380.dist-info/METADATA,sha256=GDM0HugwhrNDrv8RkxuytvPw9-hRyp2tROFfiSJEvog,6512
430
+ airbyte_cdk-6.60.0.post16.dev16484674380.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
431
+ airbyte_cdk-6.60.0.post16.dev16484674380.dist-info/entry_points.txt,sha256=AKWbEkHfpzzk9nF9tqBUaw1MbvTM4mGtEzmZQm0ZWvM,139
432
+ airbyte_cdk-6.60.0.post16.dev16484674380.dist-info/RECORD,,