airbyte-cdk 6.13.1.dev4107__py3-none-any.whl → 6.13.1.dev4109__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.
@@ -56,8 +56,12 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
56
56
  token_expiry_is_time_of_expiration: bool = False
57
57
  access_token_name: Union[InterpolatedString, str] = "access_token"
58
58
  access_token_value: Optional[Union[InterpolatedString, str]] = None
59
+ client_id_name: Union[InterpolatedString, str] = "client_id"
60
+ client_secret_name: Union[InterpolatedString, str] = "client_secret"
59
61
  expires_in_name: Union[InterpolatedString, str] = "expires_in"
62
+ refresh_token_name: Union[InterpolatedString, str] = "refresh_token"
60
63
  refresh_request_body: Optional[Mapping[str, Any]] = None
64
+ grant_type_name: Union[InterpolatedString, str] = "grant_type"
61
65
  grant_type: Union[InterpolatedString, str] = "refresh_token"
62
66
  message_repository: MessageRepository = NoopMessageRepository()
63
67
 
@@ -69,8 +73,15 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
69
73
  )
70
74
  else:
71
75
  self._token_refresh_endpoint = None
76
+ self._client_id_name = InterpolatedString.create(self.client_id_name, parameters=parameters)
72
77
  self._client_id = InterpolatedString.create(self.client_id, parameters=parameters)
78
+ self._client_secret_name = InterpolatedString.create(
79
+ self.client_secret_name, parameters=parameters
80
+ )
73
81
  self._client_secret = InterpolatedString.create(self.client_secret, parameters=parameters)
82
+ self._refresh_token_name = InterpolatedString.create(
83
+ self.refresh_token_name, parameters=parameters
84
+ )
74
85
  if self.refresh_token is not None:
75
86
  self._refresh_token: Optional[InterpolatedString] = InterpolatedString.create(
76
87
  self.refresh_token, parameters=parameters
@@ -83,6 +94,9 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
83
94
  self.expires_in_name = InterpolatedString.create(
84
95
  self.expires_in_name, parameters=parameters
85
96
  )
97
+ self.grant_type_name = InterpolatedString.create(
98
+ self.grant_type_name, parameters=parameters
99
+ )
86
100
  self.grant_type = InterpolatedString.create(self.grant_type, parameters=parameters)
87
101
  self._refresh_request_body = InterpolatedMapping(
88
102
  self.refresh_request_body or {}, parameters=parameters
@@ -122,18 +136,27 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
122
136
  return refresh_token_endpoint
123
137
  return None
124
138
 
139
+ def get_client_id_name(self) -> str:
140
+ return self._client_id_name.eval(self.config) # type: ignore # eval returns a string in this context
141
+
125
142
  def get_client_id(self) -> str:
126
143
  client_id: str = self._client_id.eval(self.config)
127
144
  if not client_id:
128
145
  raise ValueError("OAuthAuthenticator was unable to evaluate client_id parameter")
129
146
  return client_id
130
147
 
148
+ def get_client_secret_name(self) -> str:
149
+ return self._client_secret_name.eval(self.config) # type: ignore # eval returns a string in this context
150
+
131
151
  def get_client_secret(self) -> str:
132
152
  client_secret: str = self._client_secret.eval(self.config)
133
153
  if not client_secret:
134
154
  raise ValueError("OAuthAuthenticator was unable to evaluate client_secret parameter")
135
155
  return client_secret
136
156
 
157
+ def get_refresh_token_name(self) -> str:
158
+ return self._refresh_token_name.eval(self.config) # type: ignore # eval returns a string in this context
159
+
137
160
  def get_refresh_token(self) -> Optional[str]:
138
161
  return None if self._refresh_token is None else str(self._refresh_token.eval(self.config))
139
162
 
@@ -146,6 +169,9 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut
146
169
  def get_expires_in_name(self) -> str:
147
170
  return self.expires_in_name.eval(self.config) # type: ignore # eval returns a string in this context
148
171
 
172
+ def get_grant_type_name(self) -> str:
173
+ return self.grant_type_name.eval(self.config) # type: ignore # eval returns a string in this context
174
+
149
175
  def get_grant_type(self) -> str:
150
176
  return self.grant_type.eval(self.config) # type: ignore # eval returns a string in this context
151
177
 
@@ -1047,6 +1047,13 @@ definitions:
1047
1047
  type:
1048
1048
  type: string
1049
1049
  enum: [OAuthAuthenticator]
1050
+ client_id_name:
1051
+ title: Client ID Property Name
1052
+ description: The name of the property to use to refresh the `access_token`.
1053
+ type: string
1054
+ default: "client_id"
1055
+ examples:
1056
+ - custom_app_id
1050
1057
  client_id:
1051
1058
  title: Client ID
1052
1059
  description: The OAuth client ID. Fill it in the user inputs.
@@ -1054,6 +1061,13 @@ definitions:
1054
1061
  examples:
1055
1062
  - "{{ config['client_id }}"
1056
1063
  - "{{ config['credentials']['client_id }}"
1064
+ client_secret_name:
1065
+ title: Client Secret Property Name
1066
+ description: The name of the property to use to refresh the `access_token`.
1067
+ type: string
1068
+ default: "client_secret"
1069
+ examples:
1070
+ - custom_app_secret
1057
1071
  client_secret:
1058
1072
  title: Client Secret
1059
1073
  description: The OAuth client secret. Fill it in the user inputs.
@@ -1061,6 +1075,13 @@ definitions:
1061
1075
  examples:
1062
1076
  - "{{ config['client_secret }}"
1063
1077
  - "{{ config['credentials']['client_secret }}"
1078
+ refresh_token_name:
1079
+ title: Refresh Token Property Name
1080
+ description: The name of the property to use to refresh the `access_token`.
1081
+ type: string
1082
+ default: "refresh_token"
1083
+ examples:
1084
+ - custom_app_refresh_value
1064
1085
  refresh_token:
1065
1086
  title: Refresh Token
1066
1087
  description: Credential artifact used to get a new access token.
@@ -1094,6 +1115,13 @@ definitions:
1094
1115
  default: "expires_in"
1095
1116
  examples:
1096
1117
  - expires_in
1118
+ grant_type_name:
1119
+ title: Grant Type Property Name
1120
+ description: The name of the property to use to refresh the `access_token`.
1121
+ type: string
1122
+ default: "grant_type"
1123
+ examples:
1124
+ - custom_grant_type
1097
1125
  grant_type:
1098
1126
  title: Grant Type
1099
1127
  description: Specifies the OAuth2 grant type. If set to refresh_token, the refresh_token needs to be provided as well. For client_credentials, only client id and secret are required. Other grant types are not officially supported.
@@ -2204,15 +2232,15 @@ definitions:
2204
2232
  Pertains to the fields defined by the connector relating to the OAuth flow.
2205
2233
 
2206
2234
  Interpolation capabilities:
2207
- - The variables placeholders are declared as `{my_var}`.
2208
- - The nested resolution variables like `{{my_nested_var}}` is allowed as well.
2235
+ - The variables placeholders are declared as `{{my_var}}`.
2236
+ - The nested resolution variables like `{{ {{my_nested_var}} }}` is allowed as well.
2209
2237
 
2210
2238
  - The allowed interpolation context is:
2211
- + base64Encoder - encode to `base64`, {base64Encoder:{my_var_a}:{my_var_b}}
2212
- + base64Decorer - decode from `base64` encoded string, {base64Decoder:{my_string_variable_or_string_value}}
2213
- + urlEncoder - encode the input string to URL-like format, {urlEncoder:https://test.host.com/endpoint}
2214
- + urlDecorer - decode the input url-encoded string into text format, {urlDecoder:https%3A%2F%2Fairbyte.io}
2215
- + codeChallengeS256 - get the `codeChallenge` encoded value to provide additional data-provider specific authorisation values, {codeChallengeS256:{state_value}}
2239
+ + base64Encoder - encode to `base64`, {{ {{my_var_a}}:{{my_var_b}} | base64Encoder }}
2240
+ + base64Decorer - decode from `base64` encoded string, {{ {{my_string_variable_or_string_value}} | base64Decoder }}
2241
+ + urlEncoder - encode the input string to URL-like format, {{ https://test.host.com/endpoint | urlEncoder}}
2242
+ + urlDecorer - decode the input url-encoded string into text format, {{ urlDecoder:https%3A%2F%2Fairbyte.io | urlDecoder}}
2243
+ + codeChallengeS256 - get the `codeChallenge` encoded value to provide additional data-provider specific authorisation values, {{ {{state_value}} | codeChallengeS256 }}
2216
2244
 
2217
2245
  Examples:
2218
2246
  - The TikTok Marketing DeclarativeOAuth spec:
@@ -2221,12 +2249,12 @@ definitions:
2221
2249
  "type": "object",
2222
2250
  "additionalProperties": false,
2223
2251
  "properties": {
2224
- "consent_url": "https://ads.tiktok.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}",
2252
+ "consent_url": "https://ads.tiktok.com/marketing_api/auth?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{ {{redirect_uri_value}} | urlEncoder}}&{{state_key}}={{state_value}}",
2225
2253
  "access_token_url": "https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/",
2226
2254
  "access_token_params": {
2227
- "{auth_code_key}": "{{auth_code_key}}",
2228
- "{client_id_key}": "{{client_id_key}}",
2229
- "{client_secret_key}": "{{client_secret_key}}"
2255
+ "{{ auth_code_key }}": "{{ auth_code_value }}",
2256
+ "{{ client_id_key }}": "{{ client_id_value }}",
2257
+ "{{ client_secret_key }}": "{{ client_secret_value }}"
2230
2258
  },
2231
2259
  "access_token_headers": {
2232
2260
  "Content-Type": "application/json",
@@ -2244,7 +2272,6 @@ definitions:
2244
2272
  required:
2245
2273
  - consent_url
2246
2274
  - access_token_url
2247
- - extract_output
2248
2275
  properties:
2249
2276
  consent_url:
2250
2277
  title: Consent URL
@@ -2253,8 +2280,8 @@ definitions:
2253
2280
  The DeclarativeOAuth Specific string URL string template to initiate the authentication.
2254
2281
  The placeholders are replaced during the processing to provide neccessary values.
2255
2282
  examples:
2256
- - https://domain.host.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}
2257
- - 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}
2283
+ - https://domain.host.com/marketing_api/auth?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{{{redirect_uri_value}} | urlEncoder}}&{{state_key}}={{state_value}}
2284
+ - https://endpoint.host.com/oauth2/authorize?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{{{redirect_uri_value}} | urlEncoder}}&{{scope_key}}={{{{scope_value}} | urlEncoder}}&{{state_key}}={{state_value}}&subdomain={{subdomain}}
2258
2285
  scope:
2259
2286
  title: Scopes
2260
2287
  type: string
@@ -2269,7 +2296,7 @@ definitions:
2269
2296
  The DeclarativeOAuth Specific URL templated string to obtain the `access_token`, `refresh_token` etc.
2270
2297
  The placeholders are replaced during the processing to provide neccessary values.
2271
2298
  examples:
2272
- - 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}}}
2299
+ - https://auth.host.com/oauth2/token?{{client_id_key}}={{client_id_value}}&{{client_secret_key}}={{client_secret_value}}&{{auth_code_key}}={{auth_code_value}}&{{redirect_uri_key}}={{{{redirect_uri_value}} | urlEncoder}}
2273
2300
  access_token_headers:
2274
2301
  title: Access Token Headers
2275
2302
  type: object
@@ -2278,7 +2305,7 @@ definitions:
2278
2305
  The DeclarativeOAuth Specific optional headers to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.
2279
2306
  examples:
2280
2307
  - {
2281
- "Authorization": "Basic {base64Encoder:{client_id}:{client_secret}}",
2308
+ "Authorization": "Basic {{ {{ client_id_value }}:{{ client_secret_value }} | base64Encoder }}",
2282
2309
  }
2283
2310
  access_token_params:
2284
2311
  title: Access Token Query Params (Json Encoded)
@@ -2289,9 +2316,9 @@ definitions:
2289
2316
  When this property is provided, the query params will be encoded as `Json` and included in the outgoing API request.
2290
2317
  examples:
2291
2318
  - {
2292
- "{auth_code_key}": "{{auth_code_key}}",
2293
- "{client_id_key}": "{{client_id_key}}",
2294
- "{client_secret_key}": "{{client_secret_key}}",
2319
+ "{{ auth_code_key }}": "{{ auth_code_value }}",
2320
+ "{{ client_id_key }}": "{{ client_id_value }}",
2321
+ "{{ client_secret_key }}": "{{ client_secret_value }}",
2295
2322
  }
2296
2323
  extract_output:
2297
2324
  title: Extract Output
@@ -2977,6 +3004,11 @@ definitions:
2977
3004
  anyOf:
2978
3005
  - "$ref": "#/definitions/CustomRequester"
2979
3006
  - "$ref": "#/definitions/HttpRequester"
3007
+ url_requester:
3008
+ description: Requester component that describes how to prepare HTTP requests to send to the source API to extract the url from polling response by the completed async job.
3009
+ anyOf:
3010
+ - "$ref": "#/definitions/CustomRequester"
3011
+ - "$ref": "#/definitions/HttpRequester"
2980
3012
  download_requester:
2981
3013
  description: Requester component that describes how to prepare HTTP requests to send to the source API to download the data provided by the completed async job.
2982
3014
  anyOf:
@@ -481,12 +481,24 @@ class RefreshTokenUpdater(BaseModel):
481
481
 
482
482
  class OAuthAuthenticator(BaseModel):
483
483
  type: Literal["OAuthAuthenticator"]
484
+ client_id_name: Optional[str] = Field(
485
+ "client_id",
486
+ description="The name of the property to use to refresh the `access_token`.",
487
+ examples=["custom_app_id"],
488
+ title="Client ID Property Name",
489
+ )
484
490
  client_id: str = Field(
485
491
  ...,
486
492
  description="The OAuth client ID. Fill it in the user inputs.",
487
493
  examples=["{{ config['client_id }}", "{{ config['credentials']['client_id }}"],
488
494
  title="Client ID",
489
495
  )
496
+ client_secret_name: Optional[str] = Field(
497
+ "client_secret",
498
+ description="The name of the property to use to refresh the `access_token`.",
499
+ examples=["custom_app_secret"],
500
+ title="Client Secret Property Name",
501
+ )
490
502
  client_secret: str = Field(
491
503
  ...,
492
504
  description="The OAuth client secret. Fill it in the user inputs.",
@@ -496,6 +508,12 @@ class OAuthAuthenticator(BaseModel):
496
508
  ],
497
509
  title="Client Secret",
498
510
  )
511
+ refresh_token_name: Optional[str] = Field(
512
+ "refresh_token",
513
+ description="The name of the property to use to refresh the `access_token`.",
514
+ examples=["custom_app_refresh_value"],
515
+ title="Refresh Token Property Name",
516
+ )
499
517
  refresh_token: Optional[str] = Field(
500
518
  None,
501
519
  description="Credential artifact used to get a new access token.",
@@ -529,6 +547,12 @@ class OAuthAuthenticator(BaseModel):
529
547
  examples=["expires_in"],
530
548
  title="Token Expiry Property Name",
531
549
  )
550
+ grant_type_name: Optional[str] = Field(
551
+ "grant_type",
552
+ description="The name of the property to use to refresh the `access_token`.",
553
+ examples=["custom_grant_type"],
554
+ title="Grant Type Property Name",
555
+ )
532
556
  grant_type: Optional[str] = Field(
533
557
  "refresh_token",
534
558
  description="Specifies the OAuth2 grant type. If set to refresh_token, the refresh_token needs to be provided as well. For client_credentials, only client id and secret are required. Other grant types are not officially supported.",
@@ -737,33 +761,43 @@ class KeysToSnakeCase(BaseModel):
737
761
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
738
762
 
739
763
 
764
+ class FlattenFields(BaseModel):
765
+ type: Literal["FlattenFields"]
766
+ flatten_lists: Optional[bool] = Field(
767
+ True,
768
+ description="Whether to flatten lists or leave it as is. Default is True.",
769
+ title="Flatten Lists",
770
+ )
771
+ parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
772
+
773
+
740
774
  class KeysReplace(BaseModel):
741
775
  type: Literal["KeysReplace"]
742
776
  old: str = Field(
743
777
  ...,
744
778
  description="Old value to replace.",
745
- examples=[" ", "{{ record.id }}", "{{ config['id'] }}", "{{ stream_slice['id'] }}"],
779
+ examples=[
780
+ " ",
781
+ "{{ record.id }}",
782
+ "{{ config['id'] }}",
783
+ "{{ stream_slice['id'] }}",
784
+ ],
746
785
  title="Old value",
747
786
  )
748
787
  new: str = Field(
749
788
  ...,
750
789
  description="New value to set.",
751
- examples=["_", "{{ record.id }}", "{{ config['id'] }}", "{{ stream_slice['id'] }}"],
790
+ examples=[
791
+ "_",
792
+ "{{ record.id }}",
793
+ "{{ config['id'] }}",
794
+ "{{ stream_slice['id'] }}",
795
+ ],
752
796
  title="New value",
753
797
  )
754
798
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
755
799
 
756
800
 
757
- class FlattenFields(BaseModel):
758
- type: Literal["FlattenFields"]
759
- flatten_lists: Optional[bool] = Field(
760
- True,
761
- description="Whether to flatten lists or leave it as is. Default is True.",
762
- title="Flatten Lists",
763
- )
764
- parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
765
-
766
-
767
801
  class IterableDecoder(BaseModel):
768
802
  type: Literal["IterableDecoder"]
769
803
 
@@ -849,8 +883,8 @@ class OauthConnectorInputSpecification(BaseModel):
849
883
  ...,
850
884
  description="The DeclarativeOAuth Specific string URL string template to initiate the authentication.\nThe placeholders are replaced during the processing to provide neccessary values.",
851
885
  examples=[
852
- "https://domain.host.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}",
853
- "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}",
886
+ "https://domain.host.com/marketing_api/auth?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{{{redirect_uri_value}} | urlEncoder}}&{{state_key}}={{state_value}}",
887
+ "https://endpoint.host.com/oauth2/authorize?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{{{redirect_uri_value}} | urlEncoder}}&{{scope_key}}={{{{scope_value}} | urlEncoder}}&{{state_key}}={{state_value}}&subdomain={{subdomain}}",
854
888
  ],
855
889
  title="Consent URL",
856
890
  )
@@ -864,14 +898,18 @@ class OauthConnectorInputSpecification(BaseModel):
864
898
  ...,
865
899
  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.",
866
900
  examples=[
867
- "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}}}"
901
+ "https://auth.host.com/oauth2/token?{{client_id_key}}={{client_id_value}}&{{client_secret_key}}={{client_secret_value}}&{{auth_code_key}}={{auth_code_value}}&{{redirect_uri_key}}={{{{redirect_uri_value}} | urlEncoder}}"
868
902
  ],
869
903
  title="Access Token URL",
870
904
  )
871
905
  access_token_headers: Optional[Dict[str, Any]] = Field(
872
906
  None,
873
907
  description="The DeclarativeOAuth Specific optional headers to inject while exchanging the `auth_code` to `access_token` during `completeOAuthFlow` step.",
874
- examples=[{"Authorization": "Basic {base64Encoder:{client_id}:{client_secret}}"}],
908
+ examples=[
909
+ {
910
+ "Authorization": "Basic {{ {{ client_id_value }}:{{ client_secret_value }} | base64Encoder }}"
911
+ }
912
+ ],
875
913
  title="Access Token Headers",
876
914
  )
877
915
  access_token_params: Optional[Dict[str, Any]] = Field(
@@ -879,15 +917,15 @@ class OauthConnectorInputSpecification(BaseModel):
879
917
  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.",
880
918
  examples=[
881
919
  {
882
- "{auth_code_key}": "{{auth_code_key}}",
883
- "{client_id_key}": "{{client_id_key}}",
884
- "{client_secret_key}": "{{client_secret_key}}",
920
+ "{{ auth_code_key }}": "{{ auth_code_value }}",
921
+ "{{ client_id_key }}": "{{ client_id_value }}",
922
+ "{{ client_secret_key }}": "{{ client_secret_value }}",
885
923
  }
886
924
  ],
887
925
  title="Access Token Query Params (Json Encoded)",
888
926
  )
889
- extract_output: List[str] = Field(
890
- ...,
927
+ extract_output: Optional[List[str]] = Field(
928
+ None,
891
929
  description="The DeclarativeOAuth Specific list of strings to indicate which keys should be extracted and returned back to the input config.",
892
930
  examples=[["access_token", "refresh_token", "other_field"]],
893
931
  title="Extract Output",
@@ -956,7 +994,7 @@ class OAuthConfigSpecification(BaseModel):
956
994
  )
957
995
  oauth_connector_input_specification: Optional[OauthConnectorInputSpecification] = Field(
958
996
  None,
959
- description='The DeclarativeOAuth specific blob.\nPertains to the fields defined by the connector relating to the OAuth flow.\n\nInterpolation capabilities:\n- The variables placeholders are declared as `{my_var}`.\n- The nested resolution variables like `{{my_nested_var}}` is allowed as well.\n\n- The allowed interpolation context is:\n + base64Encoder - encode to `base64`, {base64Encoder:{my_var_a}:{my_var_b}}\n + base64Decorer - decode from `base64` encoded string, {base64Decoder:{my_string_variable_or_string_value}}\n + urlEncoder - encode the input string to URL-like format, {urlEncoder:https://test.host.com/endpoint}\n + urlDecorer - decode the input url-encoded string into text format, {urlDecoder:https%3A%2F%2Fairbyte.io}\n + codeChallengeS256 - get the `codeChallenge` encoded value to provide additional data-provider specific authorisation values, {codeChallengeS256:{state_value}}\n\nExamples:\n - The TikTok Marketing DeclarativeOAuth spec:\n {\n "oauth_connector_input_specification": {\n "type": "object",\n "additionalProperties": false,\n "properties": {\n "consent_url": "https://ads.tiktok.com/marketing_api/auth?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{state_key}={{state_key}}",\n "access_token_url": "https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/",\n "access_token_params": {\n "{auth_code_key}": "{{auth_code_key}}",\n "{client_id_key}": "{{client_id_key}}",\n "{client_secret_key}": "{{client_secret_key}}"\n },\n "access_token_headers": {\n "Content-Type": "application/json",\n "Accept": "application/json"\n },\n "extract_output": ["data.access_token"],\n "client_id_key": "app_id",\n "client_secret_key": "secret",\n "auth_code_key": "auth_code"\n }\n }\n }',
997
+ description='The DeclarativeOAuth specific blob.\nPertains to the fields defined by the connector relating to the OAuth flow.\n\nInterpolation capabilities:\n- The variables placeholders are declared as `{{my_var}}`.\n- The nested resolution variables like `{{ {{my_nested_var}} }}` is allowed as well.\n\n- The allowed interpolation context is:\n + base64Encoder - encode to `base64`, {{ {{my_var_a}}:{{my_var_b}} | base64Encoder }}\n + base64Decorer - decode from `base64` encoded string, {{ {{my_string_variable_or_string_value}} | base64Decoder }}\n + urlEncoder - encode the input string to URL-like format, {{ https://test.host.com/endpoint | urlEncoder}}\n + urlDecorer - decode the input url-encoded string into text format, {{ urlDecoder:https%3A%2F%2Fairbyte.io | urlDecoder}}\n + codeChallengeS256 - get the `codeChallenge` encoded value to provide additional data-provider specific authorisation values, {{ {{state_value}} | codeChallengeS256 }}\n\nExamples:\n - The TikTok Marketing DeclarativeOAuth spec:\n {\n "oauth_connector_input_specification": {\n "type": "object",\n "additionalProperties": false,\n "properties": {\n "consent_url": "https://ads.tiktok.com/marketing_api/auth?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{ {{redirect_uri_value}} | urlEncoder}}&{{state_key}}={{state_value}}",\n "access_token_url": "https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/",\n "access_token_params": {\n "{{ auth_code_key }}": "{{ auth_code_value }}",\n "{{ client_id_key }}": "{{ client_id_value }}",\n "{{ client_secret_key }}": "{{ client_secret_value }}"\n },\n "access_token_headers": {\n "Content-Type": "application/json",\n "Accept": "application/json"\n },\n "extract_output": ["data.access_token"],\n "client_id_key": "app_id",\n "client_secret_key": "secret",\n "auth_code_key": "auth_code"\n }\n }\n }',
960
998
  title="DeclarativeOAuth Connector Specification",
961
999
  )
962
1000
  complete_oauth_output_specification: Optional[Dict[str, Any]] = Field(
@@ -2040,6 +2078,10 @@ class AsyncRetriever(BaseModel):
2040
2078
  ...,
2041
2079
  description="Requester component that describes how to prepare HTTP requests to send to the source API to fetch the status of the running async job.",
2042
2080
  )
2081
+ url_requester: Optional[Union[CustomRequester, HttpRequester]] = Field(
2082
+ None,
2083
+ description="Requester component that describes how to prepare HTTP requests to send to the source API to extract the url from polling response by the completed async job.",
2084
+ )
2043
2085
  download_requester: Union[CustomRequester, HttpRequester] = Field(
2044
2086
  ...,
2045
2087
  description="Requester component that describes how to prepare HTTP requests to send to the source API to download the data provided by the completed async job.",
@@ -1885,15 +1885,24 @@ class ModelToComponentFactory:
1885
1885
  expires_in_name=InterpolatedString.create(
1886
1886
  model.expires_in_name or "expires_in", parameters=model.parameters or {}
1887
1887
  ).eval(config),
1888
+ client_id_name=InterpolatedString.create(
1889
+ model.client_id_name or "client_id", parameters=model.parameters or {}
1890
+ ).eval(config),
1888
1891
  client_id=InterpolatedString.create(
1889
1892
  model.client_id, parameters=model.parameters or {}
1890
1893
  ).eval(config),
1894
+ client_secret_name=InterpolatedString.create(
1895
+ model.client_secret_name or "client_secret", parameters=model.parameters or {}
1896
+ ).eval(config),
1891
1897
  client_secret=InterpolatedString.create(
1892
1898
  model.client_secret, parameters=model.parameters or {}
1893
1899
  ).eval(config),
1894
1900
  access_token_config_path=model.refresh_token_updater.access_token_config_path,
1895
1901
  refresh_token_config_path=model.refresh_token_updater.refresh_token_config_path,
1896
1902
  token_expiry_date_config_path=model.refresh_token_updater.token_expiry_date_config_path,
1903
+ grant_type_name=InterpolatedString.create(
1904
+ model.grant_type_name or "grant_type", parameters=model.parameters or {}
1905
+ ).eval(config),
1897
1906
  grant_type=InterpolatedString.create(
1898
1907
  model.grant_type or "refresh_token", parameters=model.parameters or {}
1899
1908
  ).eval(config),
@@ -1911,11 +1920,15 @@ class ModelToComponentFactory:
1911
1920
  return DeclarativeOauth2Authenticator( # type: ignore
1912
1921
  access_token_name=model.access_token_name or "access_token",
1913
1922
  access_token_value=model.access_token_value,
1923
+ client_id_name=model.client_id_name or "client_id",
1914
1924
  client_id=model.client_id,
1925
+ client_secret_name=model.client_secret_name or "client_secret",
1915
1926
  client_secret=model.client_secret,
1916
1927
  expires_in_name=model.expires_in_name or "expires_in",
1928
+ grant_type_name=model.grant_type_name or "grant_type",
1917
1929
  grant_type=model.grant_type or "refresh_token",
1918
1930
  refresh_request_body=model.refresh_request_body,
1931
+ refresh_token_name=model.refresh_token_name or "refresh_token",
1919
1932
  refresh_token=model.refresh_token,
1920
1933
  scopes=model.scopes,
1921
1934
  token_expiry_date=model.token_expiry_date,
@@ -2287,7 +2300,7 @@ class ModelToComponentFactory:
2287
2300
  extractor=download_extractor,
2288
2301
  name=name,
2289
2302
  record_filter=None,
2290
- transformations=[],
2303
+ transformations=transformations,
2291
2304
  schema_normalization=TypeTransformer(TransformConfig.NoTransform),
2292
2305
  config=config,
2293
2306
  parameters={},
@@ -2324,6 +2337,16 @@ class ModelToComponentFactory:
2324
2337
  if model.delete_requester
2325
2338
  else None
2326
2339
  )
2340
+ url_requester = (
2341
+ self._create_component_from_model(
2342
+ model=model.url_requester,
2343
+ decoder=decoder,
2344
+ config=config,
2345
+ name=f"job extract_url - {name}",
2346
+ )
2347
+ if model.url_requester
2348
+ else None
2349
+ )
2327
2350
  status_extractor = self._create_component_from_model(
2328
2351
  model=model.status_extractor, decoder=decoder, config=config, name=name
2329
2352
  )
@@ -2334,6 +2357,7 @@ class ModelToComponentFactory:
2334
2357
  creation_requester=creation_requester,
2335
2358
  polling_requester=polling_requester,
2336
2359
  download_retriever=download_retriever,
2360
+ url_requester=url_requester,
2337
2361
  abort_requester=abort_requester,
2338
2362
  delete_requester=delete_requester,
2339
2363
  status_extractor=status_extractor,
@@ -0,0 +1,57 @@
1
+ # AsyncHttpJobRepository sequence diagram
2
+
3
+ - Components marked as optional are not required and can be ignored.
4
+ - if `url_requester` is not provided, `urls_extractor` will get urls from the `polling_job_response`
5
+ - interpolation_context, e.g. `create_job_response` or `polling_job_response` can be obtained from stream_slice
6
+
7
+
8
+ ```mermaid
9
+ ---
10
+ title: AsyncHttpJobRepository Sequence Diagram
11
+ ---
12
+ sequenceDiagram
13
+ participant AsyncHttpJobRepository as AsyncOrchestrator
14
+ participant CreationRequester as creation_requester
15
+ participant PollingRequester as polling_requester
16
+ participant UrlRequester as url_requester (Optional)
17
+ participant DownloadRetriever as download_retriever
18
+ participant AbortRequester as abort_requester (Optional)
19
+ participant DeleteRequester as delete_requester (Optional)
20
+ participant Reporting Server as Async Reporting Server
21
+
22
+ AsyncHttpJobRepository ->> CreationRequester: Initiate job creation
23
+ CreationRequester ->> Reporting Server: Create job request
24
+ Reporting Server -->> CreationRequester: Job ID response
25
+ CreationRequester -->> AsyncHttpJobRepository: Job ID
26
+
27
+ loop Poll for job status
28
+ AsyncHttpJobRepository ->> PollingRequester: Check job status
29
+ PollingRequester ->> Reporting Server: Status request (interpolation_context: `create_job_response`)
30
+ Reporting Server -->> PollingRequester: Status response
31
+ PollingRequester -->> AsyncHttpJobRepository: Job status
32
+ end
33
+
34
+ alt Status: Ready
35
+ AsyncHttpJobRepository ->> UrlRequester: Request download URLs (if applicable)
36
+ UrlRequester ->> Reporting Server: URL request (interpolation_context: `polling_job_response`)
37
+ Reporting Server -->> UrlRequester: Download URLs
38
+ UrlRequester -->> AsyncHttpJobRepository: Download URLs
39
+
40
+ AsyncHttpJobRepository ->> DownloadRetriever: Download reports
41
+ DownloadRetriever ->> Reporting Server: Retrieve report data (interpolation_context: `url`)
42
+ Reporting Server -->> DownloadRetriever: Report data
43
+ DownloadRetriever -->> AsyncHttpJobRepository: Report data
44
+ else Status: Failed
45
+ AsyncHttpJobRepository ->> AbortRequester: Send abort request
46
+ AbortRequester ->> Reporting Server: Abort job
47
+ Reporting Server -->> AbortRequester: Abort confirmation
48
+ AbortRequester -->> AsyncHttpJobRepository: Confirmation
49
+ end
50
+
51
+ AsyncHttpJobRepository ->> DeleteRequester: Send delete job request
52
+ DeleteRequester ->> Reporting Server: Delete job
53
+ Reporting Server -->> DeleteRequester: Deletion confirmation
54
+ DeleteRequester -->> AsyncHttpJobRepository: Confirmation
55
+
56
+
57
+ ```
@@ -31,6 +31,10 @@ LOGGER = logging.getLogger("airbyte")
31
31
 
32
32
  @dataclass
33
33
  class AsyncHttpJobRepository(AsyncJobRepository):
34
+ """
35
+ See Readme file for more details about flow.
36
+ """
37
+
34
38
  creation_requester: Requester
35
39
  polling_requester: Requester
36
40
  download_retriever: SimpleRetriever
@@ -44,6 +48,9 @@ class AsyncHttpJobRepository(AsyncJobRepository):
44
48
  record_extractor: RecordExtractor = field(
45
49
  init=False, repr=False, default_factory=lambda: ResponseToFileExtractor({})
46
50
  )
51
+ url_requester: Optional[Requester] = (
52
+ None # use it in case polling_requester provides some <id> and extra request is needed to obtain list of urls to download from
53
+ )
47
54
 
48
55
  def __post_init__(self) -> None:
49
56
  self._create_job_response_by_id: Dict[str, Response] = {}
@@ -186,10 +193,13 @@ class AsyncHttpJobRepository(AsyncJobRepository):
186
193
 
187
194
  """
188
195
 
189
- for url in self.urls_extractor.extract_records(
190
- self._polling_job_response_by_id[job.api_job_id()]
191
- ):
192
- stream_slice: StreamSlice = StreamSlice(partition={"url": url}, cursor_slice={})
196
+ for url in self._get_download_url(job):
197
+ job_slice = job.job_parameters()
198
+ stream_slice = StreamSlice(
199
+ partition=job_slice.partition,
200
+ cursor_slice=job_slice.cursor_slice,
201
+ extra_fields={**job_slice.extra_fields, "url": url},
202
+ )
193
203
  for message in self.download_retriever.read_records({}, stream_slice):
194
204
  if isinstance(message, Record):
195
205
  yield message.data
@@ -226,3 +236,22 @@ class AsyncHttpJobRepository(AsyncJobRepository):
226
236
  cursor_slice={},
227
237
  )
228
238
  return stream_slice
239
+
240
+ def _get_download_url(self, job: AsyncJob) -> Iterable[str]:
241
+ if not self.url_requester:
242
+ url_response = self._polling_job_response_by_id[job.api_job_id()]
243
+ else:
244
+ stream_slice: StreamSlice = StreamSlice(
245
+ partition={
246
+ "polling_job_response": self._polling_job_response_by_id[job.api_job_id()]
247
+ },
248
+ cursor_slice={},
249
+ )
250
+ url_response = self.url_requester.send_request(stream_slice=stream_slice) # type: ignore # we expect url_requester to always be presented, otherwise raise an exception as we cannot proceed with the report
251
+ if not url_response:
252
+ raise AirbyteTracedException(
253
+ internal_message="Always expect a response or an exception from url_requester",
254
+ failure_type=FailureType.system_error,
255
+ )
256
+
257
+ yield from self.urls_extractor.extract_records(url_response) # type: ignore # we expect urls_extractor to always return list of strings
@@ -42,18 +42,35 @@ from airbyte_cdk.utils.traced_exception import AirbyteTracedException
42
42
  unstructured_partition_pdf = None
43
43
  unstructured_partition_docx = None
44
44
  unstructured_partition_pptx = None
45
- nltk_data_dir = "/tmp/nltk_data"
45
+
46
+ AIRBYTE_NLTK_DATA_DIR = "/airbyte/nltk_data"
47
+ TMP_NLTK_DATA_DIR = "/tmp/nltk_data"
48
+
49
+
50
+ def get_nltk_temp_folder() -> str:
51
+ """
52
+ For non-root connectors /tmp is not currently writable, but we should allow it in the future.
53
+ It's safe to use /airbyte for now. Fallback to /tmp for local development.
54
+ """
55
+ try:
56
+ nltk_data_dir = AIRBYTE_NLTK_DATA_DIR
57
+ os.makedirs(nltk_data_dir, exist_ok=True)
58
+ except OSError:
59
+ nltk_data_dir = TMP_NLTK_DATA_DIR
60
+ os.makedirs(nltk_data_dir, exist_ok=True)
61
+ return nltk_data_dir
62
+
46
63
 
47
64
  try:
48
- os.makedirs(nltk_data_dir, exist_ok=True)
65
+ nltk_data_dir = get_nltk_temp_folder()
49
66
  nltk.data.path.append(nltk_data_dir)
50
67
  nltk.data.find("tokenizers/punkt.zip")
51
68
  nltk.data.find("tokenizers/punkt_tab.zip")
52
69
  nltk.data.find("tokenizers/averaged_perceptron_tagger_eng.zip")
53
70
  except LookupError:
54
- nltk.download("punkt", download_dir=nltk_data_dir)
55
- nltk.download("punkt_tab", download_dir=nltk_data_dir)
56
- nltk.download("averaged_perceptron_tagger_eng", download_dir=nltk_data_dir)
71
+ nltk.download("punkt", download_dir=nltk_data_dir, quiet=True)
72
+ nltk.download("punkt_tab", download_dir=nltk_data_dir, quiet=True)
73
+ nltk.download("averaged_perceptron_tagger_eng", download_dir=nltk_data_dir, quiet=True)
57
74
 
58
75
 
59
76
  def optional_decode(contents: Union[str, bytes]) -> str:
@@ -81,10 +81,10 @@ class AbstractOauth2Authenticator(AuthBase):
81
81
  Override to define additional parameters
82
82
  """
83
83
  payload: MutableMapping[str, Any] = {
84
- "grant_type": self.get_grant_type(),
85
- "client_id": self.get_client_id(),
86
- "client_secret": self.get_client_secret(),
87
- "refresh_token": self.get_refresh_token(),
84
+ self.get_grant_type_name(): self.get_grant_type(),
85
+ self.get_client_id_name(): self.get_client_id(),
86
+ self.get_client_secret_name(): self.get_client_secret(),
87
+ self.get_refresh_token_name(): self.get_refresh_token(),
88
88
  }
89
89
 
90
90
  if self.get_scopes():
@@ -206,14 +206,26 @@ class AbstractOauth2Authenticator(AuthBase):
206
206
  def get_token_refresh_endpoint(self) -> Optional[str]:
207
207
  """Returns the endpoint to refresh the access token"""
208
208
 
209
+ @abstractmethod
210
+ def get_client_id_name(self) -> str:
211
+ """The client id name to authenticate"""
212
+
209
213
  @abstractmethod
210
214
  def get_client_id(self) -> str:
211
215
  """The client id to authenticate"""
212
216
 
217
+ @abstractmethod
218
+ def get_client_secret_name(self) -> str:
219
+ """The client secret name to authenticate"""
220
+
213
221
  @abstractmethod
214
222
  def get_client_secret(self) -> str:
215
223
  """The client secret to authenticate"""
216
224
 
225
+ @abstractmethod
226
+ def get_refresh_token_name(self) -> str:
227
+ """The refresh token name to authenticate"""
228
+
217
229
  @abstractmethod
218
230
  def get_refresh_token(self) -> Optional[str]:
219
231
  """The token used to refresh the access token when it expires"""
@@ -246,6 +258,10 @@ class AbstractOauth2Authenticator(AuthBase):
246
258
  def get_grant_type(self) -> str:
247
259
  """Returns grant_type specified for requesting access_token"""
248
260
 
261
+ @abstractmethod
262
+ def get_grant_type_name(self) -> str:
263
+ """Returns grant_type specified name for requesting access_token"""
264
+
249
265
  @property
250
266
  @abstractmethod
251
267
  def access_token(self) -> str:
@@ -30,12 +30,16 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
30
30
  client_id: str,
31
31
  client_secret: str,
32
32
  refresh_token: str,
33
+ client_id_name: str = "client_id",
34
+ client_secret_name: str = "client_secret",
35
+ refresh_token_name: str = "refresh_token",
33
36
  scopes: List[str] | None = None,
34
37
  token_expiry_date: pendulum.DateTime | None = None,
35
38
  token_expiry_date_format: str | None = None,
36
39
  access_token_name: str = "access_token",
37
40
  expires_in_name: str = "expires_in",
38
41
  refresh_request_body: Mapping[str, Any] | None = None,
42
+ grant_type_name: str = "grant_type",
39
43
  grant_type: str = "refresh_token",
40
44
  token_expiry_is_time_of_expiration: bool = False,
41
45
  refresh_token_error_status_codes: Tuple[int, ...] = (),
@@ -43,13 +47,17 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
43
47
  refresh_token_error_values: Tuple[str, ...] = (),
44
48
  ):
45
49
  self._token_refresh_endpoint = token_refresh_endpoint
50
+ self._client_secret_name = client_secret_name
46
51
  self._client_secret = client_secret
52
+ self._client_id_name = client_id_name
47
53
  self._client_id = client_id
54
+ self._refresh_token_name = refresh_token_name
48
55
  self._refresh_token = refresh_token
49
56
  self._scopes = scopes
50
57
  self._access_token_name = access_token_name
51
58
  self._expires_in_name = expires_in_name
52
59
  self._refresh_request_body = refresh_request_body
60
+ self._grant_type_name = grant_type_name
53
61
  self._grant_type = grant_type
54
62
 
55
63
  self._token_expiry_date = token_expiry_date or pendulum.now().subtract(days=1) # type: ignore [no-untyped-call]
@@ -63,12 +71,21 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
63
71
  def get_token_refresh_endpoint(self) -> str:
64
72
  return self._token_refresh_endpoint
65
73
 
74
+ def get_client_id_name(self) -> str:
75
+ return self._client_id_name
76
+
66
77
  def get_client_id(self) -> str:
67
78
  return self._client_id
68
79
 
80
+ def get_client_secret_name(self) -> str:
81
+ return self._client_secret_name
82
+
69
83
  def get_client_secret(self) -> str:
70
84
  return self._client_secret
71
85
 
86
+ def get_refresh_token_name(self) -> str:
87
+ return self._refresh_token_name
88
+
72
89
  def get_refresh_token(self) -> str:
73
90
  return self._refresh_token
74
91
 
@@ -84,6 +101,9 @@ class Oauth2Authenticator(AbstractOauth2Authenticator):
84
101
  def get_refresh_request_body(self) -> Mapping[str, Any]:
85
102
  return self._refresh_request_body # type: ignore [return-value]
86
103
 
104
+ def get_grant_type_name(self) -> str:
105
+ return self._grant_type_name
106
+
87
107
  def get_grant_type(self) -> str:
88
108
  return self._grant_type
89
109
 
@@ -129,8 +149,11 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
129
149
  expires_in_name: str = "expires_in",
130
150
  refresh_token_name: str = "refresh_token",
131
151
  refresh_request_body: Mapping[str, Any] | None = None,
152
+ grant_type_name: str = "grant_type",
132
153
  grant_type: str = "refresh_token",
154
+ client_id_name: str = "client_id",
133
155
  client_id: Optional[str] = None,
156
+ client_secret_name: str = "client_secret",
134
157
  client_secret: Optional[str] = None,
135
158
  access_token_config_path: Sequence[str] = ("credentials", "access_token"),
136
159
  refresh_token_config_path: Sequence[str] = ("credentials", "refresh_token"),
@@ -174,23 +197,30 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
174
197
  ("credentials", "client_secret"),
175
198
  )
176
199
  )
200
+ self._client_id_name = client_id_name
201
+ self._client_secret_name = client_secret_name
177
202
  self._access_token_config_path = access_token_config_path
178
203
  self._refresh_token_config_path = refresh_token_config_path
179
204
  self._token_expiry_date_config_path = token_expiry_date_config_path
180
205
  self._token_expiry_date_format = token_expiry_date_format
181
206
  self._refresh_token_name = refresh_token_name
207
+ self._grant_type_name = grant_type_name
182
208
  self._connector_config = connector_config
183
209
  self.__message_repository = message_repository
184
210
  super().__init__(
185
- token_refresh_endpoint,
186
- self.get_client_id(),
187
- self.get_client_secret(),
188
- self.get_refresh_token(),
211
+ token_refresh_endpoint=token_refresh_endpoint,
212
+ client_id_name=self._client_id_name,
213
+ client_id=self.get_client_id(),
214
+ client_secret_name=self._client_secret_name,
215
+ client_secret=self.get_client_secret(),
216
+ refresh_token=self.get_refresh_token(),
217
+ refresh_token_name=self._refresh_token_name,
189
218
  scopes=scopes,
190
219
  token_expiry_date=self.get_token_expiry_date(),
191
220
  access_token_name=access_token_name,
192
221
  expires_in_name=expires_in_name,
193
222
  refresh_request_body=refresh_request_body,
223
+ grant_type_name=self._grant_type_name,
194
224
  grant_type=grant_type,
195
225
  token_expiry_date_format=token_expiry_date_format,
196
226
  token_expiry_is_time_of_expiration=token_expiry_is_time_of_expiration,
@@ -152,3 +152,6 @@ class StreamSlice(Mapping[str, Any]):
152
152
 
153
153
  def __hash__(self) -> int:
154
154
  return hash(orjson.dumps(self._stream_slice, option=orjson.OPT_SORT_KEYS))
155
+
156
+ def __bool__(self) -> bool:
157
+ return bool(self._stream_slice) or bool(self._extra_fields)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: airbyte-cdk
3
- Version: 6.13.1.dev4107
3
+ Version: 6.13.1.dev4109
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  License: MIT
6
6
  Keywords: airbyte,connector-development-kit,cdk
@@ -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=Yr0ljFjln9FIWudQohXARyKEo6-4ACG840pZoi6JVrE,9165
56
+ airbyte_cdk/sources/declarative/auth/oauth.py,sha256=EDx-tY0ZhBXe6yVHkqjUAqMWJAl4rQXjQbr4rElt_Ds,10555
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,7 +66,7 @@ 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=GfZlk9EvYQiWDx3AipNLf1us1e986q2mgqcbHbeZU0k,133172
69
+ airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=00X3palFmBp9WqQugXgtzFVn7s17KYWKTrn83ObmBzc,134673
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
@@ -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=IZFT1m4d-zp5hQ0ayU06Vdxm6r3MEq-X2sOCo9SuG-k,93270
109
+ airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=1wrAW9XeEq2xdUAAkmHcelka-LOwyYb-izRcACkNPKM,94915
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=CLd2LurUlsJwG3JHtYTCMzAj6UFxPct7m9u8zkdDP3I,109344
114
+ airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=NElLb7eLDVmxDgtTX9fQ-ZPrpfH3d7RpMDaQiLtvuuQ,110550
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
@@ -119,6 +119,7 @@ airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py,sha25
119
119
  airbyte_cdk/sources/declarative/partition_routers/partition_router.py,sha256=YyEIzdmLd1FjbVP3QbQ2VFCLW_P-OGbVh6VpZShp54k,2218
120
120
  airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py,sha256=SKzKjSyfccq4dxGIh-J6ejrgkCHzaiTIazmbmeQiRD4,1942
121
121
  airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py,sha256=5bgXoJfBg_6i53krQMptAGb50XB5XoVfqQxKQhlLtBA,15383
122
+ airbyte_cdk/sources/declarative/requesters/README.md,sha256=WabtHlwHg_J34aL1Kwm8vboYqBaSgsFjq10qR-P2sx8,2658
122
123
  airbyte_cdk/sources/declarative/requesters/__init__.py,sha256=d7a3OoHbqaJDyyPli3nqqJ2yAW_SLX6XDaBAKOwvpxw,364
123
124
  airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py,sha256=SkEDcJxlT1683rNx93K9whoS0OyUukkuOfToGtgpF58,776
124
125
  airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py,sha256=1WZdpFmWL6W_Dko0qjflTaKIWeqt8jHT-D6HcujIp3s,884
@@ -133,7 +134,7 @@ airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.
133
134
  airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py,sha256=q0YkeYUUWO6iErUy0vjqiOkhg8_9d5YcCmtlpXAJJ9E,1314
134
135
  airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py,sha256=Tan66odx8VHzfdyyXMQkXz2pJYksllGqvxmpoajgcK4,669
135
136
  airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py,sha256=vhWsEKNTYEzZ4gerhHqnDNKu4wGIP485NAzpSQ5DRZg,7941
136
- airbyte_cdk/sources/declarative/requesters/http_job_repository.py,sha256=o0520AmHMb7SAoeokVNwoOzuZzIAT6ryx9uFYGSOrs0,8664
137
+ airbyte_cdk/sources/declarative/requesters/http_job_repository.py,sha256=3GtOefPH08evlSUxaILkiKLTHbIspFY4qd5B3ZqNE60,10063
137
138
  airbyte_cdk/sources/declarative/requesters/http_requester.py,sha256=RqYPkgJFAWfcZBTc-JBcGHPm4JL1ZQOhs9GKU4MP2eE,14723
138
139
  airbyte_cdk/sources/declarative/requesters/paginators/__init__.py,sha256=uArbKs9JKNCt7t9tZoeWwjDpyI1HoPp29FNW0JzvaEM,644
139
140
  airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py,sha256=FnSl3qPvv5wD6ieAI2Ic5c4dqBk-3fRe4tCaWzq3YwM,11840
@@ -217,7 +218,7 @@ airbyte_cdk/sources/file_based/file_types/file_transfer.py,sha256=HyGRihJxcb_lEs
217
218
  airbyte_cdk/sources/file_based/file_types/file_type_parser.py,sha256=JgpH21PrbRqwK92BJklZWvh2TndA6xZ-eP1LPMo44oQ,2832
218
219
  airbyte_cdk/sources/file_based/file_types/jsonl_parser.py,sha256=GwyNyxmST4RX-XpXy7xVH0D-znYWWBmGv_pVAu95oHQ,5886
219
220
  airbyte_cdk/sources/file_based/file_types/parquet_parser.py,sha256=XenFg5sJ-UBnIkSmsiNJRou11NO0zZXx-RXgPHMT2NA,10487
220
- airbyte_cdk/sources/file_based/file_types/unstructured_parser.py,sha256=Awxa3_M9MGMolBVnMG4-dxhRDa4G7rwXL5HNe1vgSLY,18936
221
+ airbyte_cdk/sources/file_based/file_types/unstructured_parser.py,sha256=2TYOQl62FQPCa8otLbkDIk_j01EP3oWaKSfXGhCjCHg,19492
221
222
  airbyte_cdk/sources/file_based/remote_file.py,sha256=yqRz93vPe8PBXLIMJ5W5u2JRlZRhg6sBrAjn3pPjJ8A,315
222
223
  airbyte_cdk/sources/file_based/schema_helpers.py,sha256=Cf8FH1bDFP0qCDDfEYir_WjP4exXUnikz8hZ40y1Ek0,9601
223
224
  airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py,sha256=FkByIyEy56x2_awYnxGPqGaOp7zAzpAoRkPZHKySI9M,536
@@ -287,12 +288,12 @@ airbyte_cdk/sources/streams/http/http.py,sha256=JAMpiTdS9HFNOlwayWNvQdxoqs2rpW9w
287
288
  airbyte_cdk/sources/streams/http/http_client.py,sha256=tDE0ROtxjGMVphvsw8INvGMtZ97hIF-v47pZ3jIyiwc,23011
288
289
  airbyte_cdk/sources/streams/http/rate_limiting.py,sha256=IwdjrHKUnU97XO4qONgYRv4YYW51xQ8SJm4WLafXDB8,6351
289
290
  airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py,sha256=RN0D3nOX1xLgwEwKWu6pkGy3XqBFzKSNZ8Lf6umU2eY,413
290
- airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256=sxmrQKAvN8piamssL3xh8KXevTwdaXuLs2O0hNEA5aQ,10635
291
+ airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py,sha256=xX-qKbMVN-OTwNda-B6cVQqnQrNDGBnvavAcSvXK2wU,11179
291
292
  airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py,sha256=Y3n7J-sk5yGjv_OxtY6Z6k0PEsFZmtIRi-x0KCbaHdA,1010
292
- airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py,sha256=ka-bBRWvIv09LmZNYl49p2lK9nd_Tvi2g0lIp3OkU40,14872
293
+ airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py,sha256=wjsp4Xf8u3AnY7ZmTTGfLnfj6ztDBogR5biURkqcwCA,16156
293
294
  airbyte_cdk/sources/streams/http/requests_native_auth/token.py,sha256=h5PTzcdH-RQLeCg7xZ45w_484OPUDSwNWl_iMJQmZoI,2526
294
295
  airbyte_cdk/sources/streams/utils/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
295
- airbyte_cdk/sources/types.py,sha256=WWVigI7ZSoQU2TBCzDsHJtoX4Ima9v--lcLyYwUG_cE,4904
296
+ airbyte_cdk/sources/types.py,sha256=nLPkTpyfGV4E6e99qcBWX4r8C3fE4I8Fvgx2EjvT9ic,5005
296
297
  airbyte_cdk/sources/utils/__init__.py,sha256=TTN6VUxVy6Is8BhYQZR5pxJGQh8yH4duXh4O1TiMiEY,118
297
298
  airbyte_cdk/sources/utils/casing.py,sha256=QC-gV1O4e8DR4-bhdXieUPKm_JamzslVyfABLYYRSXA,256
298
299
  airbyte_cdk/sources/utils/record_helper.py,sha256=jeB0mucudzna7Zvj-pCBbwFrbLJ36SlAWZTh5O4Fb9Y,2168
@@ -342,8 +343,8 @@ airbyte_cdk/utils/slice_hasher.py,sha256=-pHexlNYoWYPnXNH-M7HEbjmeJe9Zk7SJijdQ7d
342
343
  airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
343
344
  airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
344
345
  airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
345
- airbyte_cdk-6.13.1.dev4107.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
346
- airbyte_cdk-6.13.1.dev4107.dist-info/METADATA,sha256=BGbjvWgoTraFwu3tyWJNYBh1VlgIGlKiS_a0RIt5YeI,6008
347
- airbyte_cdk-6.13.1.dev4107.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
348
- airbyte_cdk-6.13.1.dev4107.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
349
- airbyte_cdk-6.13.1.dev4107.dist-info/RECORD,,
346
+ airbyte_cdk-6.13.1.dev4109.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
347
+ airbyte_cdk-6.13.1.dev4109.dist-info/METADATA,sha256=bNfMD2mpLZlEXjIuHgUNfYoUfAsWyTe8PF6635ClwrE,6008
348
+ airbyte_cdk-6.13.1.dev4109.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
349
+ airbyte_cdk-6.13.1.dev4109.dist-info/entry_points.txt,sha256=fj-e3PAQvsxsQzyyq8UkG1k8spunWnD4BAH2AwlR6NM,95
350
+ airbyte_cdk-6.13.1.dev4109.dist-info/RECORD,,