airbyte-cdk 6.18.2__py3-none-any.whl → 6.19.1__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/auth/oauth.py +8 -0
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml +24 -1
- airbyte_cdk/sources/declarative/decoders/composite_raw_decoder.py +43 -0
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +21 -2
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +61 -25
- airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +13 -0
- airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +8 -0
- {airbyte_cdk-6.18.2.dist-info → airbyte_cdk-6.19.1.dist-info}/METADATA +1 -1
- {airbyte_cdk-6.18.2.dist-info → airbyte_cdk-6.19.1.dist-info}/RECORD +12 -12
- {airbyte_cdk-6.18.2.dist-info → airbyte_cdk-6.19.1.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.18.2.dist-info → airbyte_cdk-6.19.1.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.18.2.dist-info → airbyte_cdk-6.19.1.dist-info}/entry_points.txt +0 -0
@@ -39,6 +39,7 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
|
|
39
39
|
token_expiry_date_format str: format of the datetime; provide it if expires_in is returned in datetime instead of seconds
|
40
40
|
token_expiry_is_time_of_expiration bool: set True it if expires_in is returned as time of expiration instead of the number seconds until expiration
|
41
41
|
refresh_request_body (Optional[Mapping[str, Any]]): The request body to send in the refresh request
|
42
|
+
refresh_request_headers (Optional[Mapping[str, Any]]): The request headers to send in the refresh request
|
42
43
|
grant_type: The grant_type to request for access_token. If set to refresh_token, the refresh_token parameter has to be provided
|
43
44
|
message_repository (MessageRepository): the message repository used to emit logs on HTTP requests
|
44
45
|
"""
|
@@ -61,6 +62,7 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
|
|
61
62
|
expires_in_name: Union[InterpolatedString, str] = "expires_in"
|
62
63
|
refresh_token_name: Union[InterpolatedString, str] = "refresh_token"
|
63
64
|
refresh_request_body: Optional[Mapping[str, Any]] = None
|
65
|
+
refresh_request_headers: Optional[Mapping[str, Any]] = None
|
64
66
|
grant_type_name: Union[InterpolatedString, str] = "grant_type"
|
65
67
|
grant_type: Union[InterpolatedString, str] = "refresh_token"
|
66
68
|
message_repository: MessageRepository = NoopMessageRepository()
|
@@ -101,6 +103,9 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
|
|
101
103
|
self._refresh_request_body = InterpolatedMapping(
|
102
104
|
self.refresh_request_body or {}, parameters=parameters
|
103
105
|
)
|
106
|
+
self._refresh_request_headers = InterpolatedMapping(
|
107
|
+
self.refresh_request_headers or {}, parameters=parameters
|
108
|
+
)
|
104
109
|
self._token_expiry_date: pendulum.DateTime = (
|
105
110
|
pendulum.parse(
|
106
111
|
InterpolatedString.create(self.token_expiry_date, parameters=parameters).eval(
|
@@ -178,6 +183,9 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
|
|
178
183
|
def get_refresh_request_body(self) -> Mapping[str, Any]:
|
179
184
|
return self._refresh_request_body.eval(self.config)
|
180
185
|
|
186
|
+
def get_refresh_request_headers(self) -> Mapping[str, Any]:
|
187
|
+
return self._refresh_request_headers.eval(self.config)
|
188
|
+
|
181
189
|
def get_token_expiry_date(self) -> pendulum.DateTime:
|
182
190
|
return self._token_expiry_date # type: ignore # _token_expiry_date is a pendulum.DateTime. It is never None despite what mypy thinks
|
183
191
|
|
@@ -678,7 +678,7 @@ definitions:
|
|
678
678
|
properties:
|
679
679
|
type:
|
680
680
|
type: string
|
681
|
-
enum: [
|
681
|
+
enum: [CustomSchemaNormalization]
|
682
682
|
class_name:
|
683
683
|
title: Class Name
|
684
684
|
description: Fully-qualified name of the class that will be implementing the custom normalization. The format is `source_<name>.<package>.<class_name>`.
|
@@ -1139,6 +1139,14 @@ definitions:
|
|
1139
1139
|
- applicationId: "{{ config['application_id'] }}"
|
1140
1140
|
applicationSecret: "{{ config['application_secret'] }}"
|
1141
1141
|
token: "{{ config['token'] }}"
|
1142
|
+
refresh_request_headers:
|
1143
|
+
title: Refresh Request Headers
|
1144
|
+
description: Headers of the request sent to get a new access token.
|
1145
|
+
type: object
|
1146
|
+
additionalProperties: true
|
1147
|
+
examples:
|
1148
|
+
- Authorization: "<AUTH_TOKEN>"
|
1149
|
+
Content-Type: "application/x-www-form-urlencoded"
|
1142
1150
|
scopes:
|
1143
1151
|
title: Scopes
|
1144
1152
|
description: List of scopes that should be granted to the access token.
|
@@ -2886,6 +2894,7 @@ definitions:
|
|
2886
2894
|
parser:
|
2887
2895
|
anyOf:
|
2888
2896
|
- "$ref": "#/definitions/GzipParser"
|
2897
|
+
- "$ref": "#/definitions/JsonParser"
|
2889
2898
|
- "$ref": "#/definitions/JsonLineParser"
|
2890
2899
|
- "$ref": "#/definitions/CsvParser"
|
2891
2900
|
# PARSERS
|
@@ -2902,6 +2911,20 @@ definitions:
|
|
2902
2911
|
anyOf:
|
2903
2912
|
- "$ref": "#/definitions/JsonLineParser"
|
2904
2913
|
- "$ref": "#/definitions/CsvParser"
|
2914
|
+
- "$ref": "#/definitions/JsonParser"
|
2915
|
+
JsonParser:
|
2916
|
+
title: JsonParser
|
2917
|
+
description: Parser used for parsing str, bytes, or bytearray data and returning data in a dictionary format.
|
2918
|
+
type: object
|
2919
|
+
required:
|
2920
|
+
- type
|
2921
|
+
properties:
|
2922
|
+
type:
|
2923
|
+
type: string
|
2924
|
+
enum: [JsonParser]
|
2925
|
+
encoding:
|
2926
|
+
type: string
|
2927
|
+
default: utf-8
|
2905
2928
|
JsonLineParser:
|
2906
2929
|
type: object
|
2907
2930
|
required:
|
@@ -7,9 +7,12 @@ from dataclasses import dataclass
|
|
7
7
|
from io import BufferedIOBase, TextIOWrapper
|
8
8
|
from typing import Any, Generator, MutableMapping, Optional
|
9
9
|
|
10
|
+
import orjson
|
10
11
|
import requests
|
11
12
|
|
13
|
+
from airbyte_cdk.models import FailureType
|
12
14
|
from airbyte_cdk.sources.declarative.decoders.decoder import Decoder
|
15
|
+
from airbyte_cdk.utils import AirbyteTracedException
|
13
16
|
|
14
17
|
logger = logging.getLogger("airbyte")
|
15
18
|
|
@@ -42,6 +45,46 @@ class GzipParser(Parser):
|
|
42
45
|
yield from self.inner_parser.parse(gzipobj)
|
43
46
|
|
44
47
|
|
48
|
+
@dataclass
|
49
|
+
class JsonParser(Parser):
|
50
|
+
encoding: str = "utf-8"
|
51
|
+
|
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
|
+
"""
|
56
|
+
raw_data = data.read()
|
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
|
+
)
|
65
|
+
|
66
|
+
if isinstance(body_json, list):
|
67
|
+
yield from body_json
|
68
|
+
else:
|
69
|
+
yield from [body_json]
|
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
|
+
|
87
|
+
|
45
88
|
@dataclass
|
46
89
|
class JsonLineParser(Parser):
|
47
90
|
encoding: Optional[str] = "utf-8"
|
@@ -571,6 +571,17 @@ class OAuthAuthenticator(BaseModel):
|
|
571
571
|
],
|
572
572
|
title="Refresh Request Body",
|
573
573
|
)
|
574
|
+
refresh_request_headers: Optional[Dict[str, Any]] = Field(
|
575
|
+
None,
|
576
|
+
description="Headers of the request sent to get a new access token.",
|
577
|
+
examples=[
|
578
|
+
{
|
579
|
+
"Authorization": "<AUTH_TOKEN>",
|
580
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
581
|
+
}
|
582
|
+
],
|
583
|
+
title="Refresh Request Headers",
|
584
|
+
)
|
574
585
|
scopes: Optional[List[str]] = Field(
|
575
586
|
None,
|
576
587
|
description="List of scopes that should be granted to the access token.",
|
@@ -1201,6 +1212,14 @@ class LegacySessionTokenAuthenticator(BaseModel):
|
|
1201
1212
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1202
1213
|
|
1203
1214
|
|
1215
|
+
class JsonParser(BaseModel):
|
1216
|
+
class Config:
|
1217
|
+
extra = Extra.allow
|
1218
|
+
|
1219
|
+
type: Literal["JsonParser"]
|
1220
|
+
encoding: Optional[str] = "utf-8"
|
1221
|
+
|
1222
|
+
|
1204
1223
|
class JsonLineParser(BaseModel):
|
1205
1224
|
type: Literal["JsonLineParser"]
|
1206
1225
|
encoding: Optional[str] = "utf-8"
|
@@ -1599,7 +1618,7 @@ class RecordSelector(BaseModel):
|
|
1599
1618
|
|
1600
1619
|
class GzipParser(BaseModel):
|
1601
1620
|
type: Literal["GzipParser"]
|
1602
|
-
inner_parser: Union[JsonLineParser, CsvParser]
|
1621
|
+
inner_parser: Union[JsonLineParser, CsvParser, JsonParser]
|
1603
1622
|
|
1604
1623
|
|
1605
1624
|
class Spec(BaseModel):
|
@@ -1634,7 +1653,7 @@ class CompositeErrorHandler(BaseModel):
|
|
1634
1653
|
|
1635
1654
|
class CompositeRawDecoder(BaseModel):
|
1636
1655
|
type: Literal["CompositeRawDecoder"]
|
1637
|
-
parser: Union[GzipParser, JsonLineParser, CsvParser]
|
1656
|
+
parser: Union[GzipParser, JsonParser, JsonLineParser, CsvParser]
|
1638
1657
|
|
1639
1658
|
|
1640
1659
|
class DeclarativeSource1(BaseModel):
|
@@ -72,6 +72,8 @@ from airbyte_cdk.sources.declarative.decoders.composite_raw_decoder import (
|
|
72
72
|
CsvParser,
|
73
73
|
GzipParser,
|
74
74
|
JsonLineParser,
|
75
|
+
JsonParser,
|
76
|
+
Parser,
|
75
77
|
)
|
76
78
|
from airbyte_cdk.sources.declarative.extractors import (
|
77
79
|
DpathExtractor,
|
@@ -247,6 +249,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
247
249
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
248
250
|
JsonLineParser as JsonLineParserModel,
|
249
251
|
)
|
252
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
253
|
+
JsonParser as JsonParserModel,
|
254
|
+
)
|
250
255
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
251
256
|
JwtAuthenticator as JwtAuthenticatorModel,
|
252
257
|
)
|
@@ -522,6 +527,7 @@ class ModelToComponentFactory:
|
|
522
527
|
JsonDecoderModel: self.create_json_decoder,
|
523
528
|
JsonlDecoderModel: self.create_jsonl_decoder,
|
524
529
|
JsonLineParserModel: self.create_json_line_parser,
|
530
|
+
JsonParserModel: self.create_json_parser,
|
525
531
|
GzipJsonDecoderModel: self.create_gzipjson_decoder,
|
526
532
|
GzipParserModel: self.create_gzip_parser,
|
527
533
|
KeysToLowerModel: self.create_keys_to_lower_transformation,
|
@@ -1032,17 +1038,17 @@ class ModelToComponentFactory:
|
|
1032
1038
|
self, model: CursorPaginationModel, config: Config, decoder: Decoder, **kwargs: Any
|
1033
1039
|
) -> CursorPaginationStrategy:
|
1034
1040
|
if isinstance(decoder, PaginationDecoderDecorator):
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
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):
|
1039
1047
|
decoder_to_use = decoder
|
1040
1048
|
else:
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
)
|
1045
|
-
decoder_to_use = PaginationDecoderDecorator(decoder=decoder)
|
1049
|
+
raise ValueError(
|
1050
|
+
self._UNSUPPORTED_DECODER_ERROR.format(decoder_type=type(inner_decoder))
|
1051
|
+
)
|
1046
1052
|
|
1047
1053
|
return CursorPaginationStrategy(
|
1048
1054
|
cursor_value=model.cursor_value,
|
@@ -1515,11 +1521,10 @@ class ModelToComponentFactory:
|
|
1515
1521
|
cursor_used_for_stop_condition: Optional[DeclarativeCursor] = None,
|
1516
1522
|
) -> Union[DefaultPaginator, PaginatorTestReadDecorator]:
|
1517
1523
|
if decoder:
|
1518
|
-
if
|
1519
|
-
|
1520
|
-
|
1521
|
-
)
|
1522
|
-
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)))
|
1523
1528
|
else:
|
1524
1529
|
decoder_to_use = PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))
|
1525
1530
|
page_size_option = (
|
@@ -1748,6 +1753,11 @@ class ModelToComponentFactory:
|
|
1748
1753
|
def create_json_decoder(model: JsonDecoderModel, config: Config, **kwargs: Any) -> JsonDecoder:
|
1749
1754
|
return JsonDecoder(parameters={})
|
1750
1755
|
|
1756
|
+
@staticmethod
|
1757
|
+
def create_json_parser(model: JsonParserModel, config: Config, **kwargs: Any) -> JsonParser:
|
1758
|
+
encoding = model.encoding if model.encoding else "utf-8"
|
1759
|
+
return JsonParser(encoding=encoding)
|
1760
|
+
|
1751
1761
|
@staticmethod
|
1752
1762
|
def create_jsonl_decoder(
|
1753
1763
|
model: JsonlDecoderModel, config: Config, **kwargs: Any
|
@@ -1909,6 +1919,9 @@ class ModelToComponentFactory:
|
|
1909
1919
|
refresh_request_body=InterpolatedMapping(
|
1910
1920
|
model.refresh_request_body or {}, parameters=model.parameters or {}
|
1911
1921
|
).eval(config),
|
1922
|
+
refresh_request_headers=InterpolatedMapping(
|
1923
|
+
model.refresh_request_headers or {}, parameters=model.parameters or {}
|
1924
|
+
).eval(config),
|
1912
1925
|
scopes=model.scopes,
|
1913
1926
|
token_expiry_date_format=model.token_expiry_date_format,
|
1914
1927
|
message_repository=self._message_repository,
|
@@ -1928,6 +1941,7 @@ class ModelToComponentFactory:
|
|
1928
1941
|
grant_type_name=model.grant_type_name or "grant_type",
|
1929
1942
|
grant_type=model.grant_type or "refresh_token",
|
1930
1943
|
refresh_request_body=model.refresh_request_body,
|
1944
|
+
refresh_request_headers=model.refresh_request_headers,
|
1931
1945
|
refresh_token_name=model.refresh_token_name or "refresh_token",
|
1932
1946
|
refresh_token=model.refresh_token,
|
1933
1947
|
scopes=model.scopes,
|
@@ -1940,22 +1954,22 @@ class ModelToComponentFactory:
|
|
1940
1954
|
message_repository=self._message_repository,
|
1941
1955
|
)
|
1942
1956
|
|
1943
|
-
@staticmethod
|
1944
1957
|
def create_offset_increment(
|
1945
|
-
model: OffsetIncrementModel, config: Config, decoder: Decoder, **kwargs: Any
|
1958
|
+
self, model: OffsetIncrementModel, config: Config, decoder: Decoder, **kwargs: Any
|
1946
1959
|
) -> OffsetIncrement:
|
1947
1960
|
if isinstance(decoder, PaginationDecoderDecorator):
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1961
|
+
inner_decoder = decoder.decoder
|
1962
|
+
else:
|
1963
|
+
inner_decoder = decoder
|
1964
|
+
decoder = PaginationDecoderDecorator(decoder=decoder)
|
1965
|
+
|
1966
|
+
if self._is_supported_decoder_for_pagination(inner_decoder):
|
1952
1967
|
decoder_to_use = decoder
|
1953
1968
|
else:
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
decoder_to_use = PaginationDecoderDecorator(decoder=decoder)
|
1969
|
+
raise ValueError(
|
1970
|
+
self._UNSUPPORTED_DECODER_ERROR.format(decoder_type=type(inner_decoder))
|
1971
|
+
)
|
1972
|
+
|
1959
1973
|
return OffsetIncrement(
|
1960
1974
|
page_size=model.page_size,
|
1961
1975
|
config=config,
|
@@ -2555,3 +2569,25 @@ class ModelToComponentFactory:
|
|
2555
2569
|
components_mapping=components_mapping,
|
2556
2570
|
parameters=model.parameters or {},
|
2557
2571
|
)
|
2572
|
+
|
2573
|
+
_UNSUPPORTED_DECODER_ERROR = (
|
2574
|
+
"Specified decoder of {decoder_type} is not supported for pagination."
|
2575
|
+
"Please set as `JsonDecoder`, `XmlDecoder`, or a `CompositeRawDecoder` with an inner_parser of `JsonParser` or `GzipParser` instead."
|
2576
|
+
"If using `GzipParser`, please ensure that the lowest level inner_parser is a `JsonParser`."
|
2577
|
+
)
|
2578
|
+
|
2579
|
+
def _is_supported_decoder_for_pagination(self, decoder: Decoder) -> bool:
|
2580
|
+
if isinstance(decoder, (JsonDecoder, XmlDecoder)):
|
2581
|
+
return True
|
2582
|
+
elif isinstance(decoder, CompositeRawDecoder):
|
2583
|
+
return self._is_supported_parser_for_pagination(decoder.parser)
|
2584
|
+
else:
|
2585
|
+
return False
|
2586
|
+
|
2587
|
+
def _is_supported_parser_for_pagination(self, parser: Parser) -> bool:
|
2588
|
+
if isinstance(parser, JsonParser):
|
2589
|
+
return True
|
2590
|
+
elif isinstance(parser, GzipParser):
|
2591
|
+
return isinstance(parser.inner_parser, JsonParser)
|
2592
|
+
else:
|
2593
|
+
return False
|
@@ -98,6 +98,14 @@ class AbstractOauth2Authenticator(AuthBase):
|
|
98
98
|
|
99
99
|
return payload
|
100
100
|
|
101
|
+
def build_refresh_request_headers(self) -> Mapping[str, Any] | None:
|
102
|
+
"""
|
103
|
+
Returns the request headers to set on the refresh request
|
104
|
+
|
105
|
+
"""
|
106
|
+
headers = self.get_refresh_request_headers()
|
107
|
+
return headers if headers else None
|
108
|
+
|
101
109
|
def _wrap_refresh_token_exception(
|
102
110
|
self, exception: requests.exceptions.RequestException
|
103
111
|
) -> bool:
|
@@ -128,6 +136,7 @@ class AbstractOauth2Authenticator(AuthBase):
|
|
128
136
|
method="POST",
|
129
137
|
url=self.get_token_refresh_endpoint(), # type: ignore # returns None, if not provided, but str | bytes is expected.
|
130
138
|
data=self.build_refresh_request_body(),
|
139
|
+
headers=self.build_refresh_request_headers(),
|
131
140
|
)
|
132
141
|
if response.ok:
|
133
142
|
response_json = response.json()
|
@@ -254,6 +263,10 @@ class AbstractOauth2Authenticator(AuthBase):
|
|
254
263
|
def get_refresh_request_body(self) -> Mapping[str, Any]:
|
255
264
|
"""Returns the request body to set on the refresh request"""
|
256
265
|
|
266
|
+
@abstractmethod
|
267
|
+
def get_refresh_request_headers(self) -> Mapping[str, Any]:
|
268
|
+
"""Returns the request headers to set on the refresh request"""
|
269
|
+
|
257
270
|
@abstractmethod
|
258
271
|
def get_grant_type(self) -> str:
|
259
272
|
"""Returns grant_type specified for requesting access_token"""
|
@@ -39,6 +39,7 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
|
|
39
39
|
access_token_name: str = "access_token",
|
40
40
|
expires_in_name: str = "expires_in",
|
41
41
|
refresh_request_body: Mapping[str, Any] | None = None,
|
42
|
+
refresh_request_headers: Mapping[str, Any] | None = None,
|
42
43
|
grant_type_name: str = "grant_type",
|
43
44
|
grant_type: str = "refresh_token",
|
44
45
|
token_expiry_is_time_of_expiration: bool = False,
|
@@ -57,6 +58,7 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
|
|
57
58
|
self._access_token_name = access_token_name
|
58
59
|
self._expires_in_name = expires_in_name
|
59
60
|
self._refresh_request_body = refresh_request_body
|
61
|
+
self._refresh_request_headers = refresh_request_headers
|
60
62
|
self._grant_type_name = grant_type_name
|
61
63
|
self._grant_type = grant_type
|
62
64
|
|
@@ -101,6 +103,9 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
|
|
101
103
|
def get_refresh_request_body(self) -> Mapping[str, Any]:
|
102
104
|
return self._refresh_request_body # type: ignore [return-value]
|
103
105
|
|
106
|
+
def get_refresh_request_headers(self) -> Mapping[str, Any]:
|
107
|
+
return self._refresh_request_headers # type: ignore [return-value]
|
108
|
+
|
104
109
|
def get_grant_type_name(self) -> str:
|
105
110
|
return self._grant_type_name
|
106
111
|
|
@@ -149,6 +154,7 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
|
|
149
154
|
expires_in_name: str = "expires_in",
|
150
155
|
refresh_token_name: str = "refresh_token",
|
151
156
|
refresh_request_body: Mapping[str, Any] | None = None,
|
157
|
+
refresh_request_headers: Mapping[str, Any] | None = None,
|
152
158
|
grant_type_name: str = "grant_type",
|
153
159
|
grant_type: str = "refresh_token",
|
154
160
|
client_id_name: str = "client_id",
|
@@ -174,6 +180,7 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
|
|
174
180
|
expires_in_name (str, optional): Name of the name of the field that characterizes when the current access token will expire, used to parse the refresh token response. Defaults to "expires_in".
|
175
181
|
refresh_token_name (str, optional): Name of the name of the refresh token field, used to parse the refresh token response. Defaults to "refresh_token".
|
176
182
|
refresh_request_body (Mapping[str, Any], optional): Custom key value pair that will be added to the refresh token request body. Defaults to None.
|
183
|
+
refresh_request_headers (Mapping[str, Any], optional): Custom key value pair that will be added to the refresh token request headers. Defaults to None.
|
177
184
|
grant_type (str, optional): OAuth grant type. Defaults to "refresh_token".
|
178
185
|
client_id (Optional[str]): The client id to authenticate. If not specified, defaults to credentials.client_id in the config object.
|
179
186
|
client_secret (Optional[str]): The client secret to authenticate. If not specified, defaults to credentials.client_secret in the config object.
|
@@ -220,6 +227,7 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
|
|
220
227
|
access_token_name=access_token_name,
|
221
228
|
expires_in_name=expires_in_name,
|
222
229
|
refresh_request_body=refresh_request_body,
|
230
|
+
refresh_request_headers=refresh_request_headers,
|
223
231
|
grant_type_name=self._grant_type_name,
|
224
232
|
grant_type=grant_type,
|
225
233
|
token_expiry_date_format=token_expiry_date_format,
|
@@ -53,7 +53,7 @@ airbyte_cdk/sources/declarative/async_job/timer.py,sha256=Fb8P72CQ7jIzJyzMSSNuBf
|
|
53
53
|
airbyte_cdk/sources/declarative/auth/__init__.py,sha256=e2CRrcBWGhz3sQu3Oh34d1riEIwXipGS8hrSB1pu0Oo,284
|
54
54
|
airbyte_cdk/sources/declarative/auth/declarative_authenticator.py,sha256=nf-OmRUHYG4ORBwyb5CANzuHEssE-oNmL-Lccn41Td8,1099
|
55
55
|
airbyte_cdk/sources/declarative/auth/jwt.py,sha256=7r5q1zOekjw8kEmEk1oUyovzVt3cbD6BuFnRILeLZi8,8250
|
56
|
-
airbyte_cdk/sources/declarative/auth/oauth.py,sha256=
|
56
|
+
airbyte_cdk/sources/declarative/auth/oauth.py,sha256=GhXWheC5GkKV7req3jBCY0aTbFwCuQ5RRSfZi3jFphM,11002
|
57
57
|
airbyte_cdk/sources/declarative/auth/selective_authenticator.py,sha256=qGwC6YsCldr1bIeKG6Qo-A9a5cTdHw-vcOn3OtQrS4c,1540
|
58
58
|
airbyte_cdk/sources/declarative/auth/token.py,sha256=r4u3WXyVa7WmiSZ9-eZXlrUI-pS0D4YWJnwjLzwV-Fk,11210
|
59
59
|
airbyte_cdk/sources/declarative/auth/token_provider.py,sha256=9oq3dcBPAPwXSfkISjhA05dMhIzxaDQTmwOydBrnsMk,3028
|
@@ -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=
|
69
|
+
airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=k_al8qcF6DSsm51IsZoUI8LCOlfZE141u2Iq5WEkfiI,135419
|
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
|
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=
|
109
|
+
airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=2UabGD45tpF_5YzjpFKcQ4PiVfCvYSa7RbrUPW7M_ZQ,95465
|
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=
|
114
|
+
airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=9hSAdPJFG_ZUkIbdBuxj_IUKARNRsRi8a7xX82UqTQ8,111726
|
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
|
@@ -288,9 +288,9 @@ airbyte_cdk/sources/streams/http/http.py,sha256=JAMpiTdS9HFNOlwayWNvQdxoqs2rpW9w
|
|
288
288
|
airbyte_cdk/sources/streams/http/http_client.py,sha256=tDE0ROtxjGMVphvsw8INvGMtZ97hIF-v47pZ3jIyiwc,23011
|
289
289
|
airbyte_cdk/sources/streams/http/rate_limiting.py,sha256=IwdjrHKUnU97XO4qONgYRv4YYW51xQ8SJm4WLafXDB8,6351
|
290
290
|
airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py,sha256=RN0D3nOX1xLgwEwKWu6pkGy3XqBFzKSNZ8Lf6umU2eY,413
|
291
|
-
airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256
|
291
|
+
airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256=-GDNyqccdutOftFpqCvvk81NwkskHhDZ8QcsUKzNjRQ,11660
|
292
292
|
airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py,sha256=Y3n7J-sk5yGjv_OxtY6Z6k0PEsFZmtIRi-x0KCbaHdA,1010
|
293
|
-
airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py,sha256=
|
293
|
+
airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py,sha256=OCNokL0GypjN8PUVJk1UFJVE5THkHAbNDmB984_F7W0,16718
|
294
294
|
airbyte_cdk/sources/streams/http/requests_native_auth/token.py,sha256=h5PTzcdH-RQLeCg7xZ45w_484OPUDSwNWl_iMJQmZoI,2526
|
295
295
|
airbyte_cdk/sources/streams/utils/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
|
296
296
|
airbyte_cdk/sources/types.py,sha256=nLPkTpyfGV4E6e99qcBWX4r8C3fE4I8Fvgx2EjvT9ic,5005
|
@@ -343,8 +343,8 @@ airbyte_cdk/utils/slice_hasher.py,sha256=-pHexlNYoWYPnXNH-M7HEbjmeJe9Zk7SJijdQ7d
|
|
343
343
|
airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
|
344
344
|
airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
|
345
345
|
airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
|
346
|
-
airbyte_cdk-6.
|
347
|
-
airbyte_cdk-6.
|
348
|
-
airbyte_cdk-6.
|
349
|
-
airbyte_cdk-6.
|
350
|
-
airbyte_cdk-6.
|
346
|
+
airbyte_cdk-6.19.1.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
|
347
|
+
airbyte_cdk-6.19.1.dist-info/METADATA,sha256=vZseMtnWdaQvyzb3uh3Egn-ahu7vHW0mijR0meswMDk,6000
|
348
|
+
airbyte_cdk-6.19.1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
349
|
+
airbyte_cdk-6.19.1.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
|
350
|
+
airbyte_cdk-6.19.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|