airbyte-cdk 6.5.3rc2__py3-none-any.whl → 6.6.0__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.
Files changed (200) hide show
  1. airbyte_cdk/__init__.py +17 -2
  2. airbyte_cdk/config_observation.py +10 -3
  3. airbyte_cdk/connector.py +19 -9
  4. airbyte_cdk/connector_builder/connector_builder_handler.py +28 -8
  5. airbyte_cdk/connector_builder/main.py +26 -6
  6. airbyte_cdk/connector_builder/message_grouper.py +95 -25
  7. airbyte_cdk/destinations/destination.py +47 -14
  8. airbyte_cdk/destinations/vector_db_based/config.py +36 -14
  9. airbyte_cdk/destinations/vector_db_based/document_processor.py +49 -11
  10. airbyte_cdk/destinations/vector_db_based/embedder.py +52 -11
  11. airbyte_cdk/destinations/vector_db_based/test_utils.py +14 -4
  12. airbyte_cdk/destinations/vector_db_based/utils.py +8 -2
  13. airbyte_cdk/destinations/vector_db_based/writer.py +15 -4
  14. airbyte_cdk/entrypoint.py +82 -26
  15. airbyte_cdk/exception_handler.py +13 -3
  16. airbyte_cdk/logger.py +10 -2
  17. airbyte_cdk/models/airbyte_protocol.py +11 -5
  18. airbyte_cdk/models/airbyte_protocol_serializers.py +9 -3
  19. airbyte_cdk/models/well_known_types.py +1 -1
  20. airbyte_cdk/sources/abstract_source.py +63 -17
  21. airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +47 -14
  22. airbyte_cdk/sources/concurrent_source/concurrent_source.py +25 -7
  23. airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +27 -6
  24. airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +9 -3
  25. airbyte_cdk/sources/connector_state_manager.py +32 -10
  26. airbyte_cdk/sources/declarative/async_job/job.py +3 -1
  27. airbyte_cdk/sources/declarative/async_job/job_orchestrator.py +68 -14
  28. airbyte_cdk/sources/declarative/async_job/job_tracker.py +24 -6
  29. airbyte_cdk/sources/declarative/async_job/repository.py +3 -1
  30. airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +3 -1
  31. airbyte_cdk/sources/declarative/auth/jwt.py +27 -7
  32. airbyte_cdk/sources/declarative/auth/oauth.py +35 -11
  33. airbyte_cdk/sources/declarative/auth/selective_authenticator.py +3 -1
  34. airbyte_cdk/sources/declarative/auth/token.py +25 -8
  35. airbyte_cdk/sources/declarative/checks/check_stream.py +12 -4
  36. airbyte_cdk/sources/declarative/checks/connection_checker.py +3 -1
  37. airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py +11 -3
  38. airbyte_cdk/sources/declarative/concurrent_declarative_source.py +106 -50
  39. airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +20 -6
  40. airbyte_cdk/sources/declarative/declarative_component_schema.yaml +43 -0
  41. airbyte_cdk/sources/declarative/declarative_source.py +3 -1
  42. airbyte_cdk/sources/declarative/declarative_stream.py +27 -6
  43. airbyte_cdk/sources/declarative/decoders/__init__.py +2 -2
  44. airbyte_cdk/sources/declarative/decoders/decoder.py +3 -1
  45. airbyte_cdk/sources/declarative/decoders/json_decoder.py +48 -13
  46. airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py +3 -1
  47. airbyte_cdk/sources/declarative/decoders/xml_decoder.py +6 -2
  48. airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +6 -2
  49. airbyte_cdk/sources/declarative/extractors/record_filter.py +24 -7
  50. airbyte_cdk/sources/declarative/extractors/record_selector.py +10 -3
  51. airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py +15 -5
  52. airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +96 -31
  53. airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py +22 -8
  54. airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py +46 -15
  55. airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py +19 -5
  56. airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py +3 -1
  57. airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +20 -2
  58. airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +5 -1
  59. airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +10 -3
  60. airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +6 -2
  61. airbyte_cdk/sources/declarative/interpolation/interpolation.py +7 -1
  62. airbyte_cdk/sources/declarative/interpolation/jinja.py +6 -2
  63. airbyte_cdk/sources/declarative/interpolation/macros.py +19 -4
  64. airbyte_cdk/sources/declarative/manifest_declarative_source.py +106 -24
  65. airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py +14 -5
  66. airbyte_cdk/sources/declarative/models/declarative_component_schema.py +697 -678
  67. airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +13 -4
  68. airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +9 -2
  69. airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +802 -232
  70. airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py +29 -7
  71. airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +25 -7
  72. airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +54 -15
  73. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +6 -2
  74. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +3 -1
  75. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +17 -5
  76. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +15 -5
  77. airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +3 -1
  78. airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +18 -8
  79. airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py +16 -7
  80. airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +51 -14
  81. airbyte_cdk/sources/declarative/requesters/http_job_repository.py +29 -8
  82. airbyte_cdk/sources/declarative/requesters/http_requester.py +58 -16
  83. airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +49 -14
  84. airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +3 -1
  85. airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +3 -1
  86. airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +17 -5
  87. airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +24 -7
  88. airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +9 -3
  89. airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +3 -1
  90. airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py +6 -2
  91. airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py +19 -6
  92. airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py +3 -1
  93. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +21 -7
  94. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +18 -6
  95. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +27 -8
  96. airbyte_cdk/sources/declarative/requesters/requester.py +3 -1
  97. airbyte_cdk/sources/declarative/retrievers/async_retriever.py +12 -5
  98. airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +105 -24
  99. airbyte_cdk/sources/declarative/schema/default_schema_loader.py +3 -1
  100. airbyte_cdk/sources/declarative/spec/spec.py +8 -2
  101. airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +3 -1
  102. airbyte_cdk/sources/declarative/transformations/add_fields.py +12 -3
  103. airbyte_cdk/sources/declarative/transformations/remove_fields.py +6 -2
  104. airbyte_cdk/sources/declarative/types.py +8 -1
  105. airbyte_cdk/sources/declarative/yaml_declarative_source.py +3 -1
  106. airbyte_cdk/sources/embedded/base_integration.py +14 -4
  107. airbyte_cdk/sources/embedded/catalog.py +16 -4
  108. airbyte_cdk/sources/embedded/runner.py +19 -3
  109. airbyte_cdk/sources/embedded/tools.py +3 -1
  110. airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py +12 -4
  111. airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py +27 -7
  112. airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +12 -6
  113. airbyte_cdk/sources/file_based/config/csv_format.py +21 -9
  114. airbyte_cdk/sources/file_based/config/file_based_stream_config.py +6 -2
  115. airbyte_cdk/sources/file_based/config/unstructured_format.py +10 -3
  116. airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py +2 -4
  117. airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py +7 -2
  118. airbyte_cdk/sources/file_based/exceptions.py +13 -15
  119. airbyte_cdk/sources/file_based/file_based_source.py +82 -24
  120. airbyte_cdk/sources/file_based/file_based_stream_reader.py +16 -5
  121. airbyte_cdk/sources/file_based/file_types/avro_parser.py +58 -17
  122. airbyte_cdk/sources/file_based/file_types/csv_parser.py +89 -26
  123. airbyte_cdk/sources/file_based/file_types/excel_parser.py +25 -7
  124. airbyte_cdk/sources/file_based/file_types/file_transfer.py +8 -2
  125. airbyte_cdk/sources/file_based/file_types/file_type_parser.py +4 -1
  126. airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +20 -6
  127. airbyte_cdk/sources/file_based/file_types/parquet_parser.py +57 -16
  128. airbyte_cdk/sources/file_based/file_types/unstructured_parser.py +64 -15
  129. airbyte_cdk/sources/file_based/schema_helpers.py +33 -10
  130. airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +3 -1
  131. airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +16 -5
  132. airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +33 -10
  133. airbyte_cdk/sources/file_based/stream/concurrent/adapters.py +47 -11
  134. airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py +13 -22
  135. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py +53 -17
  136. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py +17 -5
  137. airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py +3 -1
  138. airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +26 -9
  139. airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +67 -21
  140. airbyte_cdk/sources/http_logger.py +5 -1
  141. airbyte_cdk/sources/message/repository.py +18 -4
  142. airbyte_cdk/sources/source.py +17 -7
  143. airbyte_cdk/sources/streams/availability_strategy.py +9 -3
  144. airbyte_cdk/sources/streams/call_rate.py +63 -19
  145. airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py +31 -7
  146. airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py +6 -2
  147. airbyte_cdk/sources/streams/concurrent/adapters.py +77 -22
  148. airbyte_cdk/sources/streams/concurrent/cursor.py +56 -20
  149. airbyte_cdk/sources/streams/concurrent/default_stream.py +9 -2
  150. airbyte_cdk/sources/streams/concurrent/helpers.py +6 -2
  151. airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +9 -2
  152. airbyte_cdk/sources/streams/concurrent/partition_reader.py +4 -1
  153. airbyte_cdk/sources/streams/concurrent/partitions/record.py +10 -2
  154. airbyte_cdk/sources/streams/concurrent/partitions/types.py +6 -2
  155. airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py +25 -10
  156. airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py +32 -16
  157. airbyte_cdk/sources/streams/core.py +77 -22
  158. airbyte_cdk/sources/streams/http/availability_strategy.py +3 -1
  159. airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py +4 -1
  160. airbyte_cdk/sources/streams/http/error_handlers/error_handler.py +3 -1
  161. airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py +16 -5
  162. airbyte_cdk/sources/streams/http/error_handlers/response_models.py +9 -3
  163. airbyte_cdk/sources/streams/http/exceptions.py +2 -2
  164. airbyte_cdk/sources/streams/http/http.py +133 -33
  165. airbyte_cdk/sources/streams/http/http_client.py +91 -29
  166. airbyte_cdk/sources/streams/http/rate_limiting.py +23 -7
  167. airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +19 -6
  168. airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +38 -11
  169. airbyte_cdk/sources/streams/http/requests_native_auth/token.py +13 -3
  170. airbyte_cdk/sources/types.py +5 -1
  171. airbyte_cdk/sources/utils/record_helper.py +12 -3
  172. airbyte_cdk/sources/utils/schema_helpers.py +9 -3
  173. airbyte_cdk/sources/utils/slice_logger.py +4 -1
  174. airbyte_cdk/sources/utils/transform.py +24 -9
  175. airbyte_cdk/sql/exceptions.py +19 -6
  176. airbyte_cdk/sql/secrets.py +3 -1
  177. airbyte_cdk/sql/shared/catalog_providers.py +13 -4
  178. airbyte_cdk/sql/shared/sql_processor.py +44 -14
  179. airbyte_cdk/test/catalog_builder.py +19 -8
  180. airbyte_cdk/test/entrypoint_wrapper.py +27 -8
  181. airbyte_cdk/test/mock_http/mocker.py +41 -11
  182. airbyte_cdk/test/mock_http/request.py +9 -3
  183. airbyte_cdk/test/mock_http/response.py +3 -1
  184. airbyte_cdk/test/mock_http/response_builder.py +29 -7
  185. airbyte_cdk/test/state_builder.py +10 -2
  186. airbyte_cdk/test/utils/data.py +6 -2
  187. airbyte_cdk/test/utils/http_mocking.py +3 -1
  188. airbyte_cdk/utils/airbyte_secrets_utils.py +3 -1
  189. airbyte_cdk/utils/analytics_message.py +10 -2
  190. airbyte_cdk/utils/datetime_format_inferrer.py +4 -1
  191. airbyte_cdk/utils/mapping_helpers.py +3 -1
  192. airbyte_cdk/utils/message_utils.py +11 -4
  193. airbyte_cdk/utils/print_buffer.py +6 -1
  194. airbyte_cdk/utils/schema_inferrer.py +30 -9
  195. airbyte_cdk/utils/spec_schema_transformations.py +3 -1
  196. airbyte_cdk/utils/traced_exception.py +35 -9
  197. {airbyte_cdk-6.5.3rc2.dist-info → airbyte_cdk-6.6.0.dist-info}/METADATA +8 -7
  198. {airbyte_cdk-6.5.3rc2.dist-info → airbyte_cdk-6.6.0.dist-info}/RECORD +200 -200
  199. {airbyte_cdk-6.5.3rc2.dist-info → airbyte_cdk-6.6.0.dist-info}/LICENSE.txt +0 -0
  200. {airbyte_cdk-6.5.3rc2.dist-info → airbyte_cdk-6.6.0.dist-info}/WHEEL +0 -0
@@ -12,8 +12,13 @@ from airbyte_cdk.models import FailureType, Type
12
12
  from airbyte_cdk.sources.declarative.async_job.job import AsyncJob
13
13
  from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository
14
14
  from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus
15
- from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor, RecordExtractor
16
- from airbyte_cdk.sources.declarative.extractors.response_to_file_extractor import ResponseToFileExtractor
15
+ from airbyte_cdk.sources.declarative.extractors.dpath_extractor import (
16
+ DpathExtractor,
17
+ RecordExtractor,
18
+ )
19
+ from airbyte_cdk.sources.declarative.extractors.response_to_file_extractor import (
20
+ ResponseToFileExtractor,
21
+ )
17
22
  from airbyte_cdk.sources.declarative.requesters.requester import Requester
18
23
  from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever
19
24
  from airbyte_cdk.sources.types import Record, StreamSlice
@@ -35,7 +40,9 @@ class AsyncHttpJobRepository(AsyncJobRepository):
35
40
  urls_extractor: DpathExtractor
36
41
 
37
42
  job_timeout: Optional[timedelta] = None
38
- record_extractor: RecordExtractor = field(init=False, repr=False, default_factory=lambda: ResponseToFileExtractor())
43
+ record_extractor: RecordExtractor = field(
44
+ init=False, repr=False, default_factory=lambda: ResponseToFileExtractor()
45
+ )
39
46
 
40
47
  def __post_init__(self) -> None:
41
48
  self._create_job_response_by_id: Dict[str, Response] = {}
@@ -55,7 +62,9 @@ class AsyncHttpJobRepository(AsyncJobRepository):
55
62
  AirbyteTracedException: If the polling request returns an empty response.
56
63
  """
57
64
 
58
- polling_response: Optional[requests.Response] = self.polling_requester.send_request(stream_slice=stream_slice)
65
+ polling_response: Optional[requests.Response] = self.polling_requester.send_request(
66
+ stream_slice=stream_slice
67
+ )
59
68
  if polling_response is None:
60
69
  raise AirbyteTracedException(
61
70
  internal_message="Polling Requester received an empty Response.",
@@ -100,7 +109,9 @@ class AsyncHttpJobRepository(AsyncJobRepository):
100
109
  AirbyteTracedException: If no response is received from the creation requester.
101
110
  """
102
111
 
103
- response: Optional[requests.Response] = self.creation_requester.send_request(stream_slice=stream_slice)
112
+ response: Optional[requests.Response] = self.creation_requester.send_request(
113
+ stream_slice=stream_slice
114
+ )
104
115
  if not response:
105
116
  raise AirbyteTracedException(
106
117
  internal_message="Always expect a response or an exception from creation_requester",
@@ -146,9 +157,17 @@ class AsyncHttpJobRepository(AsyncJobRepository):
146
157
  job_status: AsyncJobStatus = self._get_validated_job_status(polling_response)
147
158
 
148
159
  if job_status != job.status():
149
- lazy_log(LOGGER, logging.DEBUG, lambda: f"Status of job {job.api_job_id()} changed from {job.status()} to {job_status}")
160
+ lazy_log(
161
+ LOGGER,
162
+ logging.DEBUG,
163
+ lambda: f"Status of job {job.api_job_id()} changed from {job.status()} to {job_status}",
164
+ )
150
165
  else:
151
- lazy_log(LOGGER, logging.DEBUG, lambda: f"Status of job {job.api_job_id()} is still {job.status()}")
166
+ lazy_log(
167
+ LOGGER,
168
+ logging.DEBUG,
169
+ lambda: f"Status of job {job.api_job_id()} is still {job.status()}",
170
+ )
152
171
 
153
172
  job.update_status(job_status)
154
173
  if job_status == AsyncJobStatus.COMPLETED:
@@ -166,7 +185,9 @@ class AsyncHttpJobRepository(AsyncJobRepository):
166
185
 
167
186
  """
168
187
 
169
- for url in self.urls_extractor.extract_records(self._polling_job_response_by_id[job.api_job_id()]):
188
+ for url in self.urls_extractor.extract_records(
189
+ self._polling_job_response_by_id[job.api_job_id()]
190
+ ):
170
191
  stream_slice: StreamSlice = StreamSlice(partition={"url": url}, cursor_slice={})
171
192
  for message in self.download_retriever.read_records({}, stream_slice):
172
193
  if isinstance(message, Record):
@@ -9,7 +9,10 @@ from typing import Any, Callable, Mapping, MutableMapping, Optional, Union
9
9
  from urllib.parse import urljoin
10
10
 
11
11
  import requests
12
- from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator, NoAuth
12
+ from airbyte_cdk.sources.declarative.auth.declarative_authenticator import (
13
+ DeclarativeAuthenticator,
14
+ NoAuth,
15
+ )
13
16
  from airbyte_cdk.sources.declarative.decoders import Decoder
14
17
  from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder
15
18
  from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
@@ -62,13 +65,19 @@ class HttpRequester(Requester):
62
65
  self._url_base = InterpolatedString.create(self.url_base, parameters=parameters)
63
66
  self._path = InterpolatedString.create(self.path, parameters=parameters)
64
67
  if self.request_options_provider is None:
65
- self._request_options_provider = InterpolatedRequestOptionsProvider(config=self.config, parameters=parameters)
68
+ self._request_options_provider = InterpolatedRequestOptionsProvider(
69
+ config=self.config, parameters=parameters
70
+ )
66
71
  elif isinstance(self.request_options_provider, dict):
67
- self._request_options_provider = InterpolatedRequestOptionsProvider(config=self.config, **self.request_options_provider)
72
+ self._request_options_provider = InterpolatedRequestOptionsProvider(
73
+ config=self.config, **self.request_options_provider
74
+ )
68
75
  else:
69
76
  self._request_options_provider = self.request_options_provider
70
77
  self._authenticator = self.authenticator or NoAuth(parameters=parameters)
71
- self._http_method = HttpMethod[self.http_method] if isinstance(self.http_method, str) else self.http_method
78
+ self._http_method = (
79
+ HttpMethod[self.http_method] if isinstance(self.http_method, str) else self.http_method
80
+ )
72
81
  self.error_handler = self.error_handler
73
82
  self._parameters = parameters
74
83
 
@@ -103,9 +112,17 @@ class HttpRequester(Requester):
103
112
  return os.path.join(self._url_base.eval(self.config), "")
104
113
 
105
114
  def get_path(
106
- self, *, stream_state: Optional[StreamState], stream_slice: Optional[StreamSlice], next_page_token: Optional[Mapping[str, Any]]
115
+ self,
116
+ *,
117
+ stream_state: Optional[StreamState],
118
+ stream_slice: Optional[StreamSlice],
119
+ next_page_token: Optional[Mapping[str, Any]],
107
120
  ) -> str:
108
- kwargs = {"stream_state": stream_state, "stream_slice": stream_slice, "next_page_token": next_page_token}
121
+ kwargs = {
122
+ "stream_state": stream_state,
123
+ "stream_slice": stream_slice,
124
+ "next_page_token": next_page_token,
125
+ }
109
126
  path = str(self._path.eval(self.config, **kwargs))
110
127
  return path.lstrip("/")
111
128
 
@@ -144,7 +161,9 @@ class HttpRequester(Requester):
144
161
  ) -> Union[Mapping[str, Any], str]:
145
162
  return (
146
163
  self._request_options_provider.get_request_body_data(
147
- stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token
164
+ stream_state=stream_state,
165
+ stream_slice=stream_slice,
166
+ next_page_token=next_page_token,
148
167
  )
149
168
  or {}
150
169
  )
@@ -181,7 +200,11 @@ class HttpRequester(Requester):
181
200
  """
182
201
  return combine_mappings(
183
202
  [
184
- requester_method(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token),
203
+ requester_method(
204
+ stream_state=stream_state,
205
+ stream_slice=stream_slice,
206
+ next_page_token=next_page_token,
207
+ ),
185
208
  auth_options_method(),
186
209
  extra_options,
187
210
  ]
@@ -223,14 +246,21 @@ class HttpRequester(Requester):
223
246
  E.g: you might want to define query parameters for paging if next_page_token is not None.
224
247
  """
225
248
  options = self._get_request_options(
226
- stream_state, stream_slice, next_page_token, self.get_request_params, self.get_authenticator().get_request_params, extra_params
249
+ stream_state,
250
+ stream_slice,
251
+ next_page_token,
252
+ self.get_request_params,
253
+ self.get_authenticator().get_request_params,
254
+ extra_params,
227
255
  )
228
256
  if isinstance(options, str):
229
257
  raise ValueError("Request params cannot be a string")
230
258
 
231
259
  for k, v in options.items():
232
260
  if isinstance(v, (dict,)):
233
- raise ValueError(f"Invalid value for `{k}` parameter. The values of request params cannot be an object.")
261
+ raise ValueError(
262
+ f"Invalid value for `{k}` parameter. The values of request params cannot be an object."
263
+ )
234
264
 
235
265
  return options
236
266
 
@@ -301,18 +331,30 @@ class HttpRequester(Requester):
301
331
  request_body_json: Optional[Mapping[str, Any]] = None,
302
332
  log_formatter: Optional[Callable[[requests.Response], Any]] = None,
303
333
  ) -> Optional[requests.Response]:
304
-
305
334
  request, response = self._http_client.send_request(
306
335
  http_method=self.get_method().value,
307
336
  url=self._join_url(
308
337
  self.get_url_base(),
309
- path or self.get_path(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token),
338
+ path
339
+ or self.get_path(
340
+ stream_state=stream_state,
341
+ stream_slice=stream_slice,
342
+ next_page_token=next_page_token,
343
+ ),
310
344
  ),
311
345
  request_kwargs={"stream": self.stream_response},
312
- headers=self._request_headers(stream_state, stream_slice, next_page_token, request_headers),
313
- params=self._request_params(stream_state, stream_slice, next_page_token, request_params),
314
- json=self._request_body_json(stream_state, stream_slice, next_page_token, request_body_json),
315
- data=self._request_body_data(stream_state, stream_slice, next_page_token, request_body_data),
346
+ headers=self._request_headers(
347
+ stream_state, stream_slice, next_page_token, request_headers
348
+ ),
349
+ params=self._request_params(
350
+ stream_state, stream_slice, next_page_token, request_params
351
+ ),
352
+ json=self._request_body_json(
353
+ stream_state, stream_slice, next_page_token, request_body_json
354
+ ),
355
+ data=self._request_body_data(
356
+ stream_state, stream_slice, next_page_token, request_body_data
357
+ ),
316
358
  dedupe_query_params=True,
317
359
  log_formatter=log_formatter,
318
360
  exit_on_rate_limit=self._exit_on_rate_limit,
@@ -6,11 +6,20 @@ from dataclasses import InitVar, dataclass, field
6
6
  from typing import Any, Mapping, MutableMapping, Optional, Union
7
7
 
8
8
  import requests
9
- from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder, PaginationDecoderDecorator
9
+ from airbyte_cdk.sources.declarative.decoders import (
10
+ Decoder,
11
+ JsonDecoder,
12
+ PaginationDecoderDecorator,
13
+ )
10
14
  from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
11
15
  from airbyte_cdk.sources.declarative.requesters.paginators.paginator import Paginator
12
- from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy
13
- from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType
16
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
17
+ PaginationStrategy,
18
+ )
19
+ from airbyte_cdk.sources.declarative.requesters.request_option import (
20
+ RequestOption,
21
+ RequestOptionType,
22
+ )
14
23
  from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath
15
24
  from airbyte_cdk.sources.types import Config, Record, StreamSlice, StreamState
16
25
 
@@ -89,13 +98,17 @@ class DefaultPaginator(Paginator):
89
98
  config: Config
90
99
  url_base: Union[InterpolatedString, str]
91
100
  parameters: InitVar[Mapping[str, Any]]
92
- decoder: Decoder = field(default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={})))
101
+ decoder: Decoder = field(
102
+ default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))
103
+ )
93
104
  page_size_option: Optional[RequestOption] = None
94
105
  page_token_option: Optional[Union[RequestPath, RequestOption]] = None
95
106
 
96
107
  def __post_init__(self, parameters: Mapping[str, Any]) -> None:
97
108
  if self.page_size_option and not self.pagination_strategy.get_page_size():
98
- raise ValueError("page_size_option cannot be set if the pagination strategy does not have a page_size")
109
+ raise ValueError(
110
+ "page_size_option cannot be set if the pagination strategy does not have a page_size"
111
+ )
99
112
  if isinstance(self.url_base, str):
100
113
  self.url_base = InterpolatedString(string=self.url_base, parameters=parameters)
101
114
  self._token: Optional[Any] = self.pagination_strategy.initial_token
@@ -103,14 +116,20 @@ class DefaultPaginator(Paginator):
103
116
  def next_page_token(
104
117
  self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
105
118
  ) -> Optional[Mapping[str, Any]]:
106
- self._token = self.pagination_strategy.next_page_token(response, last_page_size, last_record)
119
+ self._token = self.pagination_strategy.next_page_token(
120
+ response, last_page_size, last_record
121
+ )
107
122
  if self._token:
108
123
  return {"next_page_token": self._token}
109
124
  else:
110
125
  return None
111
126
 
112
127
  def path(self) -> Optional[str]:
113
- if self._token and self.page_token_option and isinstance(self.page_token_option, RequestPath):
128
+ if (
129
+ self._token
130
+ and self.page_token_option
131
+ and isinstance(self.page_token_option, RequestPath)
132
+ ):
114
133
  # Replace url base to only return the path
115
134
  return str(self._token).replace(self.url_base.eval(self.config), "") # type: ignore # url_base is casted to a InterpolatedString in __post_init__
116
135
  else:
@@ -169,8 +188,14 @@ class DefaultPaginator(Paginator):
169
188
  and self.page_token_option.inject_into == option_type
170
189
  ):
171
190
  options[self.page_token_option.field_name.eval(config=self.config)] = self._token # type: ignore # field_name is always cast to an interpolated string
172
- if self.page_size_option and self.pagination_strategy.get_page_size() and self.page_size_option.inject_into == option_type:
173
- options[self.page_size_option.field_name.eval(config=self.config)] = self.pagination_strategy.get_page_size() # type: ignore # field_name is always cast to an interpolated string
191
+ if (
192
+ self.page_size_option
193
+ and self.pagination_strategy.get_page_size()
194
+ and self.page_size_option.inject_into == option_type
195
+ ):
196
+ options[self.page_size_option.field_name.eval(config=self.config)] = (
197
+ self.pagination_strategy.get_page_size()
198
+ ) # type: ignore # field_name is always cast to an interpolated string
174
199
  return options
175
200
 
176
201
 
@@ -184,7 +209,9 @@ class PaginatorTestReadDecorator(Paginator):
184
209
 
185
210
  def __init__(self, decorated: Paginator, maximum_number_of_pages: int = 5) -> None:
186
211
  if maximum_number_of_pages and maximum_number_of_pages < 1:
187
- raise ValueError(f"The maximum number of pages on a test read needs to be strictly positive. Got {maximum_number_of_pages}")
212
+ raise ValueError(
213
+ f"The maximum number of pages on a test read needs to be strictly positive. Got {maximum_number_of_pages}"
214
+ )
188
215
  self._maximum_number_of_pages = maximum_number_of_pages
189
216
  self._decorated = decorated
190
217
  self._page_count = self._PAGE_COUNT_BEFORE_FIRST_NEXT_CALL
@@ -208,7 +235,9 @@ class PaginatorTestReadDecorator(Paginator):
208
235
  stream_slice: Optional[StreamSlice] = None,
209
236
  next_page_token: Optional[Mapping[str, Any]] = None,
210
237
  ) -> Mapping[str, Any]:
211
- return self._decorated.get_request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token)
238
+ return self._decorated.get_request_params(
239
+ stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token
240
+ )
212
241
 
213
242
  def get_request_headers(
214
243
  self,
@@ -217,7 +246,9 @@ class PaginatorTestReadDecorator(Paginator):
217
246
  stream_slice: Optional[StreamSlice] = None,
218
247
  next_page_token: Optional[Mapping[str, Any]] = None,
219
248
  ) -> Mapping[str, str]:
220
- return self._decorated.get_request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token)
249
+ return self._decorated.get_request_headers(
250
+ stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token
251
+ )
221
252
 
222
253
  def get_request_body_data(
223
254
  self,
@@ -226,7 +257,9 @@ class PaginatorTestReadDecorator(Paginator):
226
257
  stream_slice: Optional[StreamSlice] = None,
227
258
  next_page_token: Optional[Mapping[str, Any]] = None,
228
259
  ) -> Union[Mapping[str, Any], str]:
229
- return self._decorated.get_request_body_data(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token)
260
+ return self._decorated.get_request_body_data(
261
+ stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token
262
+ )
230
263
 
231
264
  def get_request_body_json(
232
265
  self,
@@ -235,7 +268,9 @@ class PaginatorTestReadDecorator(Paginator):
235
268
  stream_slice: Optional[StreamSlice] = None,
236
269
  next_page_token: Optional[Mapping[str, Any]] = None,
237
270
  ) -> Mapping[str, Any]:
238
- return self._decorated.get_request_body_json(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token)
271
+ return self._decorated.get_request_body_json(
272
+ stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token
273
+ )
239
274
 
240
275
  def reset(self, reset_value: Optional[Any] = None) -> None:
241
276
  self._decorated.reset()
@@ -57,7 +57,9 @@ class NoPagination(Paginator):
57
57
  ) -> Mapping[str, Any]:
58
58
  return {}
59
59
 
60
- def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Mapping[str, Any]:
60
+ def next_page_token(
61
+ self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
62
+ ) -> Mapping[str, Any]:
61
63
  return {}
62
64
 
63
65
  def reset(self, reset_value: Optional[Any] = None) -> None:
@@ -7,7 +7,9 @@ from dataclasses import dataclass
7
7
  from typing import Any, Mapping, Optional
8
8
 
9
9
  import requests
10
- from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider
10
+ from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
11
+ RequestOptionsProvider,
12
+ )
11
13
  from airbyte_cdk.sources.types import Record
12
14
 
13
15
 
@@ -6,10 +6,16 @@ from dataclasses import InitVar, dataclass, field
6
6
  from typing import Any, Dict, Mapping, Optional, Union
7
7
 
8
8
  import requests
9
- from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder, PaginationDecoderDecorator
9
+ from airbyte_cdk.sources.declarative.decoders import (
10
+ Decoder,
11
+ JsonDecoder,
12
+ PaginationDecoderDecorator,
13
+ )
10
14
  from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean
11
15
  from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
12
- from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy
16
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
17
+ PaginationStrategy,
18
+ )
13
19
  from airbyte_cdk.sources.types import Config, Record
14
20
 
15
21
 
@@ -31,7 +37,9 @@ class CursorPaginationStrategy(PaginationStrategy):
31
37
  parameters: InitVar[Mapping[str, Any]]
32
38
  page_size: Optional[int] = None
33
39
  stop_condition: Optional[Union[InterpolatedBoolean, str]] = None
34
- decoder: Decoder = field(default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={})))
40
+ decoder: Decoder = field(
41
+ default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))
42
+ )
35
43
 
36
44
  def __post_init__(self, parameters: Mapping[str, Any]) -> None:
37
45
  self._initial_cursor = None
@@ -40,7 +48,9 @@ class CursorPaginationStrategy(PaginationStrategy):
40
48
  else:
41
49
  self._cursor_value = self.cursor_value
42
50
  if isinstance(self.stop_condition, str):
43
- self._stop_condition: Optional[InterpolatedBoolean] = InterpolatedBoolean(condition=self.stop_condition, parameters=parameters)
51
+ self._stop_condition: Optional[InterpolatedBoolean] = InterpolatedBoolean(
52
+ condition=self.stop_condition, parameters=parameters
53
+ )
44
54
  else:
45
55
  self._stop_condition = self.stop_condition
46
56
 
@@ -48,7 +58,9 @@ class CursorPaginationStrategy(PaginationStrategy):
48
58
  def initial_token(self) -> Optional[Any]:
49
59
  return self._initial_cursor
50
60
 
51
- def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]:
61
+ def next_page_token(
62
+ self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
63
+ ) -> Optional[Any]:
52
64
  decoded_response = next(self.decoder.decode(response))
53
65
 
54
66
  # The default way that link is presented in requests.Response is a string of various links (last, next, etc). This
@@ -6,9 +6,15 @@ from dataclasses import InitVar, dataclass, field
6
6
  from typing import Any, Mapping, Optional, Union
7
7
 
8
8
  import requests
9
- from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder, PaginationDecoderDecorator
9
+ from airbyte_cdk.sources.declarative.decoders import (
10
+ Decoder,
11
+ JsonDecoder,
12
+ PaginationDecoderDecorator,
13
+ )
10
14
  from airbyte_cdk.sources.declarative.interpolation import InterpolatedString
11
- from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy
15
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
16
+ PaginationStrategy,
17
+ )
12
18
  from airbyte_cdk.sources.types import Config, Record
13
19
 
14
20
 
@@ -39,14 +45,18 @@ class OffsetIncrement(PaginationStrategy):
39
45
  config: Config
40
46
  page_size: Optional[Union[str, int]]
41
47
  parameters: InitVar[Mapping[str, Any]]
42
- decoder: Decoder = field(default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={})))
48
+ decoder: Decoder = field(
49
+ default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))
50
+ )
43
51
  inject_on_first_request: bool = False
44
52
 
45
53
  def __post_init__(self, parameters: Mapping[str, Any]) -> None:
46
54
  self._offset = 0
47
55
  page_size = str(self.page_size) if isinstance(self.page_size, int) else self.page_size
48
56
  if page_size:
49
- self._page_size: Optional[InterpolatedString] = InterpolatedString(page_size, parameters=parameters)
57
+ self._page_size: Optional[InterpolatedString] = InterpolatedString(
58
+ page_size, parameters=parameters
59
+ )
50
60
  else:
51
61
  self._page_size = None
52
62
 
@@ -56,11 +66,16 @@ class OffsetIncrement(PaginationStrategy):
56
66
  return self._offset
57
67
  return None
58
68
 
59
- def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]:
69
+ def next_page_token(
70
+ self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
71
+ ) -> Optional[Any]:
60
72
  decoded_response = next(self.decoder.decode(response))
61
73
 
62
74
  # Stop paginating when there are fewer records than the page size or the current page has no records
63
- if (self._page_size and last_page_size < self._page_size.eval(self.config, response=decoded_response)) or last_page_size == 0:
75
+ if (
76
+ self._page_size
77
+ and last_page_size < self._page_size.eval(self.config, response=decoded_response)
78
+ ) or last_page_size == 0:
64
79
  return None
65
80
  else:
66
81
  self._offset += last_page_size
@@ -68,7 +83,9 @@ class OffsetIncrement(PaginationStrategy):
68
83
 
69
84
  def reset(self, reset_value: Optional[Any] = 0) -> None:
70
85
  if not isinstance(reset_value, int):
71
- raise ValueError(f"Reset value {reset_value} for OffsetIncrement pagination strategy was not an integer")
86
+ raise ValueError(
87
+ f"Reset value {reset_value} for OffsetIncrement pagination strategy was not an integer"
88
+ )
72
89
  else:
73
90
  self._offset = reset_value
74
91
 
@@ -7,7 +7,9 @@ from typing import Any, Mapping, Optional, Union
7
7
 
8
8
  import requests
9
9
  from airbyte_cdk.sources.declarative.interpolation import InterpolatedString
10
- from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy
10
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
11
+ PaginationStrategy,
12
+ )
11
13
  from airbyte_cdk.sources.types import Config, Record
12
14
 
13
15
 
@@ -43,7 +45,9 @@ class PageIncrement(PaginationStrategy):
43
45
  return self._page
44
46
  return None
45
47
 
46
- def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]:
48
+ def next_page_token(
49
+ self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
50
+ ) -> Optional[Any]:
47
51
  # Stop paginating when there are fewer records than the page size or the current page has no records
48
52
  if (self._page_size and last_page_size < self._page_size) or last_page_size == 0:
49
53
  return None
@@ -55,7 +59,9 @@ class PageIncrement(PaginationStrategy):
55
59
  if reset_value is None:
56
60
  self._page = self.start_from_page
57
61
  elif not isinstance(reset_value, int):
58
- raise ValueError(f"Reset value {reset_value} for PageIncrement pagination strategy was not an integer")
62
+ raise ValueError(
63
+ f"Reset value {reset_value} for PageIncrement pagination strategy was not an integer"
64
+ )
59
65
  else:
60
66
  self._page = reset_value
61
67
 
@@ -24,7 +24,9 @@ class PaginationStrategy:
24
24
  """
25
25
 
26
26
  @abstractmethod
27
- def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]:
27
+ def next_page_token(
28
+ self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
29
+ ) -> Optional[Any]:
28
30
  """
29
31
  :param response: response to process
30
32
  :param last_page_size: the number of records read from the response
@@ -7,7 +7,9 @@ from typing import Any, Optional
7
7
 
8
8
  import requests
9
9
  from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor
10
- from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy
10
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
11
+ PaginationStrategy,
12
+ )
11
13
  from airbyte_cdk.sources.types import Record
12
14
 
13
15
 
@@ -35,7 +37,9 @@ class StopConditionPaginationStrategyDecorator(PaginationStrategy):
35
37
  self._delegate = _delegate
36
38
  self._stop_condition = stop_condition
37
39
 
38
- def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]:
40
+ def next_page_token(
41
+ self, response: requests.Response, last_page_size: int, last_record: Optional[Record]
42
+ ) -> Optional[Any]:
39
43
  # We evaluate in reverse order because the assumption is that most of the APIs using data feed structure will return records in
40
44
  # descending order. In terms of performance/memory, we return the records lazily
41
45
  if last_record and self._stop_condition.is_met(last_record):
@@ -6,8 +6,13 @@ from dataclasses import InitVar, dataclass
6
6
  from typing import Any, Mapping, MutableMapping, Optional, Union
7
7
 
8
8
  from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
9
- from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType
10
- from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider
9
+ from airbyte_cdk.sources.declarative.requesters.request_option import (
10
+ RequestOption,
11
+ RequestOptionType,
12
+ )
13
+ from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
14
+ RequestOptionsProvider,
15
+ )
11
16
  from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
12
17
 
13
18
 
@@ -26,8 +31,12 @@ class DatetimeBasedRequestOptionsProvider(RequestOptionsProvider):
26
31
  partition_field_end: Optional[str] = None
27
32
 
28
33
  def __post_init__(self, parameters: Mapping[str, Any]) -> None:
29
- self._partition_field_start = InterpolatedString.create(self.partition_field_start or "start_time", parameters=parameters)
30
- self._partition_field_end = InterpolatedString.create(self.partition_field_end or "end_time", parameters=parameters)
34
+ self._partition_field_start = InterpolatedString.create(
35
+ self.partition_field_start or "start_time", parameters=parameters
36
+ )
37
+ self._partition_field_end = InterpolatedString.create(
38
+ self.partition_field_end or "end_time", parameters=parameters
39
+ )
31
40
 
32
41
  def get_request_params(
33
42
  self,
@@ -65,7 +74,9 @@ class DatetimeBasedRequestOptionsProvider(RequestOptionsProvider):
65
74
  ) -> Mapping[str, Any]:
66
75
  return self._get_request_options(RequestOptionType.body_json, stream_slice)
67
76
 
68
- def _get_request_options(self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]) -> Mapping[str, Any]:
77
+ def _get_request_options(
78
+ self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]
79
+ ) -> Mapping[str, Any]:
69
80
  options: MutableMapping[str, Any] = {}
70
81
  if not stream_slice:
71
82
  return options
@@ -74,5 +85,7 @@ class DatetimeBasedRequestOptionsProvider(RequestOptionsProvider):
74
85
  self._partition_field_start.eval(self.config)
75
86
  )
76
87
  if self.end_time_option and self.end_time_option.inject_into == option_type:
77
- options[self.end_time_option.field_name.eval(config=self.config)] = stream_slice.get(self._partition_field_end.eval(self.config)) # type: ignore # field_name is always casted to an interpolated string
88
+ options[self.end_time_option.field_name.eval(config=self.config)] = stream_slice.get(
89
+ self._partition_field_end.eval(self.config)
90
+ ) # type: ignore # field_name is always casted to an interpolated string
78
91
  return options
@@ -5,7 +5,9 @@
5
5
  from dataclasses import InitVar, dataclass
6
6
  from typing import Any, Mapping, Optional, Union
7
7
 
8
- from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider
8
+ from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
9
+ RequestOptionsProvider,
10
+ )
9
11
  from airbyte_cdk.sources.types import StreamSlice, StreamState
10
12
 
11
13