airbyte-cdk 6.12.0__py3-none-any.whl → 6.12.0rc1__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/declarative_component_schema.yaml +85 -73
- airbyte_cdk/sources/declarative/decoders/__init__.py +2 -1
- airbyte_cdk/sources/declarative/decoders/parsers/__init__.py +7 -0
- airbyte_cdk/sources/declarative/decoders/parsers/parsers.py +49 -0
- airbyte_cdk/sources/declarative/decoders/zipfile_decoder.py +54 -0
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +77 -65
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +24 -32
- airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +3 -20
- airbyte_cdk/sources/streams/http/http_client.py +2 -4
- {airbyte_cdk-6.12.0.dist-info → airbyte_cdk-6.12.0rc1.dist-info}/METADATA +1 -2
- {airbyte_cdk-6.12.0.dist-info → airbyte_cdk-6.12.0rc1.dist-info}/RECORD +14 -13
- airbyte_cdk/sources/declarative/transformations/flatten_fields.py +0 -50
- airbyte_cdk/sources/declarative/transformations/keys_to_snake_transformation.py +0 -68
- {airbyte_cdk-6.12.0.dist-info → airbyte_cdk-6.12.0rc1.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.12.0.dist-info → airbyte_cdk-6.12.0rc1.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.12.0.dist-info → airbyte_cdk-6.12.0rc1.dist-info}/entry_points.txt +0 -0
@@ -1234,8 +1234,6 @@ definitions:
|
|
1234
1234
|
- "$ref": "#/definitions/CustomTransformation"
|
1235
1235
|
- "$ref": "#/definitions/RemoveFields"
|
1236
1236
|
- "$ref": "#/definitions/KeysToLower"
|
1237
|
-
- "$ref": "#/definitions/KeysToSnakeCase"
|
1238
|
-
- "$ref": "#/definitions/FlattenFields"
|
1239
1237
|
state_migrations:
|
1240
1238
|
title: State Migrations
|
1241
1239
|
description: Array of state migrations to be applied on the input state
|
@@ -1768,18 +1766,6 @@ definitions:
|
|
1768
1766
|
- "$ref": "#/definitions/AsyncRetriever"
|
1769
1767
|
- "$ref": "#/definitions/CustomRetriever"
|
1770
1768
|
- "$ref": "#/definitions/SimpleRetriever"
|
1771
|
-
schema_transformations:
|
1772
|
-
title: Schema Transformations
|
1773
|
-
description: A list of transformations to be applied to the schema.
|
1774
|
-
type: array
|
1775
|
-
items:
|
1776
|
-
anyOf:
|
1777
|
-
- "$ref": "#/definitions/AddFields"
|
1778
|
-
- "$ref": "#/definitions/CustomTransformation"
|
1779
|
-
- "$ref": "#/definitions/RemoveFields"
|
1780
|
-
- "$ref": "#/definitions/KeysToLower"
|
1781
|
-
- "$ref": "#/definitions/KeysToSnakeCase"
|
1782
|
-
- "$ref": "#/definitions/FlattenFields"
|
1783
1769
|
schema_type_identifier:
|
1784
1770
|
"$ref": "#/definitions/SchemaTypeIdentifier"
|
1785
1771
|
$parameters:
|
@@ -1852,32 +1838,6 @@ definitions:
|
|
1852
1838
|
$parameters:
|
1853
1839
|
type: object
|
1854
1840
|
additionalProperties: true
|
1855
|
-
KeysToSnakeCase:
|
1856
|
-
title: Key to Snake Case
|
1857
|
-
description: A transformation that renames all keys to snake case.
|
1858
|
-
type: object
|
1859
|
-
required:
|
1860
|
-
- type
|
1861
|
-
properties:
|
1862
|
-
type:
|
1863
|
-
type: string
|
1864
|
-
enum: [KeysToSnakeCase]
|
1865
|
-
$parameters:
|
1866
|
-
type: object
|
1867
|
-
additionalProperties: true
|
1868
|
-
FlattenFields:
|
1869
|
-
title: Flatten Fields
|
1870
|
-
description: A transformation that flatten record to single level format.
|
1871
|
-
type: object
|
1872
|
-
required:
|
1873
|
-
- type
|
1874
|
-
properties:
|
1875
|
-
type:
|
1876
|
-
type: string
|
1877
|
-
enum: [FlattenFields]
|
1878
|
-
$parameters:
|
1879
|
-
type: object
|
1880
|
-
additionalProperties: true
|
1881
1841
|
IterableDecoder:
|
1882
1842
|
title: Iterable Decoder
|
1883
1843
|
description: Use this if the response consists of strings separated by new lines (`\n`). The Decoder will wrap each row into a JSON object with the `record` key.
|
@@ -1937,6 +1897,56 @@ definitions:
|
|
1937
1897
|
$parameters:
|
1938
1898
|
type: object
|
1939
1899
|
additionalProperties: true
|
1900
|
+
ZipfileDecoder:
|
1901
|
+
title: Zipfile Decoder
|
1902
|
+
description: Decoder for response data that is returned as zipfile(s).
|
1903
|
+
type: object
|
1904
|
+
additionalProperties: true
|
1905
|
+
required:
|
1906
|
+
- type
|
1907
|
+
properties:
|
1908
|
+
type:
|
1909
|
+
type: string
|
1910
|
+
enum: [ZipfileDecoder]
|
1911
|
+
parser:
|
1912
|
+
title: Parser
|
1913
|
+
description: Parser to parse the decompressed data from the zipfile(s).
|
1914
|
+
anyOf:
|
1915
|
+
- "$ref": "#/definitions/JsonParser"
|
1916
|
+
- "$ref": "#/definitions/CustomParser"
|
1917
|
+
JsonParser:
|
1918
|
+
title: JsonParser
|
1919
|
+
description: Parser used for parsing str, bytes, or bytearray data and returning data in a dictionary format.
|
1920
|
+
type: object
|
1921
|
+
additionalProperties: true
|
1922
|
+
required:
|
1923
|
+
- type
|
1924
|
+
properties:
|
1925
|
+
type:
|
1926
|
+
type: string
|
1927
|
+
enum: [JsonParser]
|
1928
|
+
CustomParser:
|
1929
|
+
title: Custom Parser
|
1930
|
+
description: Use this to implement custom parser logic.
|
1931
|
+
type: object
|
1932
|
+
additionalProperties: true
|
1933
|
+
required:
|
1934
|
+
- type
|
1935
|
+
- class_name
|
1936
|
+
properties:
|
1937
|
+
type:
|
1938
|
+
type: string
|
1939
|
+
enum: [CustomParser]
|
1940
|
+
class_name:
|
1941
|
+
title: Class Name
|
1942
|
+
description: Fully-qualified name of the class that will be implementing the custom decoding. Has to be a sub class of Parser. The format is `source_<name>.<package>.<class_name>`.
|
1943
|
+
type: string
|
1944
|
+
additionalProperties: true
|
1945
|
+
examples:
|
1946
|
+
- "source_rivendell.components.ElvishParser"
|
1947
|
+
$parameters:
|
1948
|
+
type: object
|
1949
|
+
additionalProperties: true
|
1940
1950
|
ListPartitionRouter:
|
1941
1951
|
title: List Partition Router
|
1942
1952
|
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.
|
@@ -2170,63 +2180,65 @@ definitions:
|
|
2170
2180
|
- extract_output
|
2171
2181
|
properties:
|
2172
2182
|
consent_url:
|
2173
|
-
title: Consent URL
|
2183
|
+
title: DeclarativeOAuth Consent URL
|
2174
2184
|
type: string
|
2175
2185
|
description: |-
|
2176
2186
|
The DeclarativeOAuth Specific string URL string template to initiate the authentication.
|
2177
2187
|
The placeholders are replaced during the processing to provide neccessary values.
|
2178
2188
|
examples:
|
2179
|
-
- https://domain.host.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}
|
2180
|
-
- https://endpoint.host.com/oauth2/authorize?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{scope_key}={urlEncoder:{{scope_key}}}&{state_key}={{state_key}}&subdomain={subdomain}
|
2189
|
+
- consent_url: https://domain.host.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}
|
2190
|
+
- consent_url: https://endpoint.host.com/oauth2/authorize?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{scope_key}={urlEncoder:{{scope_key}}}&{state_key}={{state_key}}&subdomain={subdomain}
|
2181
2191
|
scope:
|
2182
|
-
title:
|
2192
|
+
title: (Optional) DeclarativeOAuth Scope
|
2183
2193
|
type: string
|
2184
2194
|
description: |-
|
2185
2195
|
The DeclarativeOAuth Specific string of the scopes needed to be grant for authenticated user.
|
2186
2196
|
examples:
|
2187
|
-
- user:read user:read_orders workspaces:read
|
2197
|
+
- scope: user:read user:read_orders workspaces:read
|
2188
2198
|
access_token_url:
|
2189
|
-
title: Access Token URL
|
2199
|
+
title: DeclarativeOAuth Access Token URL
|
2190
2200
|
type: string
|
2191
2201
|
description: |-
|
2192
2202
|
The DeclarativeOAuth Specific URL templated string to obtain the `access_token`, `refresh_token` etc.
|
2193
2203
|
The placeholders are replaced during the processing to provide neccessary values.
|
2194
2204
|
examples:
|
2195
|
-
- https://auth.host.com/oauth2/token?{client_id_key}={{client_id_key}}&{client_secret_key}={{client_secret_key}}&{auth_code_key}={{auth_code_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}
|
2205
|
+
- access_token_url: https://auth.host.com/oauth2/token?{client_id_key}={{client_id_key}}&{client_secret_key}={{client_secret_key}}&{auth_code_key}={{auth_code_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}
|
2196
2206
|
access_token_headers:
|
2197
|
-
title: Access Token Headers
|
2207
|
+
title: (Optional) DeclarativeOAuth Access Token Headers
|
2198
2208
|
type: object
|
2199
2209
|
additionalProperties: true
|
2200
2210
|
description: |-
|
2201
2211
|
The DeclarativeOAuth Specific optional headers to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.
|
2202
2212
|
examples:
|
2203
|
-
-
|
2204
|
-
|
2205
|
-
|
2213
|
+
- access_token_headers:
|
2214
|
+
{
|
2215
|
+
"Authorization": "Basic {base64Encoder:{client_id}:{client_secret}}",
|
2216
|
+
}
|
2206
2217
|
access_token_params:
|
2207
|
-
title: Access Token Query Params (Json Encoded)
|
2218
|
+
title: (Optional) DeclarativeOAuth Access Token Query Params (Json Encoded)
|
2208
2219
|
type: object
|
2209
2220
|
additionalProperties: true
|
2210
2221
|
description: |-
|
2211
2222
|
The DeclarativeOAuth Specific optional query parameters to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.
|
2212
2223
|
When this property is provided, the query params will be encoded as `Json` and included in the outgoing API request.
|
2213
2224
|
examples:
|
2214
|
-
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2225
|
+
- access_token_params:
|
2226
|
+
{
|
2227
|
+
"{auth_code_key}": "{{auth_code_key}}",
|
2228
|
+
"{client_id_key}": "{{client_id_key}}",
|
2229
|
+
"{client_secret_key}": "{{client_secret_key}}",
|
2230
|
+
}
|
2219
2231
|
extract_output:
|
2220
|
-
title: Extract Output
|
2232
|
+
title: DeclarativeOAuth Extract Output
|
2221
2233
|
type: array
|
2222
2234
|
items:
|
2223
2235
|
type: string
|
2224
2236
|
description: |-
|
2225
2237
|
The DeclarativeOAuth Specific list of strings to indicate which keys should be extracted and returned back to the input config.
|
2226
2238
|
examples:
|
2227
|
-
- ["access_token", "refresh_token", "other_field"]
|
2239
|
+
- extract_output: ["access_token", "refresh_token", "other_field"]
|
2228
2240
|
state:
|
2229
|
-
title: Configurable State Query Param
|
2241
|
+
title: (Optional) DeclarativeOAuth Configurable State Query Param
|
2230
2242
|
type: object
|
2231
2243
|
additionalProperties: true
|
2232
2244
|
required:
|
@@ -2241,49 +2253,49 @@ definitions:
|
|
2241
2253
|
max:
|
2242
2254
|
type: integer
|
2243
2255
|
examples:
|
2244
|
-
- { "min": 7, "max": 128 }
|
2256
|
+
- state: { "min": 7, "max": 128 }
|
2245
2257
|
client_id_key:
|
2246
|
-
title: Client ID Key Override
|
2258
|
+
title: (Optional) DeclarativeOAuth Client ID Key Override
|
2247
2259
|
type: string
|
2248
2260
|
description: |-
|
2249
2261
|
The DeclarativeOAuth Specific optional override to provide the custom `client_id` key name, if required by data-provider.
|
2250
2262
|
examples:
|
2251
|
-
- "my_custom_client_id_key_name"
|
2263
|
+
- client_id_key: "my_custom_client_id_key_name"
|
2252
2264
|
client_secret_key:
|
2253
|
-
title: Client Secret Key Override
|
2265
|
+
title: (Optional) DeclarativeOAuth Client Secret Key Override
|
2254
2266
|
type: string
|
2255
2267
|
description: |-
|
2256
2268
|
The DeclarativeOAuth Specific optional override to provide the custom `client_secret` key name, if required by data-provider.
|
2257
2269
|
examples:
|
2258
|
-
- "my_custom_client_secret_key_name"
|
2270
|
+
- client_secret_key: "my_custom_client_secret_key_name"
|
2259
2271
|
scope_key:
|
2260
|
-
title:
|
2272
|
+
title: (Optional) DeclarativeOAuth Scope Key Override
|
2261
2273
|
type: string
|
2262
2274
|
description: |-
|
2263
2275
|
The DeclarativeOAuth Specific optional override to provide the custom `scope` key name, if required by data-provider.
|
2264
2276
|
examples:
|
2265
|
-
- "my_custom_scope_key_key_name"
|
2277
|
+
- scope_key: "my_custom_scope_key_key_name"
|
2266
2278
|
state_key:
|
2267
|
-
title: State Key Override
|
2279
|
+
title: (Optional) DeclarativeOAuth State Key Override
|
2268
2280
|
type: string
|
2269
2281
|
description: |-
|
2270
2282
|
The DeclarativeOAuth Specific optional override to provide the custom `state` key name, if required by data-provider.
|
2271
2283
|
examples:
|
2272
|
-
- "my_custom_state_key_key_name"
|
2284
|
+
- state_key: "my_custom_state_key_key_name"
|
2273
2285
|
auth_code_key:
|
2274
|
-
title: Auth Code Key Override
|
2286
|
+
title: (Optional) DeclarativeOAuth Auth Code Key Override
|
2275
2287
|
type: string
|
2276
2288
|
description: |-
|
2277
2289
|
The DeclarativeOAuth Specific optional override to provide the custom `code` key name to something like `auth_code` or `custom_auth_code`, if required by data-provider.
|
2278
2290
|
examples:
|
2279
|
-
- "my_custom_auth_code_key_name"
|
2291
|
+
- auth_code_key: "my_custom_auth_code_key_name"
|
2280
2292
|
redirect_uri_key:
|
2281
|
-
title: Redirect URI Key Override
|
2293
|
+
title: (Optional) DeclarativeOAuth Redirect URI Key Override
|
2282
2294
|
type: string
|
2283
2295
|
description: |-
|
2284
2296
|
The DeclarativeOAuth Specific optional override to provide the custom `redirect_uri` key name to something like `callback_uri`, if required by data-provider.
|
2285
2297
|
examples:
|
2286
|
-
- "my_custom_redirect_uri_key_name"
|
2298
|
+
- redirect_uri_key: "my_custom_redirect_uri_key_name"
|
2287
2299
|
complete_oauth_output_specification:
|
2288
2300
|
title: "OAuth output specification"
|
2289
2301
|
description: |-
|
@@ -7,5 +7,6 @@ from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder, J
|
|
7
7
|
from airbyte_cdk.sources.declarative.decoders.noop_decoder import NoopDecoder
|
8
8
|
from airbyte_cdk.sources.declarative.decoders.pagination_decoder_decorator import PaginationDecoderDecorator
|
9
9
|
from airbyte_cdk.sources.declarative.decoders.xml_decoder import XmlDecoder
|
10
|
+
from airbyte_cdk.sources.declarative.decoders.zipfile_decoder import ZipfileDecoder
|
10
11
|
|
11
|
-
__all__ = ["Decoder", "JsonDecoder", "JsonlDecoder", "IterableDecoder", "GzipJsonDecoder", "NoopDecoder", "PaginationDecoderDecorator", "XmlDecoder"]
|
12
|
+
__all__ = ["Decoder", "JsonDecoder", "JsonlDecoder", "IterableDecoder", "GzipJsonDecoder", "NoopDecoder", "PaginationDecoderDecorator", "XmlDecoder", "ZipfileDecoder"]
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
import json
|
6
|
+
import logging
|
7
|
+
from abc import abstractmethod
|
8
|
+
from dataclasses import InitVar, dataclass
|
9
|
+
from typing import Any, Generator, Mapping, MutableMapping, Union
|
10
|
+
|
11
|
+
logger = logging.getLogger("airbyte")
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class Parser:
|
16
|
+
"""
|
17
|
+
Parser strategy to convert str, bytes, or bytearray data into MutableMapping[str, Any].
|
18
|
+
"""
|
19
|
+
|
20
|
+
@abstractmethod
|
21
|
+
def parse(
|
22
|
+
self, data: Union[str, bytes, bytearray]
|
23
|
+
) -> Generator[MutableMapping[str, Any], None, None]:
|
24
|
+
pass
|
25
|
+
|
26
|
+
|
27
|
+
@dataclass
|
28
|
+
class JsonParser(Parser):
|
29
|
+
"""
|
30
|
+
Parser strategy for converting JSON-structure str, bytes, or bytearray data into MutableMapping[str, Any].
|
31
|
+
"""
|
32
|
+
|
33
|
+
parameters: InitVar[Mapping[str, Any]]
|
34
|
+
|
35
|
+
def parse(
|
36
|
+
self, data: Union[str, bytes, bytearray]
|
37
|
+
) -> Generator[MutableMapping[str, Any], None, None]:
|
38
|
+
try:
|
39
|
+
body_json = json.loads(data)
|
40
|
+
except json.JSONDecodeError:
|
41
|
+
logger.warning(f"Data cannot be parsed into json: {data=}")
|
42
|
+
yield {}
|
43
|
+
|
44
|
+
if not isinstance(body_json, list):
|
45
|
+
body_json = [body_json]
|
46
|
+
if len(body_json) == 0:
|
47
|
+
yield {}
|
48
|
+
else:
|
49
|
+
yield from body_json
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
import gzip
|
6
|
+
import io
|
7
|
+
import logging
|
8
|
+
import zipfile
|
9
|
+
from dataclasses import InitVar, dataclass
|
10
|
+
from typing import Any, Generator, Mapping, MutableMapping, Optional
|
11
|
+
|
12
|
+
import requests
|
13
|
+
|
14
|
+
from airbyte_cdk.sources.declarative.decoders import Decoder
|
15
|
+
from airbyte_cdk.sources.declarative.decoders.parsers import JsonParser, Parser
|
16
|
+
|
17
|
+
logger = logging.getLogger("airbyte")
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class ZipfileDecoder(Decoder):
|
22
|
+
parameters: InitVar[Mapping[str, Any]]
|
23
|
+
parser: Optional[Parser] = None
|
24
|
+
|
25
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
26
|
+
self._parser = (
|
27
|
+
self.parser(parameters=parameters) if self.parser else JsonParser(parameters=parameters)
|
28
|
+
)
|
29
|
+
|
30
|
+
def is_stream_response(self) -> bool:
|
31
|
+
return False
|
32
|
+
|
33
|
+
def decode(
|
34
|
+
self, response: requests.Response
|
35
|
+
) -> Generator[MutableMapping[str, Any], None, None]:
|
36
|
+
try:
|
37
|
+
zip_file = zipfile.ZipFile(io.BytesIO(response.content))
|
38
|
+
except zipfile.BadZipFile as e:
|
39
|
+
logger.exception(e)
|
40
|
+
logger.error(
|
41
|
+
f"Received an invalid zip file in response to URL: {response.request.url}. "
|
42
|
+
f"The size of the response body is: {len(response.content)}"
|
43
|
+
)
|
44
|
+
yield {}
|
45
|
+
|
46
|
+
for gzip_filename in zip_file.namelist():
|
47
|
+
with zip_file.open(gzip_filename) as file:
|
48
|
+
try:
|
49
|
+
for data in gzip.open(file):
|
50
|
+
yield from self._parser.parse(data)
|
51
|
+
except gzip.BadGzipFile as e:
|
52
|
+
logger.exception(e)
|
53
|
+
logger.error(f"Fail to read contents of zipped response: {e}")
|
54
|
+
yield {}
|
@@ -710,16 +710,6 @@ class KeysToLower(BaseModel):
|
|
710
710
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
711
711
|
|
712
712
|
|
713
|
-
class KeysToSnakeCase(BaseModel):
|
714
|
-
type: Literal["KeysToSnakeCase"]
|
715
|
-
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
716
|
-
|
717
|
-
|
718
|
-
class FlattenFields(BaseModel):
|
719
|
-
type: Literal["FlattenFields"]
|
720
|
-
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
721
|
-
|
722
|
-
|
723
713
|
class IterableDecoder(BaseModel):
|
724
714
|
type: Literal["IterableDecoder"]
|
725
715
|
|
@@ -751,6 +741,27 @@ class GzipJsonDecoder(BaseModel):
|
|
751
741
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
752
742
|
|
753
743
|
|
744
|
+
class JsonParser(BaseModel):
|
745
|
+
class Config:
|
746
|
+
extra = Extra.allow
|
747
|
+
|
748
|
+
type: Literal["JsonParser"]
|
749
|
+
|
750
|
+
|
751
|
+
class CustomParser(BaseModel):
|
752
|
+
class Config:
|
753
|
+
extra = Extra.allow
|
754
|
+
|
755
|
+
type: Literal["CustomParser"]
|
756
|
+
class_name: str = Field(
|
757
|
+
...,
|
758
|
+
description="Fully-qualified name of the class that will be implementing the custom decoding. Has to be a sub class of Parser. The format is `source_<name>.<package>.<class_name>`.",
|
759
|
+
examples=["source_rivendell.components.ElvishParser"],
|
760
|
+
title="Class Name",
|
761
|
+
)
|
762
|
+
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
763
|
+
|
764
|
+
|
754
765
|
class MinMaxDatetime(BaseModel):
|
755
766
|
type: Literal["MinMaxDatetime"]
|
756
767
|
datetime: str = Field(
|
@@ -805,90 +816,104 @@ class OauthConnectorInputSpecification(BaseModel):
|
|
805
816
|
...,
|
806
817
|
description="The DeclarativeOAuth Specific string URL string template to initiate the authentication.\nThe placeholders are replaced during the processing to provide neccessary values.",
|
807
818
|
examples=[
|
808
|
-
|
809
|
-
|
819
|
+
{
|
820
|
+
"consent_url": "https://domain.host.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}"
|
821
|
+
},
|
822
|
+
{
|
823
|
+
"consent_url": "https://endpoint.host.com/oauth2/authorize?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{scope_key}={urlEncoder:{{scope_key}}}&{state_key}={{state_key}}&subdomain={subdomain}"
|
824
|
+
},
|
810
825
|
],
|
811
|
-
title="Consent URL",
|
826
|
+
title="DeclarativeOAuth Consent URL",
|
812
827
|
)
|
813
828
|
scope: Optional[str] = Field(
|
814
829
|
None,
|
815
830
|
description="The DeclarativeOAuth Specific string of the scopes needed to be grant for authenticated user.",
|
816
|
-
examples=["user:read user:read_orders workspaces:read"],
|
817
|
-
title="
|
831
|
+
examples=[{"scope": "user:read user:read_orders workspaces:read"}],
|
832
|
+
title="(Optional) DeclarativeOAuth Scope",
|
818
833
|
)
|
819
834
|
access_token_url: str = Field(
|
820
835
|
...,
|
821
836
|
description="The DeclarativeOAuth Specific URL templated string to obtain the `access_token`, `refresh_token` etc.\nThe placeholders are replaced during the processing to provide neccessary values.",
|
822
837
|
examples=[
|
823
|
-
|
838
|
+
{
|
839
|
+
"access_token_url": "https://auth.host.com/oauth2/token?{client_id_key}={{client_id_key}}&{client_secret_key}={{client_secret_key}}&{auth_code_key}={{auth_code_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}"
|
840
|
+
}
|
824
841
|
],
|
825
|
-
title="Access Token URL",
|
842
|
+
title="DeclarativeOAuth Access Token URL",
|
826
843
|
)
|
827
844
|
access_token_headers: Optional[Dict[str, Any]] = Field(
|
828
845
|
None,
|
829
846
|
description="The DeclarativeOAuth Specific optional headers to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.",
|
830
|
-
examples=[
|
831
|
-
|
847
|
+
examples=[
|
848
|
+
{
|
849
|
+
"access_token_headers": {
|
850
|
+
"Authorization": "Basic {base64Encoder:{client_id}:{client_secret}}"
|
851
|
+
}
|
852
|
+
}
|
853
|
+
],
|
854
|
+
title="(Optional) DeclarativeOAuth Access Token Headers",
|
832
855
|
)
|
833
856
|
access_token_params: Optional[Dict[str, Any]] = Field(
|
834
857
|
None,
|
835
858
|
description="The DeclarativeOAuth Specific optional query parameters to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.\nWhen this property is provided, the query params will be encoded as `Json` and included in the outgoing API request.",
|
836
859
|
examples=[
|
837
860
|
{
|
838
|
-
"
|
839
|
-
|
840
|
-
|
861
|
+
"access_token_params": {
|
862
|
+
"{auth_code_key}": "{{auth_code_key}}",
|
863
|
+
"{client_id_key}": "{{client_id_key}}",
|
864
|
+
"{client_secret_key}": "{{client_secret_key}}",
|
865
|
+
}
|
841
866
|
}
|
842
867
|
],
|
843
|
-
title="Access Token Query Params (Json Encoded)",
|
868
|
+
title="(Optional) DeclarativeOAuth Access Token Query Params (Json Encoded)",
|
844
869
|
)
|
845
870
|
extract_output: List[str] = Field(
|
846
871
|
...,
|
847
872
|
description="The DeclarativeOAuth Specific list of strings to indicate which keys should be extracted and returned back to the input config.",
|
848
|
-
examples=[["access_token", "refresh_token", "other_field"]],
|
849
|
-
title="Extract Output",
|
873
|
+
examples=[{"extract_output": ["access_token", "refresh_token", "other_field"]}],
|
874
|
+
title="DeclarativeOAuth Extract Output",
|
850
875
|
)
|
851
876
|
state: Optional[State] = Field(
|
852
877
|
None,
|
853
878
|
description="The DeclarativeOAuth Specific object to provide the criteria of how the `state` query param should be constructed,\nincluding length and complexity.",
|
854
|
-
examples=[{"min": 7, "max": 128}],
|
855
|
-
title="Configurable State Query Param",
|
879
|
+
examples=[{"state": {"min": 7, "max": 128}}],
|
880
|
+
title="(Optional) DeclarativeOAuth Configurable State Query Param",
|
856
881
|
)
|
857
882
|
client_id_key: Optional[str] = Field(
|
858
883
|
None,
|
859
884
|
description="The DeclarativeOAuth Specific optional override to provide the custom `client_id` key name, if required by data-provider.",
|
860
|
-
examples=["my_custom_client_id_key_name"],
|
861
|
-
title="Client ID Key Override",
|
885
|
+
examples=[{"client_id_key": "my_custom_client_id_key_name"}],
|
886
|
+
title="(Optional) DeclarativeOAuth Client ID Key Override",
|
862
887
|
)
|
863
888
|
client_secret_key: Optional[str] = Field(
|
864
889
|
None,
|
865
890
|
description="The DeclarativeOAuth Specific optional override to provide the custom `client_secret` key name, if required by data-provider.",
|
866
|
-
examples=["my_custom_client_secret_key_name"],
|
867
|
-
title="Client Secret Key Override",
|
891
|
+
examples=[{"client_secret_key": "my_custom_client_secret_key_name"}],
|
892
|
+
title="(Optional) DeclarativeOAuth Client Secret Key Override",
|
868
893
|
)
|
869
894
|
scope_key: Optional[str] = Field(
|
870
895
|
None,
|
871
896
|
description="The DeclarativeOAuth Specific optional override to provide the custom `scope` key name, if required by data-provider.",
|
872
|
-
examples=["my_custom_scope_key_key_name"],
|
873
|
-
title="
|
897
|
+
examples=[{"scope_key": "my_custom_scope_key_key_name"}],
|
898
|
+
title="(Optional) DeclarativeOAuth Scope Key Override",
|
874
899
|
)
|
875
900
|
state_key: Optional[str] = Field(
|
876
901
|
None,
|
877
902
|
description="The DeclarativeOAuth Specific optional override to provide the custom `state` key name, if required by data-provider.",
|
878
|
-
examples=["my_custom_state_key_key_name"],
|
879
|
-
title="State Key Override",
|
903
|
+
examples=[{"state_key": "my_custom_state_key_key_name"}],
|
904
|
+
title="(Optional) DeclarativeOAuth State Key Override",
|
880
905
|
)
|
881
906
|
auth_code_key: Optional[str] = Field(
|
882
907
|
None,
|
883
908
|
description="The DeclarativeOAuth Specific optional override to provide the custom `code` key name to something like `auth_code` or `custom_auth_code`, if required by data-provider.",
|
884
|
-
examples=["my_custom_auth_code_key_name"],
|
885
|
-
title="Auth Code Key Override",
|
909
|
+
examples=[{"auth_code_key": "my_custom_auth_code_key_name"}],
|
910
|
+
title="(Optional) DeclarativeOAuth Auth Code Key Override",
|
886
911
|
)
|
887
912
|
redirect_uri_key: Optional[str] = Field(
|
888
913
|
None,
|
889
914
|
description="The DeclarativeOAuth Specific optional override to provide the custom `redirect_uri` key name to something like `callback_uri`, if required by data-provider.",
|
890
|
-
examples=["my_custom_redirect_uri_key_name"],
|
891
|
-
title="Redirect URI Key Override",
|
915
|
+
examples=[{"redirect_uri_key": "my_custom_redirect_uri_key_name"}],
|
916
|
+
title="(Optional) DeclarativeOAuth Redirect URI Key Override",
|
892
917
|
)
|
893
918
|
|
894
919
|
|
@@ -1464,6 +1489,18 @@ class SessionTokenRequestApiKeyAuthenticator(BaseModel):
|
|
1464
1489
|
)
|
1465
1490
|
|
1466
1491
|
|
1492
|
+
class ZipfileDecoder(BaseModel):
|
1493
|
+
class Config:
|
1494
|
+
extra = Extra.allow
|
1495
|
+
|
1496
|
+
type: Literal["ZipfileDecoder"]
|
1497
|
+
parser: Optional[Union[JsonParser, CustomParser]] = Field(
|
1498
|
+
None,
|
1499
|
+
description="Parser to parse the decompressed data from the zipfile(s).",
|
1500
|
+
title="Parser",
|
1501
|
+
)
|
1502
|
+
|
1503
|
+
|
1467
1504
|
class ListPartitionRouter(BaseModel):
|
1468
1505
|
type: Literal["ListPartitionRouter"]
|
1469
1506
|
cursor_field: str = Field(
|
@@ -1664,16 +1701,7 @@ class DeclarativeStream(BaseModel):
|
|
1664
1701
|
title="Schema Loader",
|
1665
1702
|
)
|
1666
1703
|
transformations: Optional[
|
1667
|
-
List[
|
1668
|
-
Union[
|
1669
|
-
AddFields,
|
1670
|
-
CustomTransformation,
|
1671
|
-
RemoveFields,
|
1672
|
-
KeysToLower,
|
1673
|
-
KeysToSnakeCase,
|
1674
|
-
FlattenFields,
|
1675
|
-
]
|
1676
|
-
]
|
1704
|
+
List[Union[AddFields, CustomTransformation, RemoveFields, KeysToLower]]
|
1677
1705
|
] = Field(
|
1678
1706
|
None,
|
1679
1707
|
description="A list of transformations to be applied to each output record.",
|
@@ -1837,22 +1865,6 @@ class DynamicSchemaLoader(BaseModel):
|
|
1837
1865
|
description="Component used to coordinate how records are extracted across stream slices and request pages.",
|
1838
1866
|
title="Retriever",
|
1839
1867
|
)
|
1840
|
-
schema_transformations: Optional[
|
1841
|
-
List[
|
1842
|
-
Union[
|
1843
|
-
AddFields,
|
1844
|
-
CustomTransformation,
|
1845
|
-
RemoveFields,
|
1846
|
-
KeysToLower,
|
1847
|
-
KeysToSnakeCase,
|
1848
|
-
FlattenFields,
|
1849
|
-
]
|
1850
|
-
]
|
1851
|
-
] = Field(
|
1852
|
-
None,
|
1853
|
-
description="A list of transformations to be applied to the schema.",
|
1854
|
-
title="Schema Transformations",
|
1855
|
-
)
|
1856
1868
|
schema_type_identifier: SchemaTypeIdentifier
|
1857
1869
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1858
1870
|
|
@@ -66,7 +66,9 @@ from airbyte_cdk.sources.declarative.decoders import (
|
|
66
66
|
JsonlDecoder,
|
67
67
|
PaginationDecoderDecorator,
|
68
68
|
XmlDecoder,
|
69
|
+
ZipfileDecoder,
|
69
70
|
)
|
71
|
+
from airbyte_cdk.sources.declarative.decoders.parsers import JsonParser
|
70
72
|
from airbyte_cdk.sources.declarative.extractors import (
|
71
73
|
DpathExtractor,
|
72
74
|
RecordFilter,
|
@@ -197,9 +199,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
197
199
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
198
200
|
ExponentialBackoffStrategy as ExponentialBackoffStrategyModel,
|
199
201
|
)
|
200
|
-
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
201
|
-
FlattenFields as FlattenFieldsModel,
|
202
|
-
)
|
203
202
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
204
203
|
GzipJsonDecoder as GzipJsonDecoderModel,
|
205
204
|
)
|
@@ -227,6 +226,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
227
226
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
228
227
|
JsonlDecoder as JsonlDecoderModel,
|
229
228
|
)
|
229
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
230
|
+
JsonParser as JsonParserModel,
|
231
|
+
)
|
230
232
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
231
233
|
JwtAuthenticator as JwtAuthenticatorModel,
|
232
234
|
)
|
@@ -239,9 +241,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
239
241
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
240
242
|
KeysToLower as KeysToLowerModel,
|
241
243
|
)
|
242
|
-
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
243
|
-
KeysToSnakeCase as KeysToSnakeCaseModel,
|
244
|
-
)
|
245
244
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
246
245
|
LegacySessionTokenAuthenticator as LegacySessionTokenAuthenticatorModel,
|
247
246
|
)
|
@@ -322,6 +321,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
322
321
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
323
322
|
XmlDecoder as XmlDecoderModel,
|
324
323
|
)
|
324
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
325
|
+
ZipfileDecoder as ZipfileDecoderModel,
|
326
|
+
)
|
325
327
|
from airbyte_cdk.sources.declarative.partition_routers import (
|
326
328
|
CartesianProductStreamSlicer,
|
327
329
|
ListPartitionRouter,
|
@@ -393,15 +395,9 @@ from airbyte_cdk.sources.declarative.transformations import (
|
|
393
395
|
RemoveFields,
|
394
396
|
)
|
395
397
|
from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition
|
396
|
-
from airbyte_cdk.sources.declarative.transformations.flatten_fields import (
|
397
|
-
FlattenFields,
|
398
|
-
)
|
399
398
|
from airbyte_cdk.sources.declarative.transformations.keys_to_lower_transformation import (
|
400
399
|
KeysToLowerTransformation,
|
401
400
|
)
|
402
|
-
from airbyte_cdk.sources.declarative.transformations.keys_to_snake_transformation import (
|
403
|
-
KeysToSnakeCaseTransformation,
|
404
|
-
)
|
405
401
|
from airbyte_cdk.sources.message import (
|
406
402
|
InMemoryMessageRepository,
|
407
403
|
LogAppenderMessageRepositoryDecorator,
|
@@ -482,10 +478,9 @@ class ModelToComponentFactory:
|
|
482
478
|
InlineSchemaLoaderModel: self.create_inline_schema_loader,
|
483
479
|
JsonDecoderModel: self.create_json_decoder,
|
484
480
|
JsonlDecoderModel: self.create_jsonl_decoder,
|
481
|
+
JsonParserModel: self.create_json_parser,
|
485
482
|
GzipJsonDecoderModel: self.create_gzipjson_decoder,
|
486
483
|
KeysToLowerModel: self.create_keys_to_lower_transformation,
|
487
|
-
KeysToSnakeCaseModel: self.create_keys_to_snake_transformation,
|
488
|
-
FlattenFieldsModel: self.create_flatten_fields,
|
489
484
|
IterableDecoderModel: self.create_iterable_decoder,
|
490
485
|
XmlDecoderModel: self.create_xml_decoder,
|
491
486
|
JsonFileSchemaLoaderModel: self.create_json_file_schema_loader,
|
@@ -519,6 +514,7 @@ class ModelToComponentFactory:
|
|
519
514
|
ConfigComponentsResolverModel: self.create_config_components_resolver,
|
520
515
|
StreamConfigModel: self.create_stream_config,
|
521
516
|
ComponentMappingDefinitionModel: self.create_components_mapping_definition,
|
517
|
+
ZipfileDecoderModel: self.create_zipfile_decoder,
|
522
518
|
}
|
523
519
|
|
524
520
|
# Needed for the case where we need to perform a second parse on the fields of a custom component
|
@@ -601,16 +597,6 @@ class ModelToComponentFactory:
|
|
601
597
|
) -> KeysToLowerTransformation:
|
602
598
|
return KeysToLowerTransformation()
|
603
599
|
|
604
|
-
def create_keys_to_snake_transformation(
|
605
|
-
self, model: KeysToSnakeCaseModel, config: Config, **kwargs: Any
|
606
|
-
) -> KeysToSnakeCaseTransformation:
|
607
|
-
return KeysToSnakeCaseTransformation()
|
608
|
-
|
609
|
-
def create_flatten_fields(
|
610
|
-
self, model: FlattenFieldsModel, config: Config, **kwargs: Any
|
611
|
-
) -> FlattenFields:
|
612
|
-
return FlattenFields()
|
613
|
-
|
614
600
|
@staticmethod
|
615
601
|
def _json_schema_type_name_to_type(value_type: Optional[ValueType]) -> Optional[Type[Any]]:
|
616
602
|
if not value_type:
|
@@ -1662,13 +1648,6 @@ class ModelToComponentFactory:
|
|
1662
1648
|
model.retriever, stream_slicer
|
1663
1649
|
)
|
1664
1650
|
|
1665
|
-
schema_transformations = []
|
1666
|
-
if model.schema_transformations:
|
1667
|
-
for transformation_model in model.schema_transformations:
|
1668
|
-
schema_transformations.append(
|
1669
|
-
self._create_component_from_model(model=transformation_model, config=config)
|
1670
|
-
)
|
1671
|
-
|
1672
1651
|
retriever = self._create_component_from_model(
|
1673
1652
|
model=model.retriever,
|
1674
1653
|
config=config,
|
@@ -1683,7 +1662,6 @@ class ModelToComponentFactory:
|
|
1683
1662
|
return DynamicSchemaLoader(
|
1684
1663
|
retriever=retriever,
|
1685
1664
|
config=config,
|
1686
|
-
schema_transformations=schema_transformations,
|
1687
1665
|
schema_type_identifier=schema_type_identifier,
|
1688
1666
|
parameters=model.parameters or {},
|
1689
1667
|
)
|
@@ -1714,6 +1692,20 @@ class ModelToComponentFactory:
|
|
1714
1692
|
) -> GzipJsonDecoder:
|
1715
1693
|
return GzipJsonDecoder(parameters={}, encoding=model.encoding)
|
1716
1694
|
|
1695
|
+
def create_zipfile_decoder(
|
1696
|
+
self, model: ZipfileDecoderModel, config: Config, **kwargs: Any
|
1697
|
+
) -> ZipfileDecoder:
|
1698
|
+
parser = (
|
1699
|
+
self._create_component_from_model(model=model.parser, config=config)
|
1700
|
+
if model.parser
|
1701
|
+
else None
|
1702
|
+
)
|
1703
|
+
return ZipfileDecoder(parameters={}, parser=parser)
|
1704
|
+
|
1705
|
+
@staticmethod
|
1706
|
+
def create_json_parser(model: JsonParserModel, config: Config, **kwargs: Any) -> JsonParser:
|
1707
|
+
return JsonParser(parameters={})
|
1708
|
+
|
1717
1709
|
@staticmethod
|
1718
1710
|
def create_json_file_schema_loader(
|
1719
1711
|
model: JsonFileSchemaLoaderModel, config: Config, **kwargs: Any
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
|
6
6
|
from copy import deepcopy
|
7
|
-
from dataclasses import InitVar, dataclass
|
7
|
+
from dataclasses import InitVar, dataclass
|
8
8
|
from typing import Any, List, Mapping, MutableMapping, Optional, Union
|
9
9
|
|
10
10
|
import dpath
|
@@ -13,9 +13,8 @@ from typing_extensions import deprecated
|
|
13
13
|
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
14
14
|
from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever
|
15
15
|
from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader
|
16
|
-
from airbyte_cdk.sources.declarative.transformations import RecordTransformation
|
17
16
|
from airbyte_cdk.sources.source import ExperimentalClassWarning
|
18
|
-
from airbyte_cdk.sources.types import Config
|
17
|
+
from airbyte_cdk.sources.types import Config
|
19
18
|
|
20
19
|
AIRBYTE_DATA_TYPES: Mapping[str, Mapping[str, Any]] = {
|
21
20
|
"string": {"type": ["null", "string"]},
|
@@ -104,7 +103,6 @@ class DynamicSchemaLoader(SchemaLoader):
|
|
104
103
|
config: Config
|
105
104
|
parameters: InitVar[Mapping[str, Any]]
|
106
105
|
schema_type_identifier: SchemaTypeIdentifier
|
107
|
-
schema_transformations: List[RecordTransformation] = field(default_factory=lambda: [])
|
108
106
|
|
109
107
|
def get_json_schema(self) -> Mapping[str, Any]:
|
110
108
|
"""
|
@@ -130,27 +128,12 @@ class DynamicSchemaLoader(SchemaLoader):
|
|
130
128
|
)
|
131
129
|
properties[key] = value
|
132
130
|
|
133
|
-
transformed_properties = self._transform(properties, {})
|
134
|
-
|
135
131
|
return {
|
136
132
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
137
133
|
"type": "object",
|
138
|
-
"properties":
|
134
|
+
"properties": properties,
|
139
135
|
}
|
140
136
|
|
141
|
-
def _transform(
|
142
|
-
self,
|
143
|
-
properties: Mapping[str, Any],
|
144
|
-
stream_state: StreamState,
|
145
|
-
stream_slice: Optional[StreamSlice] = None,
|
146
|
-
) -> Mapping[str, Any]:
|
147
|
-
for transformation in self.schema_transformations:
|
148
|
-
transformation.transform(
|
149
|
-
properties, # type: ignore # properties has type Mapping[str, Any], but Dict[str, Any] expected
|
150
|
-
config=self.config,
|
151
|
-
)
|
152
|
-
return properties
|
153
|
-
|
154
137
|
def _get_key(
|
155
138
|
self,
|
156
139
|
raw_schema: MutableMapping[str, Any],
|
@@ -262,7 +262,7 @@ class HttpClient:
|
|
262
262
|
user_backoff_handler = user_defined_backoff_handler(max_tries=max_tries, max_time=max_time)(
|
263
263
|
self._send
|
264
264
|
)
|
265
|
-
rate_limit_backoff_handler = rate_limit_default_backoff_handler(
|
265
|
+
rate_limit_backoff_handler = rate_limit_default_backoff_handler()
|
266
266
|
backoff_handler = http_client_default_backoff_handler(
|
267
267
|
max_tries=max_tries, max_time=max_time
|
268
268
|
)
|
@@ -472,9 +472,7 @@ class HttpClient:
|
|
472
472
|
|
473
473
|
elif retry_endlessly:
|
474
474
|
raise RateLimitBackoffException(
|
475
|
-
request=request,
|
476
|
-
response=(response if response is not None else exc),
|
477
|
-
error_message=error_message,
|
475
|
+
request=request, response=response or exc, error_message=error_message
|
478
476
|
)
|
479
477
|
|
480
478
|
raise DefaultBackoffException(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: airbyte-cdk
|
3
|
-
Version: 6.12.
|
3
|
+
Version: 6.12.0rc1
|
4
4
|
Summary: A framework for writing Airbyte Connectors.
|
5
5
|
Home-page: https://airbyte.com
|
6
6
|
License: MIT
|
@@ -22,7 +22,6 @@ Provides-Extra: sql
|
|
22
22
|
Provides-Extra: vector-db-based
|
23
23
|
Requires-Dist: Jinja2 (>=3.1.2,<3.2.0)
|
24
24
|
Requires-Dist: PyYAML (>=6.0.1,<7.0.0)
|
25
|
-
Requires-Dist: Unidecode (>=1.3,<2.0)
|
26
25
|
Requires-Dist: airbyte-protocol-models-dataclasses (>=0.14,<0.15)
|
27
26
|
Requires-Dist: avro (>=1.11.2,<1.12.0) ; extra == "file-based"
|
28
27
|
Requires-Dist: backoff
|
@@ -66,15 +66,18 @@ airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=PxP4p268
|
|
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=aW6LC_YuqlqqCiRgBKm7ecNsF_0iPi1NF8sDmiq6wsA,130106
|
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
|
-
airbyte_cdk/sources/declarative/decoders/__init__.py,sha256=
|
72
|
+
airbyte_cdk/sources/declarative/decoders/__init__.py,sha256=q4XSJFXbVYgXoal910hrCL6t-EQLBtLUq4gvP1eNW9o,773
|
73
73
|
airbyte_cdk/sources/declarative/decoders/decoder.py,sha256=sl-Gt8lXi7yD2Q-sD8je5QS2PbgrgsYjxRLWsay7DMc,826
|
74
74
|
airbyte_cdk/sources/declarative/decoders/json_decoder.py,sha256=qdbjeR6RffKaah_iWvMsOcDolYuxJY5DaI3b9AMTZXg,3327
|
75
75
|
airbyte_cdk/sources/declarative/decoders/noop_decoder.py,sha256=iZh0yKY_JzgBnJWiubEusf5c0o6Khd-8EWFWT-8EgFo,542
|
76
76
|
airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py,sha256=ZVBZhAOl0I0MymXN5CKTC-kIXG4GuUQAEyn0XpUDuSE,1081
|
77
|
+
airbyte_cdk/sources/declarative/decoders/parsers/__init__.py,sha256=3qvAJF3O2Ie0qK5ANgsEKR136t7HKk53rR_FyO8ihuY,186
|
78
|
+
airbyte_cdk/sources/declarative/decoders/parsers/parsers.py,sha256=Xlz4xmRYAtMFqdvAMwEdTxh-90glKlijMEm6qLOyuAs,1257
|
77
79
|
airbyte_cdk/sources/declarative/decoders/xml_decoder.py,sha256=EU-7t-5vIGRHZ14h-f0GUE4V5-eTM9Flux-A8xgI1Rc,3117
|
80
|
+
airbyte_cdk/sources/declarative/decoders/zipfile_decoder.py,sha256=IPLCgYpab6og6j7BdvBuhn_7c1ZYyg8yu48DPkvA84c,1752
|
78
81
|
airbyte_cdk/sources/declarative/exceptions.py,sha256=kTPUA4I2NV4J6HDz-mKPGMrfuc592akJnOyYx38l_QM,176
|
79
82
|
airbyte_cdk/sources/declarative/extractors/__init__.py,sha256=YFuL4D4RuuB8E1DNSbJNIj0_HApOlyECoJ_s8DuJMeI,611
|
80
83
|
airbyte_cdk/sources/declarative/extractors/dpath_extractor.py,sha256=wR4Ol4MG2lt5UlqXF5EU_k7qa5cN4_-luu3PJ1PlO3A,3131
|
@@ -104,12 +107,12 @@ airbyte_cdk/sources/declarative/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW
|
|
104
107
|
airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py,sha256=iemy3fKLczcU0-Aor7tx5jcT6DRedKMqyK7kCOp01hg,3924
|
105
108
|
airbyte_cdk/sources/declarative/migrations/state_migration.py,sha256=KWPjealMLKSMtajXgkdGgKg7EmTLR-CqqD7UIh0-eDU,794
|
106
109
|
airbyte_cdk/sources/declarative/models/__init__.py,sha256=nUFxNCiKeYRVXuZEKA7GD-lTHxsiKcQ8FitZjKhPIvE,100
|
107
|
-
airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=
|
110
|
+
airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=94efE5chOvaQaBTRx-Hxu2xyN6mDZ7DuFWJUH5fOgWY,91690
|
108
111
|
airbyte_cdk/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
|
109
112
|
airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=Rir9_z3Kcd5Es0-LChrzk-0qubAsiK_RSEnLmK2OXm8,553
|
110
113
|
airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=CXwTfD3wSQq3okcqwigpprbHhSURUokh4GK2OmOyKC8,9132
|
111
114
|
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=
|
115
|
+
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=62HI4jMJE7EUJY8GLuGL33mfBmfP7zVSnoLcdyTlwYw,105328
|
113
116
|
airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=1NjaZoGAIefvWwj6wx-LOKIXXWS-UnBlZFnuR7y6uYA,745
|
114
117
|
airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py,sha256=c5cuVFM6NFkuQqG8Z5IwkBuwDrvXZN1CunUOM_L0ezg,6892
|
115
118
|
airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py,sha256=t7pRdFWfFWJtQQG19c9PVeMODyO2BknRTakpM5U9N-8,4844
|
@@ -162,7 +165,7 @@ airbyte_cdk/sources/declarative/retrievers/retriever.py,sha256=XPLs593Xv8c5cKMc3
|
|
162
165
|
airbyte_cdk/sources/declarative/retrievers/simple_retriever.py,sha256=N4swGw5mfuTXJ2R7AKX18CHzizsr69pXwt5uSHLPi48,24172
|
163
166
|
airbyte_cdk/sources/declarative/schema/__init__.py,sha256=Io9vninzlEjQ2uFmWklxfwNM0cXfljtzOz5zL1OVyT4,701
|
164
167
|
airbyte_cdk/sources/declarative/schema/default_schema_loader.py,sha256=KTACrIE23a83wsm3Rd9Eb4K6-20lrGqYxTHNp9yxsso,1820
|
165
|
-
airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py,sha256=
|
168
|
+
airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py,sha256=tP5DIEMn-k2JshWeXmo53ZEudDAVb4AJ50Z5tfme_ZU,8063
|
166
169
|
airbyte_cdk/sources/declarative/schema/inline_schema_loader.py,sha256=bVETE10hRsatRJq3R3BeyRR0wIoK3gcP1gcpVRQ_P5U,464
|
167
170
|
airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py,sha256=5Wl-fqW-pVf_dxJ4yGHMAFfC4JjKHYJhqFJT1xA57F4,4177
|
168
171
|
airbyte_cdk/sources/declarative/schema/schema_loader.py,sha256=kjt8v0N5wWKA5zyLnrDLxf1PJKdUqvQq2RVnAOAzNSY,379
|
@@ -173,9 +176,7 @@ airbyte_cdk/sources/declarative/stream_slicers/declarative_partition_generator.p
|
|
173
176
|
airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py,sha256=SOkIPBi2Wu7yxIvA15yFzUAB95a3IzA8LPq5DEqHQQc,725
|
174
177
|
airbyte_cdk/sources/declarative/transformations/__init__.py,sha256=CPJ8TlMpiUmvG3624VYu_NfTzxwKcfBjM2Q2wJ7fkSA,919
|
175
178
|
airbyte_cdk/sources/declarative/transformations/add_fields.py,sha256=r4YdAuAk2bQtNWJMztIIy2CC-NglD9NeK1s1TeO9wkw,5027
|
176
|
-
airbyte_cdk/sources/declarative/transformations/flatten_fields.py,sha256=ti9fLVk-EpMeDY7ImduvQq1YGounLYmH9dHzp7MIRxk,1703
|
177
179
|
airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py,sha256=RTs5KX4V3hM7A6QN1WlGF21YccTIyNH6qQI9IMb__hw,670
|
178
|
-
airbyte_cdk/sources/declarative/transformations/keys_to_snake_transformation.py,sha256=43zwe6_F5ba5C4eY0RgXxPz7ndPKZfXGChHepFn-2lk,2263
|
179
180
|
airbyte_cdk/sources/declarative/transformations/remove_fields.py,sha256=EwUP0SZ2p4GRJ6Q8CUzlz9dcUeEidEFDlI2IBye2tlc,2745
|
180
181
|
airbyte_cdk/sources/declarative/transformations/transformation.py,sha256=4sXtx9cNY2EHUPq-xHvDs8GQEBUy3Eo6TkRLKHPXx68,1161
|
181
182
|
airbyte_cdk/sources/declarative/types.py,sha256=yqx0xlZv_76tkC7fqJKefmvl4GJJ8mXbeddwVV8XRJU,778
|
@@ -280,7 +281,7 @@ airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py,sha
|
|
280
281
|
airbyte_cdk/sources/streams/http/error_handlers/response_models.py,sha256=xGIVELBFY0TmH9aUq1ikoqJz8oHLr6di2JLvKWVEO-s,2236
|
281
282
|
airbyte_cdk/sources/streams/http/exceptions.py,sha256=njC7MlMJoFYcSGz4mIp6-bqLFTr6vC8ej25X0oSeyjE,1824
|
282
283
|
airbyte_cdk/sources/streams/http/http.py,sha256=JAMpiTdS9HFNOlwayWNvQdxoqs2rpW9wdYlhFHv_1Q4,28496
|
283
|
-
airbyte_cdk/sources/streams/http/http_client.py,sha256=
|
284
|
+
airbyte_cdk/sources/streams/http/http_client.py,sha256=dyNrbcahEnDfGTrhqkr1XdfPiuVVRlKOdj-TJ5WRVrk,22923
|
284
285
|
airbyte_cdk/sources/streams/http/rate_limiting.py,sha256=IwdjrHKUnU97XO4qONgYRv4YYW51xQ8SJm4WLafXDB8,6351
|
285
286
|
airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py,sha256=RN0D3nOX1xLgwEwKWu6pkGy3XqBFzKSNZ8Lf6umU2eY,413
|
286
287
|
airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256=nxI94yJ3bGfpDO8RR3QvOJ-PSW0n9CElSAkgl5ae80Y,10321
|
@@ -338,8 +339,8 @@ airbyte_cdk/utils/slice_hasher.py,sha256=-pHexlNYoWYPnXNH-M7HEbjmeJe9Zk7SJijdQ7d
|
|
338
339
|
airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
|
339
340
|
airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
|
340
341
|
airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
|
341
|
-
airbyte_cdk-6.12.
|
342
|
-
airbyte_cdk-6.12.
|
343
|
-
airbyte_cdk-6.12.
|
344
|
-
airbyte_cdk-6.12.
|
345
|
-
airbyte_cdk-6.12.
|
342
|
+
airbyte_cdk-6.12.0rc1.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
|
343
|
+
airbyte_cdk-6.12.0rc1.dist-info/METADATA,sha256=Dmtuhf6DiAt2U3kmIQjlVuruZToq8QNPhsqtZvUePAE,5953
|
344
|
+
airbyte_cdk-6.12.0rc1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
345
|
+
airbyte_cdk-6.12.0rc1.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
|
346
|
+
airbyte_cdk-6.12.0rc1.dist-info/RECORD,,
|
@@ -1,50 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
from dataclasses import dataclass
|
6
|
-
from typing import Any, Dict, Optional
|
7
|
-
|
8
|
-
from airbyte_cdk.sources.declarative.transformations import RecordTransformation
|
9
|
-
from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
|
10
|
-
|
11
|
-
|
12
|
-
@dataclass
|
13
|
-
class FlattenFields(RecordTransformation):
|
14
|
-
def transform(
|
15
|
-
self,
|
16
|
-
record: Dict[str, Any],
|
17
|
-
config: Optional[Config] = None,
|
18
|
-
stream_state: Optional[StreamState] = None,
|
19
|
-
stream_slice: Optional[StreamSlice] = None,
|
20
|
-
) -> None:
|
21
|
-
transformed_record = self.flatten_record(record)
|
22
|
-
record.clear()
|
23
|
-
record.update(transformed_record)
|
24
|
-
|
25
|
-
def flatten_record(self, record: Dict[str, Any]) -> Dict[str, Any]:
|
26
|
-
stack = [(record, "_")]
|
27
|
-
transformed_record: Dict[str, Any] = {}
|
28
|
-
force_with_parent_name = False
|
29
|
-
|
30
|
-
while stack:
|
31
|
-
current_record, parent_key = stack.pop()
|
32
|
-
|
33
|
-
if isinstance(current_record, dict):
|
34
|
-
for current_key, value in current_record.items():
|
35
|
-
new_key = (
|
36
|
-
f"{parent_key}.{current_key}"
|
37
|
-
if (current_key in transformed_record or force_with_parent_name)
|
38
|
-
else current_key
|
39
|
-
)
|
40
|
-
stack.append((value, new_key))
|
41
|
-
|
42
|
-
elif isinstance(current_record, list):
|
43
|
-
for i, item in enumerate(current_record):
|
44
|
-
force_with_parent_name = True
|
45
|
-
stack.append((item, f"{parent_key}.{i}"))
|
46
|
-
|
47
|
-
else:
|
48
|
-
transformed_record[parent_key] = current_record
|
49
|
-
|
50
|
-
return transformed_record
|
@@ -1,68 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
import re
|
6
|
-
from dataclasses import dataclass
|
7
|
-
from typing import Any, Dict, List, Optional
|
8
|
-
|
9
|
-
import unidecode
|
10
|
-
|
11
|
-
from airbyte_cdk.sources.declarative.transformations import RecordTransformation
|
12
|
-
from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
|
13
|
-
|
14
|
-
|
15
|
-
@dataclass
|
16
|
-
class KeysToSnakeCaseTransformation(RecordTransformation):
|
17
|
-
token_pattern: re.Pattern[str] = re.compile(
|
18
|
-
r"[A-Z]+[a-z]*|[a-z]+|\d+|(?P<NoToken>[^a-zA-Z\d]+)"
|
19
|
-
)
|
20
|
-
|
21
|
-
def transform(
|
22
|
-
self,
|
23
|
-
record: Dict[str, Any],
|
24
|
-
config: Optional[Config] = None,
|
25
|
-
stream_state: Optional[StreamState] = None,
|
26
|
-
stream_slice: Optional[StreamSlice] = None,
|
27
|
-
) -> None:
|
28
|
-
transformed_record = self._transform_record(record)
|
29
|
-
record.clear()
|
30
|
-
record.update(transformed_record)
|
31
|
-
|
32
|
-
def _transform_record(self, record: Dict[str, Any]) -> Dict[str, Any]:
|
33
|
-
transformed_record = {}
|
34
|
-
for key, value in record.items():
|
35
|
-
transformed_key = self.process_key(key)
|
36
|
-
transformed_value = value
|
37
|
-
|
38
|
-
if isinstance(value, dict):
|
39
|
-
transformed_value = self._transform_record(value)
|
40
|
-
|
41
|
-
transformed_record[transformed_key] = transformed_value
|
42
|
-
return transformed_record
|
43
|
-
|
44
|
-
def process_key(self, key: str) -> str:
|
45
|
-
key = self.normalize_key(key)
|
46
|
-
tokens = self.tokenize_key(key)
|
47
|
-
tokens = self.filter_tokens(tokens)
|
48
|
-
return self.tokens_to_snake_case(tokens)
|
49
|
-
|
50
|
-
def normalize_key(self, key: str) -> str:
|
51
|
-
return unidecode.unidecode(key)
|
52
|
-
|
53
|
-
def tokenize_key(self, key: str) -> List[str]:
|
54
|
-
tokens = []
|
55
|
-
for match in self.token_pattern.finditer(key):
|
56
|
-
token = match.group(0) if match.group("NoToken") is None else ""
|
57
|
-
tokens.append(token)
|
58
|
-
return tokens
|
59
|
-
|
60
|
-
def filter_tokens(self, tokens: List[str]) -> List[str]:
|
61
|
-
if len(tokens) >= 3:
|
62
|
-
tokens = tokens[:1] + [t for t in tokens[1:-1] if t] + tokens[-1:]
|
63
|
-
if tokens and tokens[0].isdigit():
|
64
|
-
tokens.insert(0, "")
|
65
|
-
return tokens
|
66
|
-
|
67
|
-
def tokens_to_snake_case(self, tokens: List[str]) -> str:
|
68
|
-
return "_".join(token.lower() for token in tokens)
|
File without changes
|
File without changes
|
File without changes
|