airbyte-cdk 6.18.0.dev1__py3-none-any.whl → 6.18.0.dev3__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.
@@ -2014,20 +2014,6 @@ definitions:
2014
2014
  $parameters:
2015
2015
  type: object
2016
2016
  additionalProperties: true
2017
- JsonParser:
2018
- title: JsonParser
2019
- description: Parser used for parsing str, bytes, or bytearray data and returning data in a dictionary format.
2020
- type: object
2021
- additionalProperties: true
2022
- required:
2023
- - type
2024
- properties:
2025
- type:
2026
- type: string
2027
- enum: [JsonParser]
2028
- encoding:
2029
- type: string
2030
- default: utf-8
2031
2017
  ListPartitionRouter:
2032
2018
  title: List Partition Router
2033
2019
  description: A Partition router that specifies a list of attributes where each attribute describes a portion of the complete data set for a stream. During a sync, each value is iterated over and can be used as input to outbound API requests.
@@ -2873,6 +2859,7 @@ definitions:
2873
2859
  parser:
2874
2860
  anyOf:
2875
2861
  - "$ref": "#/definitions/GzipParser"
2862
+ - "$ref": "#/definitions/JsonParser"
2876
2863
  - "$ref": "#/definitions/JsonLineParser"
2877
2864
  - "$ref": "#/definitions/CsvParser"
2878
2865
  # PARSERS
@@ -2889,6 +2876,21 @@ definitions:
2889
2876
  anyOf:
2890
2877
  - "$ref": "#/definitions/JsonLineParser"
2891
2878
  - "$ref": "#/definitions/CsvParser"
2879
+ - "$ref": "#/definitions/JsonParser"
2880
+ JsonParser:
2881
+ title: JsonParser
2882
+ description: Parser used for parsing str, bytes, or bytearray data and returning data in a dictionary format.
2883
+ type: object
2884
+ additionalProperties: true
2885
+ required:
2886
+ - type
2887
+ properties:
2888
+ type:
2889
+ type: string
2890
+ enum: [JsonParser]
2891
+ encoding:
2892
+ type: string
2893
+ default: utf-8
2892
2894
  JsonLineParser:
2893
2895
  type: object
2894
2896
  required:
@@ -50,25 +50,40 @@ class JsonParser(Parser):
50
50
  encoding: str = "utf-8"
51
51
 
52
52
  def parse(self, data: BufferedIOBase) -> Generator[MutableMapping[str, Any], None, None]:
53
+ """
54
+ Attempts to deserialize data using orjson library. As an extra layer of safety we fallback on the json library to deserialize the data.
55
+ """
53
56
  raw_data = data.read()
54
- try:
55
- body_json = orjson.loads(raw_data.decode(self.encoding))
56
- except Exception:
57
- try:
58
- body_json = json.loads(raw_data.decode(self.encoding))
59
- except Exception as exc:
60
- raise AirbyteTracedException(
61
- message="Response JSON data failed to be parsed. See logs for more inforation.",
62
- internal_message=f"Response JSON data faild to be parsed: {exc=}, {raw_data=}",
63
- failure_type=FailureType.system_error,
64
- exception=exc,
65
- )
57
+ body_json = self._parse_orjson(raw_data) or self._parse_json(raw_data)
58
+
59
+ if body_json is None:
60
+ raise AirbyteTracedException(
61
+ message="Response JSON data failed to be parsed. See logs for more information.",
62
+ internal_message=f"Response JSON data failed to be parsed.",
63
+ failure_type=FailureType.system_error,
64
+ )
66
65
 
67
66
  if isinstance(body_json, list):
68
67
  yield from body_json
69
68
  else:
70
69
  yield from [body_json]
71
70
 
71
+ def _parse_orjson(self, raw_data: bytes) -> Optional[Any]:
72
+ try:
73
+ return orjson.loads(raw_data.decode(self.encoding))
74
+ except Exception as exc:
75
+ logger.debug(
76
+ f"Failed to parse JSON data using orjson library. Falling back to json library. {exc}"
77
+ )
78
+ return None
79
+
80
+ def _parse_json(self, raw_data: bytes) -> Optional[Any]:
81
+ try:
82
+ return json.loads(raw_data.decode(self.encoding))
83
+ except Exception as exc:
84
+ logger.error(f"Failed to parse JSON data using json library. {exc}")
85
+ return None
86
+
72
87
 
73
88
  @dataclass
74
89
  class JsonLineParser(Parser):
@@ -805,14 +805,6 @@ class GzipJsonDecoder(BaseModel):
805
805
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
806
806
 
807
807
 
808
- class JsonParser(BaseModel):
809
- class Config:
810
- extra = Extra.allow
811
-
812
- type: Literal["JsonParser"]
813
- encoding: Optional[str] = "utf-8"
814
-
815
-
816
808
  class MinMaxDatetime(BaseModel):
817
809
  type: Literal["MinMaxDatetime"]
818
810
  datetime: str = Field(
@@ -1181,6 +1173,14 @@ class LegacySessionTokenAuthenticator(BaseModel):
1181
1173
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1182
1174
 
1183
1175
 
1176
+ class JsonParser(BaseModel):
1177
+ class Config:
1178
+ extra = Extra.allow
1179
+
1180
+ type: Literal["JsonParser"]
1181
+ encoding: Optional[str] = "utf-8"
1182
+
1183
+
1184
1184
  class JsonLineParser(BaseModel):
1185
1185
  type: Literal["JsonLineParser"]
1186
1186
  encoding: Optional[str] = "utf-8"
@@ -1579,7 +1579,7 @@ class RecordSelector(BaseModel):
1579
1579
 
1580
1580
  class GzipParser(BaseModel):
1581
1581
  type: Literal["GzipParser"]
1582
- inner_parser: Union[JsonLineParser, CsvParser]
1582
+ inner_parser: Union[JsonLineParser, CsvParser, JsonParser]
1583
1583
 
1584
1584
 
1585
1585
  class Spec(BaseModel):
@@ -1614,7 +1614,7 @@ class CompositeErrorHandler(BaseModel):
1614
1614
 
1615
1615
  class CompositeRawDecoder(BaseModel):
1616
1616
  type: Literal["CompositeRawDecoder"]
1617
- parser: Union[GzipParser, JsonLineParser, CsvParser]
1617
+ parser: Union[GzipParser, JsonParser, JsonLineParser, CsvParser]
1618
1618
 
1619
1619
 
1620
1620
  class DeclarativeSource1(BaseModel):
@@ -73,6 +73,7 @@ from airbyte_cdk.sources.declarative.decoders.composite_raw_decoder import (
73
73
  GzipParser,
74
74
  JsonLineParser,
75
75
  JsonParser,
76
+ Parser,
76
77
  )
77
78
  from airbyte_cdk.sources.declarative.extractors import (
78
79
  DpathExtractor,
@@ -1037,17 +1038,17 @@ class ModelToComponentFactory:
1037
1038
  self, model: CursorPaginationModel, config: Config, decoder: Decoder, **kwargs: Any
1038
1039
  ) -> CursorPaginationStrategy:
1039
1040
  if isinstance(decoder, PaginationDecoderDecorator):
1040
- if not isinstance(decoder.decoder, (JsonDecoder, XmlDecoder)):
1041
- raise ValueError(
1042
- f"Provided decoder of {type(decoder.decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead."
1043
- )
1041
+ inner_decoder = decoder.decoder
1042
+ else:
1043
+ inner_decoder = decoder
1044
+ decoder = PaginationDecoderDecorator(decoder=decoder)
1045
+
1046
+ if self._is_supported_decoder_for_pagination(inner_decoder):
1044
1047
  decoder_to_use = decoder
1045
1048
  else:
1046
- if not isinstance(decoder, (JsonDecoder, XmlDecoder)):
1047
- raise ValueError(
1048
- f"Provided decoder of {type(decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead."
1049
- )
1050
- decoder_to_use = PaginationDecoderDecorator(decoder=decoder)
1049
+ raise ValueError(
1050
+ self._UNSUPPORTED_DECODER_ERROR.format(decoder_type=type(inner_decoder))
1051
+ )
1051
1052
 
1052
1053
  return CursorPaginationStrategy(
1053
1054
  cursor_value=model.cursor_value,
@@ -1520,11 +1521,10 @@ class ModelToComponentFactory:
1520
1521
  cursor_used_for_stop_condition: Optional[DeclarativeCursor] = None,
1521
1522
  ) -> Union[DefaultPaginator, PaginatorTestReadDecorator]:
1522
1523
  if decoder:
1523
- if not isinstance(decoder, (JsonDecoder, XmlDecoder)):
1524
- raise ValueError(
1525
- f"Provided decoder of {type(decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead."
1526
- )
1527
- decoder_to_use = PaginationDecoderDecorator(decoder=decoder)
1524
+ if self._is_supported_decoder_for_pagination(decoder):
1525
+ decoder_to_use = PaginationDecoderDecorator(decoder=decoder)
1526
+ else:
1527
+ raise ValueError(self._UNSUPPORTED_DECODER_ERROR.format(decoder_type=type(decoder)))
1528
1528
  else:
1529
1529
  decoder_to_use = PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))
1530
1530
  page_size_option = (
@@ -1755,7 +1755,7 @@ class ModelToComponentFactory:
1755
1755
 
1756
1756
  @staticmethod
1757
1757
  def create_json_parser(model: JsonParserModel, config: Config, **kwargs: Any) -> JsonParser:
1758
- encoding = model.encoding or "utf-8"
1758
+ encoding = model.encoding if model.encoding else "utf-8"
1759
1759
  return JsonParser(encoding=encoding)
1760
1760
 
1761
1761
  @staticmethod
@@ -1937,22 +1937,22 @@ class ModelToComponentFactory:
1937
1937
  message_repository=self._message_repository,
1938
1938
  )
1939
1939
 
1940
- @staticmethod
1941
1940
  def create_offset_increment(
1942
- model: OffsetIncrementModel, config: Config, decoder: Decoder, **kwargs: Any
1941
+ self, model: OffsetIncrementModel, config: Config, decoder: Decoder, **kwargs: Any
1943
1942
  ) -> OffsetIncrement:
1944
1943
  if isinstance(decoder, PaginationDecoderDecorator):
1945
- if not isinstance(decoder.decoder, (JsonDecoder, XmlDecoder)):
1946
- raise ValueError(
1947
- f"Provided decoder of {type(decoder.decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead."
1948
- )
1944
+ inner_decoder = decoder.decoder
1945
+ else:
1946
+ inner_decoder = decoder
1947
+ decoder = PaginationDecoderDecorator(decoder=decoder)
1948
+
1949
+ if self._is_supported_decoder_for_pagination(inner_decoder):
1949
1950
  decoder_to_use = decoder
1950
1951
  else:
1951
- if not isinstance(decoder, (JsonDecoder, XmlDecoder)):
1952
- raise ValueError(
1953
- f"Provided decoder of {type(decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead."
1954
- )
1955
- decoder_to_use = PaginationDecoderDecorator(decoder=decoder)
1952
+ raise ValueError(
1953
+ self._UNSUPPORTED_DECODER_ERROR.format(decoder_type=type(inner_decoder))
1954
+ )
1955
+
1956
1956
  return OffsetIncrement(
1957
1957
  page_size=model.page_size,
1958
1958
  config=config,
@@ -2541,3 +2541,25 @@ class ModelToComponentFactory:
2541
2541
  components_mapping=components_mapping,
2542
2542
  parameters=model.parameters or {},
2543
2543
  )
2544
+
2545
+ _UNSUPPORTED_DECODER_ERROR = (
2546
+ "Specified decoder of {decoder_type} is not supported for pagination."
2547
+ "Please set as `JsonDecoder`, `XmlDecoder`, or a `CompositeRawDecoder` with an inner_parser of `JsonParser` or `GzipParser` instead."
2548
+ "If using `GzipParser`, please ensure that the lowest level inner_parser is a `JsonParser`."
2549
+ )
2550
+
2551
+ def _is_supported_decoder_for_pagination(self, decoder: Decoder) -> bool:
2552
+ if isinstance(decoder, (JsonDecoder, XmlDecoder)):
2553
+ return True
2554
+ elif isinstance(decoder, CompositeRawDecoder):
2555
+ return self._is_supported_parser_for_pagination(decoder.parser)
2556
+ else:
2557
+ return False
2558
+
2559
+ def _is_supported_parser_for_pagination(self, parser: Parser) -> bool:
2560
+ if isinstance(parser, JsonParser):
2561
+ return True
2562
+ elif isinstance(parser, GzipParser):
2563
+ return isinstance(parser.inner_parser, JsonParser)
2564
+ else:
2565
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: airbyte-cdk
3
- Version: 6.18.0.dev1
3
+ Version: 6.18.0.dev3
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  License: MIT
6
6
  Keywords: airbyte,connector-development-kit,cdk
@@ -66,11 +66,11 @@ airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=tSTCSmyM
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=QDqDyKmkYDDW3fXA8ImE61p4v_sBNQnqnV-uX_qNHNM,133531
69
+ airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=fCvq1sFwE4h7sP9sjZHoggsw8K3pvOEMvnf_es3fizA,133625
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=edGj4fGxznBk4xzRQyCA1rGfbpqe7z-RE0K3kQQWbgA,858
73
- airbyte_cdk/sources/declarative/decoders/composite_raw_decoder.py,sha256=rSvqdGsVgBT3ZfY_bthjZl_OmxY84iKz8g9GQIWyq8k,3766
73
+ airbyte_cdk/sources/declarative/decoders/composite_raw_decoder.py,sha256=kQfUVMVhChKe5OngwIQrs0F9KGnRUN-CKVFakCU23DQ,4354
74
74
  airbyte_cdk/sources/declarative/decoders/decoder.py,sha256=sl-Gt8lXi7yD2Q-sD8je5QS2PbgrgsYjxRLWsay7DMc,826
75
75
  airbyte_cdk/sources/declarative/decoders/json_decoder.py,sha256=qdbjeR6RffKaah_iWvMsOcDolYuxJY5DaI3b9AMTZXg,3327
76
76
  airbyte_cdk/sources/declarative/decoders/noop_decoder.py,sha256=iZh0yKY_JzgBnJWiubEusf5c0o6Khd-8EWFWT-8EgFo,542
@@ -106,12 +106,12 @@ airbyte_cdk/sources/declarative/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW
106
106
  airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py,sha256=iemy3fKLczcU0-Aor7tx5jcT6DRedKMqyK7kCOp01hg,3924
107
107
  airbyte_cdk/sources/declarative/migrations/state_migration.py,sha256=KWPjealMLKSMtajXgkdGgKg7EmTLR-CqqD7UIh0-eDU,794
108
108
  airbyte_cdk/sources/declarative/models/__init__.py,sha256=nUFxNCiKeYRVXuZEKA7GD-lTHxsiKcQ8FitZjKhPIvE,100
109
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=SpMwCe-6NZTxICSFIXzwlAnAwNLlC8xS12ncEC1NcbA,93536
109
+ airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=_aQM6pF-a4Zk7kQ-_GiVaRi30bpyTQDg4G7KZD83yuI,93560
110
110
  airbyte_cdk/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
111
111
  airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=Rir9_z3Kcd5Es0-LChrzk-0qubAsiK_RSEnLmK2OXm8,553
112
112
  airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=CXwTfD3wSQq3okcqwigpprbHhSURUokh4GK2OmOyKC8,9132
113
113
  airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py,sha256=IWUOdF03o-aQn0Occo1BJCxU0Pz-QILk5L67nzw2thw,6803
114
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=lmSh2Yp-lgRTbbSw3m6UH8L2nTRjt0w3aiISWHRG6IM,109739
114
+ airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=PEtlR6K9zCYDEXfba9QtYeUnC-KOVdaHD-9QSq_UNKY,110269
115
115
  airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=HJ-Syp3p7RpyR_OK0X_a2kSyISfu3W-PKrRI16iY0a8,957
116
116
  airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py,sha256=n82J15S8bjeMZ5uROu--P3hnbQoxkY5v7RPHYx7g7ro,2929
117
117
  airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py,sha256=c5cuVFM6NFkuQqG8Z5IwkBuwDrvXZN1CunUOM_L0ezg,6892
@@ -342,8 +342,8 @@ airbyte_cdk/utils/slice_hasher.py,sha256=-pHexlNYoWYPnXNH-M7HEbjmeJe9Zk7SJijdQ7d
342
342
  airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
343
343
  airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
344
344
  airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
345
- airbyte_cdk-6.18.0.dev1.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
346
- airbyte_cdk-6.18.0.dev1.dist-info/METADATA,sha256=ALXOgvI3pTcF2tNmvbQ9S8fG424n229th_tx1u2uSCo,6005
347
- airbyte_cdk-6.18.0.dev1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
348
- airbyte_cdk-6.18.0.dev1.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
349
- airbyte_cdk-6.18.0.dev1.dist-info/RECORD,,
345
+ airbyte_cdk-6.18.0.dev3.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
346
+ airbyte_cdk-6.18.0.dev3.dist-info/METADATA,sha256=1N26t4q8cvzW-7escwWwzk2BpIgCDOhfvCsLtu4-270,6005
347
+ airbyte_cdk-6.18.0.dev3.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
348
+ airbyte_cdk-6.18.0.dev3.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
349
+ airbyte_cdk-6.18.0.dev3.dist-info/RECORD,,