airbyte-cdk 0.50.0__tar.gz → 0.50.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (369) hide show
  1. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/PKG-INFO +1 -1
  2. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/entrypoint.py +7 -0
  3. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/declarative_component_schema.yaml +3 -3
  4. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/models/declarative_component_schema.py +3 -3
  5. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py +9 -9
  6. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/csv_format.py +42 -6
  7. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_based_source.py +4 -5
  8. airbyte-cdk-0.50.2/airbyte_cdk/sources/file_based/file_types/csv_parser.py +237 -0
  9. airbyte-cdk-0.50.2/airbyte_cdk/sources/file_based/stream/cursor/__init__.py +4 -0
  10. airbyte-cdk-0.50.0/airbyte_cdk/sources/file_based/stream/cursor/file_based_cursor.py → airbyte-cdk-0.50.2/airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py +9 -1
  11. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +10 -10
  12. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +15 -2
  13. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk.egg-info/PKG-INFO +1 -1
  14. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk.egg-info/SOURCES.txt +2 -1
  15. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/setup.py +1 -1
  16. airbyte-cdk-0.50.2/unit_tests/sources/file_based/config/test_csv_format.py +23 -0
  17. airbyte-cdk-0.50.2/unit_tests/sources/file_based/file_types/test_csv_parser.py +98 -0
  18. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/helpers.py +5 -0
  19. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/in_memory_files_source.py +11 -3
  20. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/csv_scenarios.py +1254 -47
  21. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/incremental_scenarios.py +6 -5
  22. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/scenario_builder.py +8 -7
  23. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/stream/test_default_file_based_cursor.py +13 -12
  24. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/test_scenarios.py +30 -0
  25. airbyte-cdk-0.50.0/airbyte_cdk/sources/file_based/file_types/csv_parser.py +0 -182
  26. airbyte-cdk-0.50.0/airbyte_cdk/sources/file_based/stream/cursor/__init__.py +0 -4
  27. airbyte-cdk-0.50.0/unit_tests/sources/file_based/file_types/test_csv_parser.py +0 -66
  28. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/LICENSE.txt +0 -0
  29. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/README.md +0 -0
  30. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/__init__.py +0 -0
  31. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/config_observation.py +0 -0
  32. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/connector.py +0 -0
  33. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/connector_builder/__init__.py +0 -0
  34. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/connector_builder/connector_builder_handler.py +0 -0
  35. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/connector_builder/main.py +0 -0
  36. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/connector_builder/message_grouper.py +0 -0
  37. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/connector_builder/models.py +0 -0
  38. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/destinations/__init__.py +0 -0
  39. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/destinations/destination.py +0 -0
  40. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/exception_handler.py +0 -0
  41. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/logger.py +0 -0
  42. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/models/__init__.py +0 -0
  43. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/models/airbyte_protocol.py +0 -0
  44. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/models/well_known_types.py +0 -0
  45. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/py.typed +0 -0
  46. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/__init__.py +0 -0
  47. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/abstract_source.py +0 -0
  48. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/config.py +0 -0
  49. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/connector_state_manager.py +0 -0
  50. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/__init__.py +0 -0
  51. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/auth/__init__.py +0 -0
  52. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +0 -0
  53. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/auth/oauth.py +0 -0
  54. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/auth/token.py +0 -0
  55. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/auth/token_provider.py +0 -0
  56. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/checks/__init__.py +0 -0
  57. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/checks/check_stream.py +0 -0
  58. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/checks/connection_checker.py +0 -0
  59. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/create_partial.py +0 -0
  60. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/datetime/__init__.py +0 -0
  61. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/datetime/datetime_parser.py +0 -0
  62. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +0 -0
  63. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/declarative_source.py +0 -0
  64. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/declarative_stream.py +0 -0
  65. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/decoders/__init__.py +0 -0
  66. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/decoders/decoder.py +0 -0
  67. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/decoders/json_decoder.py +0 -0
  68. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/exceptions.py +0 -0
  69. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/extractors/__init__.py +0 -0
  70. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +0 -0
  71. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/extractors/http_selector.py +0 -0
  72. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/extractors/record_extractor.py +0 -0
  73. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/extractors/record_filter.py +0 -0
  74. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/extractors/record_selector.py +0 -0
  75. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/incremental/__init__.py +0 -0
  76. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/incremental/cursor.py +0 -0
  77. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +0 -0
  78. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py +0 -0
  79. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/__init__.py +0 -0
  80. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/filters.py +0 -0
  81. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +0 -0
  82. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +0 -0
  83. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +0 -0
  84. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +0 -0
  85. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/interpolation.py +0 -0
  86. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/jinja.py +0 -0
  87. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/interpolation/macros.py +0 -0
  88. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/manifest_declarative_source.py +0 -0
  89. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/models/__init__.py +0 -0
  90. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/__init__.py +0 -0
  91. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/class_types_registry.py +0 -0
  92. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +0 -0
  93. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py +0 -0
  94. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +0 -0
  95. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +0 -0
  96. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +0 -0
  97. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/partition_routers/__init__.py +0 -0
  98. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +0 -0
  99. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +0 -0
  100. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +0 -0
  101. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/__init__.py +0 -0
  102. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +0 -0
  103. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -0
  104. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +0 -0
  105. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +0 -0
  106. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +0 -0
  107. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +0 -0
  108. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +0 -0
  109. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +0 -0
  110. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +0 -0
  111. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +0 -0
  112. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +0 -0
  113. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +0 -0
  114. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/response_action.py +0 -0
  115. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/error_handlers/response_status.py +0 -0
  116. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/http_requester.py +0 -0
  117. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +0 -0
  118. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +0 -0
  119. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +0 -0
  120. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +0 -0
  121. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +0 -0
  122. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +0 -0
  123. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +0 -0
  124. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +0 -0
  125. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +0 -0
  126. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py +0 -0
  127. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_option.py +0 -0
  128. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +0 -0
  129. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +0 -0
  130. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +0 -0
  131. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +0 -0
  132. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +0 -0
  133. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/request_path.py +0 -0
  134. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/requesters/requester.py +0 -0
  135. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/retrievers/__init__.py +0 -0
  136. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/retrievers/retriever.py +0 -0
  137. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +0 -0
  138. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/schema/__init__.py +0 -0
  139. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/schema/default_schema_loader.py +0 -0
  140. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/schema/inline_schema_loader.py +0 -0
  141. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +0 -0
  142. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/schema/schema_loader.py +0 -0
  143. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/spec/__init__.py +0 -0
  144. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/spec/spec.py +0 -0
  145. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/stream_slicers/__init__.py +0 -0
  146. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/stream_slicers/cartesian_product_stream_slicer.py +0 -0
  147. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +0 -0
  148. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/transformations/__init__.py +0 -0
  149. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/transformations/add_fields.py +0 -0
  150. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/transformations/remove_fields.py +0 -0
  151. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/transformations/transformation.py +0 -0
  152. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/types.py +0 -0
  153. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/declarative/yaml_declarative_source.py +0 -0
  154. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/deprecated/__init__.py +0 -0
  155. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/deprecated/base_source.py +0 -0
  156. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/deprecated/client.py +0 -0
  157. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/embedded/__init__.py +0 -0
  158. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/embedded/base_integration.py +0 -0
  159. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/embedded/catalog.py +0 -0
  160. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/embedded/runner.py +0 -0
  161. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/embedded/tools.py +0 -0
  162. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/__init__.py +0 -0
  163. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/availability_strategy/__init__.py +0 -0
  164. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py +0 -0
  165. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/__init__.py +0 -0
  166. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +0 -0
  167. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/avro_format.py +0 -0
  168. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +0 -0
  169. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/jsonl_format.py +0 -0
  170. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/config/parquet_format.py +0 -0
  171. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/discovery_policy/__init__.py +0 -0
  172. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py +0 -0
  173. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py +0 -0
  174. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/exceptions.py +0 -0
  175. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_based_stream_reader.py +0 -0
  176. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_types/__init__.py +0 -0
  177. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_types/avro_parser.py +0 -0
  178. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_types/file_type_parser.py +0 -0
  179. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +0 -0
  180. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/file_types/parquet_parser.py +0 -0
  181. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/remote_file.py +0 -0
  182. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/schema_helpers.py +0 -0
  183. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py +0 -0
  184. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +0 -0
  185. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +0 -0
  186. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/stream/__init__.py +0 -0
  187. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +0 -0
  188. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/file_based/types.py +0 -0
  189. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/http_logger.py +0 -0
  190. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/message/__init__.py +0 -0
  191. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/message/repository.py +0 -0
  192. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/singer/__init__.py +0 -0
  193. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/singer/singer_helpers.py +0 -0
  194. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/singer/source.py +0 -0
  195. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/source.py +0 -0
  196. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/__init__.py +0 -0
  197. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/availability_strategy.py +0 -0
  198. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/core.py +0 -0
  199. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/__init__.py +0 -0
  200. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/auth/__init__.py +0 -0
  201. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/auth/core.py +0 -0
  202. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/auth/oauth.py +0 -0
  203. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/auth/token.py +0 -0
  204. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/availability_strategy.py +0 -0
  205. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/exceptions.py +0 -0
  206. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/http.py +0 -0
  207. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/rate_limiting.py +0 -0
  208. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py +0 -0
  209. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +0 -0
  210. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +0 -0
  211. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +0 -0
  212. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/http/requests_native_auth/token.py +0 -0
  213. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/utils/__init__.py +0 -0
  214. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/streams/utils/stream_helper.py +0 -0
  215. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/__init__.py +0 -0
  216. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/casing.py +0 -0
  217. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/catalog_helpers.py +0 -0
  218. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/record_helper.py +0 -0
  219. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/schema_helpers.py +0 -0
  220. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/schema_models.py +0 -0
  221. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/transform.py +0 -0
  222. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/sources/utils/types.py +0 -0
  223. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/__init__.py +0 -0
  224. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/airbyte_secrets_utils.py +0 -0
  225. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/datetime_format_inferrer.py +0 -0
  226. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/event_timing.py +0 -0
  227. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/mapping_helpers.py +0 -0
  228. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/schema_inferrer.py +0 -0
  229. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/spec_schema_transformations.py +0 -0
  230. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/stream_status_utils.py +0 -0
  231. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk/utils/traced_exception.py +0 -0
  232. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk.egg-info/dependency_links.txt +0 -0
  233. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk.egg-info/requires.txt +0 -0
  234. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/airbyte_cdk.egg-info/top_level.txt +0 -0
  235. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/pyproject.toml +0 -0
  236. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/setup.cfg +0 -0
  237. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/source_declarative_manifest/__init__.py +0 -0
  238. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/source_declarative_manifest/main.py +0 -0
  239. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/connector_builder/__init__.py +0 -0
  240. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/connector_builder/test_connector_builder_handler.py +0 -0
  241. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/connector_builder/test_message_grouper.py +0 -0
  242. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/connector_builder/utils.py +0 -0
  243. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/destinations/__init__.py +0 -0
  244. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/destinations/test_destination.py +0 -0
  245. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/singer/__init__.py +0 -0
  246. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/singer/test_singer_helpers.py +0 -0
  247. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/singer/test_singer_source.py +0 -0
  248. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/__init__.py +0 -0
  249. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/__init__.py +0 -0
  250. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/auth/__init__.py +0 -0
  251. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/auth/test_oauth.py +0 -0
  252. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/auth/test_session_token_auth.py +0 -0
  253. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/auth/test_token_auth.py +0 -0
  254. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/auth/test_token_provider.py +0 -0
  255. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/checks/__init__.py +0 -0
  256. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/checks/test_check_stream.py +0 -0
  257. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/decoders/__init__.py +0 -0
  258. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/decoders/test_json_decoder.py +0 -0
  259. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/external_component.py +0 -0
  260. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/extractors/__init__.py +0 -0
  261. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/extractors/test_dpath_extractor.py +0 -0
  262. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/extractors/test_record_filter.py +0 -0
  263. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/extractors/test_record_selector.py +0 -0
  264. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/incremental/__init__.py +0 -0
  265. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py +0 -0
  266. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/incremental/test_per_partition_cursor.py +0 -0
  267. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/incremental/test_per_partition_cursor_integration.py +0 -0
  268. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/__init__.py +0 -0
  269. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_filters.py +0 -0
  270. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py +0 -0
  271. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py +0 -0
  272. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py +0 -0
  273. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_interpolated_string.py +0 -0
  274. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_jinja.py +0 -0
  275. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/interpolation/test_macros.py +0 -0
  276. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/parsers/__init__.py +0 -0
  277. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py +0 -0
  278. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py +0 -0
  279. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +0 -0
  280. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/parsers/testing_components.py +0 -0
  281. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/partition_routers/__init__.py +0 -0
  282. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/partition_routers/test_list_partition_router.py +0 -0
  283. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/partition_routers/test_single_partition_router.py +0 -0
  284. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py +0 -0
  285. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/__init__.py +0 -0
  286. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/__init__.py +0 -0
  287. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -0
  288. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py +0 -0
  289. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py +0 -0
  290. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py +0 -0
  291. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py +0 -0
  292. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py +0 -0
  293. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py +0 -0
  294. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py +0 -0
  295. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py +0 -0
  296. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/error_handlers/test_response_status.py +0 -0
  297. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/__init__.py +0 -0
  298. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py +0 -0
  299. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +0 -0
  300. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py +0 -0
  301. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py +0 -0
  302. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_page_increment.py +0 -0
  303. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_request_option.py +0 -0
  304. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/paginators/test_stop_condition.py +0 -0
  305. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/request_options/__init__.py +0 -0
  306. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py +0 -0
  307. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/test_http_requester.py +0 -0
  308. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py +0 -0
  309. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/retrievers/__init__.py +0 -0
  310. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/retrievers/test_simple_retriever.py +0 -0
  311. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/schema/__init__.py +0 -0
  312. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/schema/source_test/SourceTest.py +0 -0
  313. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/schema/source_test/__init__.py +0 -0
  314. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/schema/test_default_schema_loader.py +0 -0
  315. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/schema/test_inline_schema_loader.py +0 -0
  316. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/schema/test_json_file_schema_loader.py +0 -0
  317. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/states/__init__.py +0 -0
  318. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/stream_slicers/__init__.py +0 -0
  319. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/stream_slicers/test_cartesian_product_stream_slicer.py +0 -0
  320. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/test_create_partial.py +0 -0
  321. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/test_declarative_stream.py +0 -0
  322. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/test_manifest_declarative_source.py +0 -0
  323. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/declarative/test_yaml_declarative_source.py +0 -0
  324. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/__init__.py +0 -0
  325. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/config/__init__.py +0 -0
  326. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/config/test_abstract_file_based_spec.py +0 -0
  327. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/config/test_file_based_stream_config.py +0 -0
  328. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/file_types/__init__.py +0 -0
  329. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/file_types/test_avro_parser.py +0 -0
  330. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/file_types/test_jsonl_parser.py +0 -0
  331. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/file_types/test_parquet_parser.py +0 -0
  332. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/__init__.py +0 -0
  333. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/avro_scenarios.py +0 -0
  334. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/check_scenarios.py +0 -0
  335. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/jsonl_scenarios.py +0 -0
  336. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/parquet_scenarios.py +0 -0
  337. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py +0 -0
  338. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py +0 -0
  339. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/stream/__init__.py +0 -0
  340. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/stream/test_default_file_based_stream.py +0 -0
  341. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/test_file_based_stream_reader.py +0 -0
  342. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/file_based/test_schema_helpers.py +0 -0
  343. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/fixtures/__init__.py +0 -0
  344. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/fixtures/source_test_fixture.py +0 -0
  345. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/message/__init__.py +0 -0
  346. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/message/test_repository.py +0 -0
  347. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/__init__.py +0 -0
  348. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/__init__.py +0 -0
  349. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/auth/__init__.py +0 -0
  350. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/auth/test_auth.py +0 -0
  351. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/requests_native_auth/__init__.py +0 -0
  352. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py +0 -0
  353. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/test_availability_strategy.py +0 -0
  354. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/http/test_http.py +0 -0
  355. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/test_availability_strategy.py +0 -0
  356. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/streams/test_streams_core.py +0 -0
  357. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/test_abstract_source.py +0 -0
  358. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/test_config.py +0 -0
  359. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/test_connector_state_manager.py +0 -0
  360. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/test_http_logger.py +0 -0
  361. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/test_integration_source.py +0 -0
  362. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/sources/test_source.py +0 -0
  363. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/__init__.py +0 -0
  364. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/test_datetime_format_inferrer.py +0 -0
  365. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/test_mapping_helpers.py +0 -0
  366. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/test_schema_inferrer.py +0 -0
  367. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/test_secret_utils.py +0 -0
  368. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/test_stream_status_utils.py +0 -0
  369. {airbyte-cdk-0.50.0 → airbyte-cdk-0.50.2}/unit_tests/utils/test_traced_exception.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 0.50.0
3
+ Version: 0.50.2
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://github.com/airbytehq/airbyte
6
6
  Author: Airbyte
@@ -181,6 +181,13 @@ class AirbyteEntrypoint(object):
181
181
  return parsed_args.catalog
182
182
  return None
183
183
 
184
+ @classmethod
185
+ def extract_config(cls, args: List[str]) -> Optional[Any]:
186
+ parsed_args = cls.parse_args(args)
187
+ if hasattr(parsed_args, "config"):
188
+ return parsed_args.config
189
+ return None
190
+
184
191
  def _emit_queued_messages(self, source: Source) -> Iterable[AirbyteMessage]:
185
192
  if hasattr(source, "message_repository") and source.message_repository:
186
193
  yield from source.message_repository.consume_queue()
@@ -578,9 +578,9 @@ definitions:
578
578
  - "created_at"
579
579
  - "{{ config['record_cursor'] }}"
580
580
  datetime_format:
581
- title: Cursor Field Datetime Format
581
+ title: Outgoing Datetime Format
582
582
  description: |
583
- The datetime format of the Cursor Field. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:
583
+ The datetime format used to format the datetime values that are sent in outgoing requests to the API. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:
584
584
  * **%s**: Epoch unix timestamp - `1686218963`
585
585
  * **%a**: Weekday (abbreviated) - `Sun`
586
586
  * **%A**: Weekday (full) - `Sunday`
@@ -626,7 +626,7 @@ definitions:
626
626
  - "{{ config['start_time'] }}"
627
627
  cursor_datetime_formats:
628
628
  title: Cursor Datetime Formats
629
- description: The possible formats for the cursor field
629
+ description: The possible formats for the cursor field, in order of preference. The first format that matches the cursor field value will be used to parse it. If not provided, the `datetime_format` will be used.
630
630
  type: array
631
631
  items:
632
632
  type: string
@@ -810,9 +810,9 @@ class DatetimeBasedCursor(BaseModel):
810
810
  )
811
811
  datetime_format: str = Field(
812
812
  ...,
813
- description="The datetime format of the Cursor Field. Use placeholders starting with \"%\" to describe the format the API is using. The following placeholders are available:\n * **%s**: Epoch unix timestamp - `1686218963`\n * **%a**: Weekday (abbreviated) - `Sun`\n * **%A**: Weekday (full) - `Sunday`\n * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)\n * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`\n * **%b**: Month (abbreviated) - `Jan`\n * **%B**: Month (full) - `January`\n * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`\n * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`\n * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`\n * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`\n * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`\n * **%p**: AM/PM indicator\n * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`\n * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`\n * **%f**: Microsecond (zero-padded to 6 digits) - `000000`\n * **%z**: UTC offset - `(empty)`, `+0000`, `-04:00`\n * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`\n * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`\n * **%U**: Week number of the year (starting Sunday) - `00`, ..., `53`\n * **%W**: Week number of the year (starting Monday) - `00`, ..., `53`\n * **%c**: Date and time - `Tue Aug 16 21:30:00 1988`\n * **%x**: Date standard format - `08/16/1988`\n * **%X**: Time standard format - `21:30:00`\n * **%%**: Literal '%' character\n\n Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).\n",
813
+ description="The datetime format used to format the datetime values that are sent in outgoing requests to the API. Use placeholders starting with \"%\" to describe the format the API is using. The following placeholders are available:\n * **%s**: Epoch unix timestamp - `1686218963`\n * **%a**: Weekday (abbreviated) - `Sun`\n * **%A**: Weekday (full) - `Sunday`\n * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)\n * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`\n * **%b**: Month (abbreviated) - `Jan`\n * **%B**: Month (full) - `January`\n * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`\n * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`\n * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`\n * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`\n * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`\n * **%p**: AM/PM indicator\n * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`\n * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`\n * **%f**: Microsecond (zero-padded to 6 digits) - `000000`\n * **%z**: UTC offset - `(empty)`, `+0000`, `-04:00`\n * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`\n * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`\n * **%U**: Week number of the year (starting Sunday) - `00`, ..., `53`\n * **%W**: Week number of the year (starting Monday) - `00`, ..., `53`\n * **%c**: Date and time - `Tue Aug 16 21:30:00 1988`\n * **%x**: Date standard format - `08/16/1988`\n * **%X**: Time standard format - `21:30:00`\n * **%%**: Literal '%' character\n\n Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).\n",
814
814
  examples=["%Y-%m-%dT%H:%M:%S.%f%z", "%Y-%m-%d", "%s"],
815
- title="Cursor Field Datetime Format",
815
+ title="Outgoing Datetime Format",
816
816
  )
817
817
  start_datetime: Union[str, MinMaxDatetime] = Field(
818
818
  ...,
@@ -822,7 +822,7 @@ class DatetimeBasedCursor(BaseModel):
822
822
  )
823
823
  cursor_datetime_formats: Optional[List[str]] = Field(
824
824
  None,
825
- description="The possible formats for the cursor field",
825
+ description="The possible formats for the cursor field, in order of preference. The first format that matches the cursor field value will be used to parse it. If not provided, the `datetime_format` will be used.",
826
826
  title="Cursor Datetime Formats",
827
827
  )
828
828
  cursor_granularity: Optional[str] = Field(
@@ -4,7 +4,7 @@
4
4
 
5
5
  import logging
6
6
  import traceback
7
- from typing import List, Optional, Tuple
7
+ from typing import TYPE_CHECKING, List, Optional, Tuple
8
8
 
9
9
  from airbyte_cdk.sources import Source
10
10
  from airbyte_cdk.sources.file_based.availability_strategy import AbstractFileBasedAvailabilityStrategy
@@ -12,14 +12,16 @@ from airbyte_cdk.sources.file_based.exceptions import CheckAvailabilityError, Fi
12
12
  from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader
13
13
  from airbyte_cdk.sources.file_based.remote_file import RemoteFile
14
14
  from airbyte_cdk.sources.file_based.schema_helpers import conforms_to_schema
15
- from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream
15
+
16
+ if TYPE_CHECKING:
17
+ from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream
16
18
 
17
19
 
18
20
  class DefaultFileBasedAvailabilityStrategy(AbstractFileBasedAvailabilityStrategy):
19
21
  def __init__(self, stream_reader: AbstractFileBasedStreamReader):
20
22
  self.stream_reader = stream_reader
21
23
 
22
- def check_availability(self, stream: AbstractFileBasedStream, logger: logging.Logger, _: Optional[Source]) -> Tuple[bool, Optional[str]]: # type: ignore[override]
24
+ def check_availability(self, stream: "AbstractFileBasedStream", logger: logging.Logger, _: Optional[Source]) -> Tuple[bool, Optional[str]]: # type: ignore[override]
23
25
  """
24
26
  Perform a connection check for the stream (verify that we can list files from the stream).
25
27
 
@@ -33,7 +35,7 @@ class DefaultFileBasedAvailabilityStrategy(AbstractFileBasedAvailabilityStrategy
33
35
  return True, None
34
36
 
35
37
  def check_availability_and_parsability(
36
- self, stream: AbstractFileBasedStream, logger: logging.Logger, _: Optional[Source]
38
+ self, stream: "AbstractFileBasedStream", logger: logging.Logger, _: Optional[Source]
37
39
  ) -> Tuple[bool, Optional[str]]:
38
40
  """
39
41
  Perform a connection check for the stream.
@@ -51,8 +53,6 @@ class DefaultFileBasedAvailabilityStrategy(AbstractFileBasedAvailabilityStrategy
51
53
  - If the user provided a schema in the config, check that a subset of records in
52
54
  one file conform to the schema via a call to stream.conforms_to_schema(schema).
53
55
  """
54
- if not isinstance(stream, AbstractFileBasedStream):
55
- raise ValueError(f"Stream {stream.name} is not a file-based stream.")
56
56
  try:
57
57
  files = self._check_list_files(stream)
58
58
  self._check_extensions(stream, files)
@@ -62,7 +62,7 @@ class DefaultFileBasedAvailabilityStrategy(AbstractFileBasedAvailabilityStrategy
62
62
 
63
63
  return True, None
64
64
 
65
- def _check_list_files(self, stream: AbstractFileBasedStream) -> List[RemoteFile]:
65
+ def _check_list_files(self, stream: "AbstractFileBasedStream") -> List[RemoteFile]:
66
66
  try:
67
67
  files = stream.list_files()
68
68
  except Exception as exc:
@@ -73,12 +73,12 @@ class DefaultFileBasedAvailabilityStrategy(AbstractFileBasedAvailabilityStrategy
73
73
 
74
74
  return files
75
75
 
76
- def _check_extensions(self, stream: AbstractFileBasedStream, files: List[RemoteFile]) -> None:
76
+ def _check_extensions(self, stream: "AbstractFileBasedStream", files: List[RemoteFile]) -> None:
77
77
  if not all(f.extension_agrees_with_file_type(stream.config.file_type) for f in files):
78
78
  raise CheckAvailabilityError(FileBasedSourceError.EXTENSION_MISMATCH, stream=stream.name)
79
79
  return None
80
80
 
81
- def _check_parse_record(self, stream: AbstractFileBasedStream, file: RemoteFile, logger: logging.Logger) -> None:
81
+ def _check_parse_record(self, stream: "AbstractFileBasedStream", file: RemoteFile, logger: logging.Logger) -> None:
82
82
  parser = stream.get_parser(stream.config.file_type)
83
83
 
84
84
  try:
@@ -4,9 +4,9 @@
4
4
 
5
5
  import codecs
6
6
  from enum import Enum
7
- from typing import Optional
7
+ from typing import Any, Mapping, Optional, Set
8
8
 
9
- from pydantic import BaseModel, Field, validator
9
+ from pydantic import BaseModel, Field, root_validator, validator
10
10
  from typing_extensions import Literal
11
11
 
12
12
 
@@ -17,6 +17,10 @@ class QuotingBehavior(Enum):
17
17
  QUOTE_NONE = "Quote None"
18
18
 
19
19
 
20
+ DEFAULT_TRUE_VALUES = ["y", "yes", "t", "true", "on", "1"]
21
+ DEFAULT_FALSE_VALUES = ["n", "no", "f", "false", "off", "0"]
22
+
23
+
20
24
  class CsvFormat(BaseModel):
21
25
  filetype: Literal["csv"] = "csv"
22
26
  delimiter: str = Field(
@@ -46,10 +50,34 @@ class CsvFormat(BaseModel):
46
50
  default=QuotingBehavior.QUOTE_SPECIAL_CHARACTERS,
47
51
  description="The quoting behavior determines when a value in a row should have quote marks added around it. For example, if Quote Non-numeric is specified, while reading, quotes are expected for row values that do not contain numbers. Or for Quote All, every row value will be expecting quotes.",
48
52
  )
49
-
50
- # Noting that the existing S3 connector had a config option newlines_in_values. This was only supported by pyarrow and not
51
- # the Python csv package. It has a little adoption, but long term we should ideally phase this out because of the drawbacks
52
- # of using pyarrow
53
+ null_values: Set[str] = Field(
54
+ title="Null Values",
55
+ default=[],
56
+ description="A set of case-sensitive strings that should be interpreted as null values. For example, if the value 'NA' should be interpreted as null, enter 'NA' in this field.",
57
+ )
58
+ skip_rows_before_header: int = Field(
59
+ title="Skip Rows Before Header",
60
+ default=0,
61
+ description="The number of rows to skip before the header row. For example, if the header row is on the 3rd row, enter 2 in this field.",
62
+ )
63
+ skip_rows_after_header: int = Field(
64
+ title="Skip Rows After Header", default=0, description="The number of rows to skip after the header row."
65
+ )
66
+ autogenerate_column_names: bool = Field(
67
+ title="Autogenerate Column Names",
68
+ default=False,
69
+ description="Whether to autogenerate column names if column_names is empty. If true, column names will be of the form “f0”, “f1”… If false, column names will be read from the first CSV row after skip_rows_before_header.",
70
+ )
71
+ true_values: Set[str] = Field(
72
+ title="True Values",
73
+ default=DEFAULT_TRUE_VALUES,
74
+ description="A set of case-sensitive strings that should be interpreted as true values.",
75
+ )
76
+ false_values: Set[str] = Field(
77
+ title="False Values",
78
+ default=DEFAULT_FALSE_VALUES,
79
+ description="A set of case-sensitive strings that should be interpreted as false values.",
80
+ )
53
81
 
54
82
  @validator("delimiter")
55
83
  def validate_delimiter(cls, v: str) -> str:
@@ -78,3 +106,11 @@ class CsvFormat(BaseModel):
78
106
  except LookupError:
79
107
  raise ValueError(f"invalid encoding format: {v}")
80
108
  return v
109
+
110
+ @root_validator
111
+ def validate_option_combinations(cls, values: Mapping[str, Any]) -> Mapping[str, Any]:
112
+ skip_rows_before_header = values.get("skip_rows_before_header", 0)
113
+ auto_generate_column_names = values.get("autogenerate_column_names", False)
114
+ if skip_rows_before_header > 0 and auto_generate_column_names:
115
+ raise ValueError("Cannot skip rows before header and autogenerate column names at the same time.")
116
+ return values
@@ -19,12 +19,11 @@ from airbyte_cdk.sources.file_based.file_types import default_parsers
19
19
  from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser
20
20
  from airbyte_cdk.sources.file_based.schema_validation_policies import DEFAULT_SCHEMA_VALIDATION_POLICIES, AbstractSchemaValidationPolicy
21
21
  from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream, DefaultFileBasedStream
22
+ from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor
22
23
  from airbyte_cdk.sources.file_based.stream.cursor.default_file_based_cursor import DefaultFileBasedCursor
23
24
  from airbyte_cdk.sources.streams import Stream
24
25
  from pydantic.error_wrappers import ValidationError
25
26
 
26
- DEFAULT_MAX_HISTORY_SIZE = 10_000
27
-
28
27
 
29
28
  class FileBasedSource(AbstractSource, ABC):
30
29
  def __init__(
@@ -36,7 +35,7 @@ class FileBasedSource(AbstractSource, ABC):
36
35
  discovery_policy: AbstractDiscoveryPolicy = DefaultDiscoveryPolicy(),
37
36
  parsers: Mapping[str, FileTypeParser] = default_parsers,
38
37
  validation_policies: Mapping[str, AbstractSchemaValidationPolicy] = DEFAULT_SCHEMA_VALIDATION_POLICIES,
39
- max_history_size: int = DEFAULT_MAX_HISTORY_SIZE,
38
+ cursor_cls: Type[AbstractFileBasedCursor] = DefaultFileBasedCursor,
40
39
  ):
41
40
  self.stream_reader = stream_reader
42
41
  self.spec_class = spec_class
@@ -46,7 +45,7 @@ class FileBasedSource(AbstractSource, ABC):
46
45
  self.validation_policies = validation_policies
47
46
  catalog = self.read_catalog(catalog_path) if catalog_path else None
48
47
  self.stream_schemas = {s.stream.name: s.stream.json_schema for s in catalog.streams} if catalog else {}
49
- self.max_history_size = max_history_size
48
+ self.cursor_cls = cursor_cls
50
49
  self.logger = logging.getLogger(f"airbyte.{self.name}")
51
50
 
52
51
  def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]:
@@ -104,7 +103,7 @@ class FileBasedSource(AbstractSource, ABC):
104
103
  discovery_policy=self.discovery_policy,
105
104
  parsers=self.parsers,
106
105
  validation_policy=self._validate_and_get_validation_policy(stream_config),
107
- cursor=DefaultFileBasedCursor(self.max_history_size, stream_config.days_to_sync_if_history_is_full),
106
+ cursor=self.cursor_cls(stream_config),
108
107
  )
109
108
  )
110
109
  return streams
@@ -0,0 +1,237 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ import csv
6
+ import json
7
+ import logging
8
+ from functools import partial
9
+ from io import IOBase
10
+ from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Set
11
+
12
+ from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat, QuotingBehavior
13
+ from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig
14
+ from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, RecordParseError
15
+ from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode
16
+ from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser
17
+ from airbyte_cdk.sources.file_based.remote_file import RemoteFile
18
+ from airbyte_cdk.sources.file_based.schema_helpers import TYPE_PYTHON_MAPPING
19
+
20
+ DIALECT_NAME = "_config_dialect"
21
+
22
+ config_to_quoting: Mapping[QuotingBehavior, int] = {
23
+ QuotingBehavior.QUOTE_ALL: csv.QUOTE_ALL,
24
+ QuotingBehavior.QUOTE_SPECIAL_CHARACTERS: csv.QUOTE_MINIMAL,
25
+ QuotingBehavior.QUOTE_NONNUMERIC: csv.QUOTE_NONNUMERIC,
26
+ QuotingBehavior.QUOTE_NONE: csv.QUOTE_NONE,
27
+ }
28
+
29
+
30
+ class CsvParser(FileTypeParser):
31
+ async def infer_schema(
32
+ self,
33
+ config: FileBasedStreamConfig,
34
+ file: RemoteFile,
35
+ stream_reader: AbstractFileBasedStreamReader,
36
+ logger: logging.Logger,
37
+ ) -> Dict[str, Any]:
38
+ config_format = config.format.get(config.file_type) if config.format else CsvFormat()
39
+ if not isinstance(config_format, CsvFormat):
40
+ raise ValueError(f"Invalid format config: {config_format}")
41
+ dialect_name = config.name + DIALECT_NAME
42
+ csv.register_dialect(
43
+ dialect_name,
44
+ delimiter=config_format.delimiter,
45
+ quotechar=config_format.quote_char,
46
+ escapechar=config_format.escape_char,
47
+ doublequote=config_format.double_quote,
48
+ quoting=config_to_quoting.get(config_format.quoting_behavior, csv.QUOTE_MINIMAL),
49
+ )
50
+ with stream_reader.open_file(file, self.file_read_mode, logger) as fp:
51
+ # todo: the existing InMemoryFilesSource.open_file() test source doesn't currently require an encoding, but actual
52
+ # sources will likely require one. Rather than modify the interface now we can wait until the real use case
53
+ headers = self._get_headers(fp, config_format, dialect_name)
54
+ schema = {field.strip(): {"type": "string"} for field in headers}
55
+ csv.unregister_dialect(dialect_name)
56
+ return schema
57
+
58
+ def parse_records(
59
+ self,
60
+ config: FileBasedStreamConfig,
61
+ file: RemoteFile,
62
+ stream_reader: AbstractFileBasedStreamReader,
63
+ logger: logging.Logger,
64
+ ) -> Iterable[Dict[str, Any]]:
65
+ schema: Mapping[str, Any] = config.input_schema # type: ignore
66
+ config_format = config.format.get(config.file_type) if config.format else CsvFormat()
67
+ if not isinstance(config_format, CsvFormat):
68
+ raise ValueError(f"Invalid format config: {config_format}")
69
+ # Formats are configured individually per-stream so a unique dialect should be registered for each stream.
70
+ # We don't unregister the dialect because we are lazily parsing each csv file to generate records
71
+ # This will potentially be a problem if we ever process multiple streams concurrently
72
+ dialect_name = config.name + DIALECT_NAME
73
+ csv.register_dialect(
74
+ dialect_name,
75
+ delimiter=config_format.delimiter,
76
+ quotechar=config_format.quote_char,
77
+ escapechar=config_format.escape_char,
78
+ doublequote=config_format.double_quote,
79
+ quoting=config_to_quoting.get(config_format.quoting_behavior, csv.QUOTE_MINIMAL),
80
+ )
81
+ with stream_reader.open_file(file, self.file_read_mode, logger) as fp:
82
+ # todo: the existing InMemoryFilesSource.open_file() test source doesn't currently require an encoding, but actual
83
+ # sources will likely require one. Rather than modify the interface now we can wait until the real use case
84
+ self._skip_rows_before_header(fp, config_format.skip_rows_before_header)
85
+ field_names = self._auto_generate_headers(fp, config_format) if config_format.autogenerate_column_names else None
86
+ reader = csv.DictReader(fp, dialect=dialect_name, fieldnames=field_names) # type: ignore
87
+ yield from self._read_and_cast_types(reader, schema, config_format, logger)
88
+
89
+ @property
90
+ def file_read_mode(self) -> FileReadMode:
91
+ return FileReadMode.READ
92
+
93
+ @staticmethod
94
+ def _read_and_cast_types(
95
+ reader: csv.DictReader, schema: Optional[Mapping[str, Any]], config_format: CsvFormat, logger: logging.Logger # type: ignore
96
+ ) -> Iterable[Dict[str, Any]]:
97
+ """
98
+ If the user provided a schema, attempt to cast the record values to the associated type.
99
+
100
+ If a column is not in the schema or cannot be cast to an appropriate python type,
101
+ cast it to a string. Downstream, the user's validation policy will determine whether the
102
+ record should be emitted.
103
+ """
104
+ cast_fn = CsvParser._get_cast_function(schema, config_format, logger)
105
+ for i, row in enumerate(reader):
106
+ if i < config_format.skip_rows_after_header:
107
+ continue
108
+ # The row was not properly parsed if any of the values are None
109
+ if any(val is None for val in row.values()):
110
+ raise RecordParseError(FileBasedSourceError.ERROR_PARSING_RECORD)
111
+ else:
112
+ yield CsvParser._to_nullable(cast_fn(row), config_format.null_values)
113
+
114
+ @staticmethod
115
+ def _get_cast_function(
116
+ schema: Optional[Mapping[str, Any]], config_format: CsvFormat, logger: logging.Logger
117
+ ) -> Callable[[Mapping[str, str]], Mapping[str, str]]:
118
+ # Only cast values if the schema is provided
119
+ if schema:
120
+ property_types = {col: prop["type"] for col, prop in schema["properties"].items()}
121
+ return partial(_cast_types, property_types=property_types, config_format=config_format, logger=logger)
122
+ else:
123
+ # If no schema is provided, yield the rows as they are
124
+ return _no_cast
125
+
126
+ @staticmethod
127
+ def _to_nullable(row: Mapping[str, str], null_values: Set[str]) -> Dict[str, Optional[str]]:
128
+ nullable = row | {k: None if v in null_values else v for k, v in row.items()}
129
+ return nullable
130
+
131
+ @staticmethod
132
+ def _skip_rows_before_header(fp: IOBase, rows_to_skip: int) -> None:
133
+ """
134
+ Skip rows before the header. This has to be done on the file object itself, not the reader
135
+ """
136
+ for _ in range(rows_to_skip):
137
+ fp.readline()
138
+
139
+ def _get_headers(self, fp: IOBase, config_format: CsvFormat, dialect_name: str) -> List[str]:
140
+ # Note that this method assumes the dialect has already been registered if we're parsing the headers
141
+ if config_format.autogenerate_column_names:
142
+ return self._auto_generate_headers(fp, config_format)
143
+ else:
144
+ # If we're not autogenerating column names, we need to skip the rows before the header
145
+ self._skip_rows_before_header(fp, config_format.skip_rows_before_header)
146
+ # Then read the header
147
+ reader = csv.DictReader(fp, dialect=dialect_name) # type: ignore
148
+ return next(reader) # type: ignore
149
+
150
+ def _auto_generate_headers(self, fp: IOBase, config_format: CsvFormat) -> List[str]:
151
+ """
152
+ Generates field names as [f0, f1, ...] in the same way as pyarrow's csv reader with autogenerate_column_names=True.
153
+ See https://arrow.apache.org/docs/python/generated/pyarrow.csv.ReadOptions.html
154
+ """
155
+ next_line = next(fp).strip()
156
+ number_of_columns = len(next_line.split(config_format.delimiter)) # type: ignore
157
+ # Reset the file pointer to the beginning of the file so that the first row is not skipped
158
+ fp.seek(0)
159
+ return [f"f{i}" for i in range(number_of_columns)]
160
+
161
+
162
+ def _cast_types(row: Dict[str, str], property_types: Dict[str, Any], config_format: CsvFormat, logger: logging.Logger) -> Dict[str, Any]:
163
+ """
164
+ Casts the values in the input 'row' dictionary according to the types defined in the JSON schema.
165
+
166
+ Array and object types are only handled if they can be deserialized as JSON.
167
+
168
+ If any errors are encountered, the value will be emitted as a string.
169
+ """
170
+ warnings = []
171
+ result = {}
172
+
173
+ for key, value in row.items():
174
+ prop_type = property_types.get(key)
175
+ cast_value: Any = value
176
+
177
+ if prop_type in TYPE_PYTHON_MAPPING and prop_type is not None:
178
+ _, python_type = TYPE_PYTHON_MAPPING[prop_type]
179
+
180
+ if python_type is None:
181
+ if value == "":
182
+ cast_value = None
183
+ else:
184
+ warnings.append(_format_warning(key, value, prop_type))
185
+
186
+ elif python_type == bool:
187
+ try:
188
+ cast_value = _value_to_bool(value, config_format.true_values, config_format.false_values)
189
+ except ValueError:
190
+ warnings.append(_format_warning(key, value, prop_type))
191
+
192
+ elif python_type == dict:
193
+ try:
194
+ cast_value = json.loads(value)
195
+ except json.JSONDecodeError:
196
+ warnings.append(_format_warning(key, value, prop_type))
197
+
198
+ elif python_type == list:
199
+ try:
200
+ parsed_value = json.loads(value)
201
+ if isinstance(parsed_value, list):
202
+ cast_value = parsed_value
203
+ except json.JSONDecodeError:
204
+ warnings.append(_format_warning(key, value, prop_type))
205
+
206
+ elif python_type:
207
+ try:
208
+ cast_value = python_type(value)
209
+ except ValueError:
210
+ warnings.append(_format_warning(key, value, prop_type))
211
+
212
+ else:
213
+ warnings.append(_format_warning(key, value, prop_type))
214
+
215
+ result[key] = cast_value
216
+
217
+ if warnings:
218
+ logger.warning(
219
+ f"{FileBasedSourceError.ERROR_CASTING_VALUE.value}: {','.join([w for w in warnings])}",
220
+ )
221
+ return result
222
+
223
+
224
+ def _value_to_bool(value: str, true_values: Set[str], false_values: Set[str]) -> bool:
225
+ if value in true_values:
226
+ return True
227
+ if value in false_values:
228
+ return False
229
+ raise ValueError(f"Value {value} is not a valid boolean value")
230
+
231
+
232
+ def _format_warning(key: str, value: str, expected_type: Optional[Any]) -> str:
233
+ return f"{key}: value={value},expected_type={expected_type}"
234
+
235
+
236
+ def _no_cast(row: Mapping[str, str]) -> Mapping[str, str]:
237
+ return row
@@ -0,0 +1,4 @@
1
+ from .abstract_file_based_cursor import AbstractFileBasedCursor
2
+ from .default_file_based_cursor import DefaultFileBasedCursor
3
+
4
+ __all__ = ["AbstractFileBasedCursor", "DefaultFileBasedCursor"]
@@ -7,15 +7,23 @@ from abc import ABC, abstractmethod
7
7
  from datetime import datetime
8
8
  from typing import Any, Iterable, MutableMapping
9
9
 
10
+ from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig
10
11
  from airbyte_cdk.sources.file_based.remote_file import RemoteFile
11
12
  from airbyte_cdk.sources.file_based.types import StreamState
12
13
 
13
14
 
14
- class FileBasedCursor(ABC):
15
+ class AbstractFileBasedCursor(ABC):
15
16
  """
16
17
  Abstract base class for cursors used by file-based streams.
17
18
  """
18
19
 
20
+ @abstractmethod
21
+ def __init__(self, stream_config: FileBasedStreamConfig, **kwargs: Any):
22
+ """
23
+ Common interface for all cursors.
24
+ """
25
+ ...
26
+
19
27
  @abstractmethod
20
28
  def add_file(self, file: RemoteFile) -> None:
21
29
  """
@@ -4,26 +4,26 @@
4
4
 
5
5
  import logging
6
6
  from datetime import datetime, timedelta
7
- from typing import Iterable, MutableMapping, Optional
7
+ from typing import Any, Iterable, MutableMapping, Optional
8
8
 
9
+ from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig
9
10
  from airbyte_cdk.sources.file_based.remote_file import RemoteFile
10
- from airbyte_cdk.sources.file_based.stream.cursor.file_based_cursor import FileBasedCursor
11
+ from airbyte_cdk.sources.file_based.stream.cursor.abstract_file_based_cursor import AbstractFileBasedCursor
11
12
  from airbyte_cdk.sources.file_based.types import StreamState
12
13
 
13
14
 
14
- class DefaultFileBasedCursor(FileBasedCursor):
15
+ class DefaultFileBasedCursor(AbstractFileBasedCursor):
15
16
  DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL = 3
17
+ DEFAULT_MAX_HISTORY_SIZE = 10_000
16
18
  DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
17
19
 
18
- def __init__(self, max_history_size: int, days_to_sync_if_history_is_full: Optional[int]):
20
+ def __init__(self, stream_config: FileBasedStreamConfig, **_: Any):
21
+ super().__init__(stream_config)
19
22
  self._file_to_datetime_history: MutableMapping[str, str] = {}
20
- self._max_history_size = max_history_size
21
23
  self._time_window_if_history_is_full = timedelta(
22
- days=days_to_sync_if_history_is_full or self.DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL
24
+ days=stream_config.days_to_sync_if_history_is_full or self.DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL
23
25
  )
24
26
 
25
- if self._max_history_size <= 0:
26
- raise ValueError(f"max_history_size must be a positive integer, got {self._max_history_size}")
27
27
  if self._time_window_if_history_is_full <= timedelta():
28
28
  raise ValueError(f"days_to_sync_if_history_is_full must be a positive timedelta, got {self._time_window_if_history_is_full}")
29
29
 
@@ -37,7 +37,7 @@ class DefaultFileBasedCursor(FileBasedCursor):
37
37
 
38
38
  def add_file(self, file: RemoteFile) -> None:
39
39
  self._file_to_datetime_history[file.uri] = file.last_modified.strftime(self.DATE_TIME_FORMAT)
40
- if len(self._file_to_datetime_history) > self._max_history_size:
40
+ if len(self._file_to_datetime_history) > self.DEFAULT_MAX_HISTORY_SIZE:
41
41
  # Get the earliest file based on its last modified date and its uri
42
42
  oldest_file = self._compute_earliest_file_in_history()
43
43
  if oldest_file:
@@ -67,7 +67,7 @@ class DefaultFileBasedCursor(FileBasedCursor):
67
67
  """
68
68
  Returns true if the state's history is full, meaning new entries will start to replace old entries.
69
69
  """
70
- return len(self._file_to_datetime_history) >= self._max_history_size
70
+ return len(self._file_to_datetime_history) >= self.DEFAULT_MAX_HISTORY_SIZE
71
71
 
72
72
  def _should_sync_file(self, file: RemoteFile, logger: logging.Logger) -> bool:
73
73
  if file.uri in self._file_to_datetime_history:
@@ -15,13 +15,14 @@ from airbyte_cdk.sources.file_based.exceptions import (
15
15
  FileBasedSourceError,
16
16
  InvalidSchemaError,
17
17
  MissingSchemaError,
18
+ RecordParseError,
18
19
  SchemaInferenceError,
19
20
  StopSyncPerValidationPolicy,
20
21
  )
21
22
  from airbyte_cdk.sources.file_based.remote_file import RemoteFile
22
23
  from airbyte_cdk.sources.file_based.schema_helpers import merge_schemas, schemaless_schema
23
24
  from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream
24
- from airbyte_cdk.sources.file_based.stream.cursor import FileBasedCursor
25
+ from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor
25
26
  from airbyte_cdk.sources.file_based.types import StreamSlice
26
27
  from airbyte_cdk.sources.streams import IncrementalMixin
27
28
  from airbyte_cdk.sources.streams.core import JsonSchema
@@ -39,7 +40,7 @@ class DefaultFileBasedStream(AbstractFileBasedStream, IncrementalMixin):
39
40
  ab_file_name_col = "_ab_source_file_url"
40
41
  airbyte_columns = [ab_last_mod_col, ab_file_name_col]
41
42
 
42
- def __init__(self, cursor: FileBasedCursor, **kwargs: Any):
43
+ def __init__(self, cursor: AbstractFileBasedCursor, **kwargs: Any):
43
44
  super().__init__(**kwargs)
44
45
  self._cursor = cursor
45
46
 
@@ -105,6 +106,18 @@ class DefaultFileBasedStream(AbstractFileBasedStream, IncrementalMixin):
105
106
  )
106
107
  break
107
108
 
109
+ except RecordParseError:
110
+ # Increment line_no because the exception was raised before we could increment it
111
+ line_no += 1
112
+ yield AirbyteMessage(
113
+ type=MessageType.LOG,
114
+ log=AirbyteLogMessage(
115
+ level=Level.ERROR,
116
+ message=f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream={self.name} file={file.uri} line_no={line_no} n_skipped={n_skipped}",
117
+ stack_trace=traceback.format_exc(),
118
+ ),
119
+ )
120
+
108
121
  except Exception:
109
122
  yield AirbyteMessage(
110
123
  type=MessageType.LOG,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 0.50.0
3
+ Version: 0.50.2
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://github.com/airbytehq/airbyte
6
6
  Author: Airbyte
@@ -177,8 +177,8 @@ airbyte_cdk/sources/file_based/stream/__init__.py
177
177
  airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py
178
178
  airbyte_cdk/sources/file_based/stream/default_file_based_stream.py
179
179
  airbyte_cdk/sources/file_based/stream/cursor/__init__.py
180
+ airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py
180
181
  airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py
181
- airbyte_cdk/sources/file_based/stream/cursor/file_based_cursor.py
182
182
  airbyte_cdk/sources/message/__init__.py
183
183
  airbyte_cdk/sources/message/repository.py
184
184
  airbyte_cdk/sources/singer/__init__.py
@@ -321,6 +321,7 @@ unit_tests/sources/file_based/test_scenarios.py
321
321
  unit_tests/sources/file_based/test_schema_helpers.py
322
322
  unit_tests/sources/file_based/config/__init__.py
323
323
  unit_tests/sources/file_based/config/test_abstract_file_based_spec.py
324
+ unit_tests/sources/file_based/config/test_csv_format.py
324
325
  unit_tests/sources/file_based/config/test_file_based_stream_config.py
325
326
  unit_tests/sources/file_based/file_types/__init__.py
326
327
  unit_tests/sources/file_based/file_types/test_avro_parser.py