From 50690551799c439a1eb13ffe9fb72da701c1f61e Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Thu, 4 Aug 2022 11:58:43 -0700 Subject: [PATCH 1/9] fix parse and format methods --- .../stream_slicers/datetime_stream_slicer.py | 19 +++---- .../test_datetime_stream_slicer.py | 53 +++++++++++++++++++ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py index a9190cc1fe593..536ad71c73eaa 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py @@ -4,9 +4,8 @@ import datetime import re -from typing import Any, Iterable, Mapping, Optional +from typing import Any, Iterable, Mapping, Optional, Union -import dateutil from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString @@ -155,7 +154,7 @@ def stream_slices(self, sync_mode: SyncMode, stream_state: Mapping[str, Any]) -> def _format_datetime(self, dt: datetime.datetime): if self._datetime_format == "timestamp": - return dt.timestamp() + return int(dt.timestamp()) else: return dt.strftime(self._datetime_format) @@ -173,15 +172,13 @@ def _get_date(self, cursor_value, default_date: datetime.datetime, comparator) - cursor_date = self.parse_date(cursor_value or default_date) return comparator(cursor_date, default_date) - def parse_date(self, date: Any) -> datetime: - if date and isinstance(date, str): - if self.is_int(date): - return datetime.datetime.fromtimestamp(int(date)).replace(tzinfo=self._timezone) - else: - return dateutil.parser.parse(date).replace(tzinfo=self._timezone) - elif isinstance(date, int): + def parse_date(self, date: Union[str, datetime.datetime]) -> datetime.datetime: + if self._datetime_format == "timestamp": return datetime.datetime.fromtimestamp(int(date)).replace(tzinfo=self._timezone) - return date + elif isinstance(date, str): + return datetime.datetime.strptime(str(date), self._datetime_format).replace(tzinfo=self._timezone) + else: + return date def is_int(self, s) -> bool: try: diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py index c34f4ada975d1..cdd5fe19094d3 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py @@ -443,5 +443,58 @@ def test_request_option(test_name, inject_into, field_name, expected_req_params, assert expected_body_data == slicer.request_body_data() +@pytest.mark.parametrize( + "test_name, input_date, date_format, expected_output_date", + [ + ( + "test_parse_date_iso", + "2021-01-01T00:00:00.000000+0000", + "%Y-%m-%dT%H:%M:%S.%f%z", + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + ), + ("test_parse_date_number", "20210101", "%Y%m%d", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)), + ( + "test_parse_date_datetime", + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + "%Y%m%d", + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + ), + ], +) +def test_parse_date(test_name, input_date, date_format, expected_output_date): + slicer = DatetimeStreamSlicer( + start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000"), + end_datetime=MinMaxDatetime("2021-01-10T00:00:00.000000+0000"), + step="1d", + cursor_field=InterpolatedString(cursor_field), + datetime_format=date_format, + lookback_window=InterpolatedString("0d"), + config=config, + ) + output_date = slicer.parse_date(input_date) + assert expected_output_date == output_date + + +@pytest.mark.parametrize( + "test_name, input_dt, datetimeformat, expected_output", + [ + ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "timestamp", 1609459200), + ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "2021-01-01"), + ], +) +def test_format_datetime(test_name, input_dt, datetimeformat, expected_output): + slicer = DatetimeStreamSlicer( + start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000"), + end_datetime=MinMaxDatetime("2021-01-10T00:00:00.000000+0000"), + step="1d", + cursor_field=InterpolatedString(cursor_field), + datetime_format=datetimeformat, + lookback_window=InterpolatedString("0d"), + config=config, + ) + output_date = slicer._format_datetime(input_dt) + assert expected_output == output_date + + if __name__ == "__main__": unittest.main() From 8c3f746f9dec3630f5c49811724b666151006263 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Thu, 4 Aug 2022 12:00:40 -0700 Subject: [PATCH 2/9] define constant --- .../declarative/stream_slicers/datetime_stream_slicer.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py index 536ad71c73eaa..562e0cff77fd8 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py @@ -4,7 +4,7 @@ import datetime import re -from typing import Any, Iterable, Mapping, Optional, Union +from typing import Any, Final, Iterable, Mapping, Optional, Union from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime @@ -14,6 +14,8 @@ from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState +TIMESTAMP_FORMAT: Final[str] = "timestamp" + class DatetimeStreamSlicer(StreamSlicer): """ @@ -153,7 +155,7 @@ def stream_slices(self, sync_mode: SyncMode, stream_state: Mapping[str, Any]) -> return dates def _format_datetime(self, dt: datetime.datetime): - if self._datetime_format == "timestamp": + if self._datetime_format == TIMESTAMP_FORMAT: return int(dt.timestamp()) else: return dt.strftime(self._datetime_format) @@ -173,7 +175,7 @@ def _get_date(self, cursor_value, default_date: datetime.datetime, comparator) - return comparator(cursor_date, default_date) def parse_date(self, date: Union[str, datetime.datetime]) -> datetime.datetime: - if self._datetime_format == "timestamp": + if self._datetime_format == TIMESTAMP_FORMAT: return datetime.datetime.fromtimestamp(int(date)).replace(tzinfo=self._timezone) elif isinstance(date, str): return datetime.datetime.strptime(str(date), self._datetime_format).replace(tzinfo=self._timezone) From 44b34838c66d6e4cfe7bf14bdd230afc112ea951 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Thu, 4 Aug 2022 16:11:56 -0700 Subject: [PATCH 3/9] remove timestamp magic keyword --- .../stream_slicers/datetime_stream_slicer.py | 20 +++---------------- .../test_datetime_stream_slicer.py | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py index 562e0cff77fd8..08481bedaabdc 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py @@ -4,7 +4,7 @@ import datetime import re -from typing import Any, Final, Iterable, Mapping, Optional, Union +from typing import Any, Iterable, Mapping, Optional, Union from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime @@ -14,8 +14,6 @@ from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState -TIMESTAMP_FORMAT: Final[str] = "timestamp" - class DatetimeStreamSlicer(StreamSlicer): """ @@ -155,10 +153,7 @@ def stream_slices(self, sync_mode: SyncMode, stream_state: Mapping[str, Any]) -> return dates def _format_datetime(self, dt: datetime.datetime): - if self._datetime_format == TIMESTAMP_FORMAT: - return int(dt.timestamp()) - else: - return dt.strftime(self._datetime_format) + return dt.strftime(self._datetime_format) def _partition_daterange(self, start, end, step: datetime.timedelta): start_field = self._stream_slice_field_start.eval(self._config) @@ -175,20 +170,11 @@ def _get_date(self, cursor_value, default_date: datetime.datetime, comparator) - return comparator(cursor_date, default_date) def parse_date(self, date: Union[str, datetime.datetime]) -> datetime.datetime: - if self._datetime_format == TIMESTAMP_FORMAT: - return datetime.datetime.fromtimestamp(int(date)).replace(tzinfo=self._timezone) - elif isinstance(date, str): + if isinstance(date, str): return datetime.datetime.strptime(str(date), self._datetime_format).replace(tzinfo=self._timezone) else: return date - def is_int(self, s) -> bool: - try: - int(s) - return True - except ValueError: - return False - @classmethod def _parse_timedelta(cls, time_str): """ diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py index cdd5fe19094d3..62f7e9f26d65d 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py @@ -478,7 +478,7 @@ def test_parse_date(test_name, input_date, date_format, expected_output_date): @pytest.mark.parametrize( "test_name, input_dt, datetimeformat, expected_output", [ - ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "timestamp", 1609459200), + ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609488000"), ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "2021-01-01"), ], ) From 6ce12436d3fdaaa07b335f2d2da3c23777d729f6 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Thu, 4 Aug 2022 16:15:32 -0700 Subject: [PATCH 4/9] comment --- .../sources/declarative/datetime/min_max_datetime.py | 4 ++++ .../declarative/stream_slicers/datetime_stream_slicer.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py index eb105803c1fde..a58e0d1103fc4 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py @@ -13,6 +13,10 @@ class MinMaxDatetime: Compares the provided date against optional minimum or maximum times. If date is earlier than min_date, then min_date is returned. If date is greater than max_date, then max_date is returned. If neither, the input date is returned. + + The timestamp format accepts the same format codes as datetime.strfptime, which are + all the format codes required by the 1989 C standard. + Full list of accepted format codes: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes """ def __init__( diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py index 08481bedaabdc..0b10a2d244516 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py @@ -30,6 +30,10 @@ class DatetimeStreamSlicer(StreamSlicer): - days, d For example, "1d" will produce windows of 1 day, and 2weeks windows of 2 weeks. + + The timestamp format accepts the same format codes as datetime.strfptime, which are + all the format codes required by the 1989 C standard. + Full list of accepted format codes: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes """ timedelta_regex = re.compile(r"((?P[\.\d]+?)w)?" r"((?P[\.\d]+?)d)?$") From f097032e828b7e966d984f1726b9a4f06c5f172e Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Fri, 5 Aug 2022 17:16:45 -0700 Subject: [PATCH 5/9] test for ci --- .../declarative/stream_slicers/test_datetime_stream_slicer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py index ac61685d29536..04698eca6b62f 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py @@ -481,7 +481,7 @@ def test_parse_date(test_name, input_date, date_format, expected_output_date): @pytest.mark.parametrize( "test_name, input_dt, datetimeformat, expected_output", [ - ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609488000"), + # ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609488000"), ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "2021-01-01"), ], ) From c6d5eb1adf16901bd2c09fd1f673f9dc4d4680e4 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Sun, 7 Aug 2022 10:19:02 -0700 Subject: [PATCH 6/9] uncomment test --- .../stream_slicers/test_datetime_stream_slicer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py index 04698eca6b62f..41c714366072d 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py @@ -481,7 +481,7 @@ def test_parse_date(test_name, input_date, date_format, expected_output_date): @pytest.mark.parametrize( "test_name, input_dt, datetimeformat, expected_output", [ - # ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609488000"), + ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609488000"), ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "2021-01-01"), ], ) @@ -496,7 +496,10 @@ def test_format_datetime(test_name, input_dt, datetimeformat, expected_output): config=config, options={}, ) + output_date = slicer._format_datetime(input_dt) + print(f"expected: {expected_output}") + print(f"actualoutput: {expected_output}") assert expected_output == output_date From d2eb71ff3e1dd3ab4749f8d50cccd0c4527c672f Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Sun, 7 Aug 2022 13:15:26 -0700 Subject: [PATCH 7/9] use timestamp() --- .../sources/declarative/datetime/min_max_datetime.py | 2 +- .../stream_slicers/datetime_stream_slicer.py | 12 +++++++++--- .../stream_slicers/test_datetime_stream_slicer.py | 4 +--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py index 29aab8586493c..0c4b5232cf696 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py @@ -19,7 +19,7 @@ class MinMaxDatetime(JsonSchemaMixin): The timestamp format accepts the same format codes as datetime.strfptime, which are all the format codes required by the 1989 C standard. - Full list of accepted format codes: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes + Full list of accepted format codes: https://man7.org/linux/man-pages/man3/strftime.3.html Attributes: datetime (Union[InterpolatedString, str]): InterpolatedString or string representing the datetime in the format specified by `datetime_format` diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py index 40dedec074ddd..c81d11e851298 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/datetime_stream_slicer.py @@ -36,7 +36,7 @@ class DatetimeStreamSlicer(StreamSlicer, JsonSchemaMixin): The timestamp format accepts the same format codes as datetime.strfptime, which are all the format codes required by the 1989 C standard. - Full list of accepted format codes: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes + Full list of accepted format codes: https://man7.org/linux/man-pages/man3/strftime.3.html Attributes: start_datetime (MinMaxDatetime): the datetime that determines the earliest record that should be synced @@ -131,7 +131,7 @@ def stream_slices(self, sync_mode: SyncMode, stream_state: Mapping[str, Any]) -> """ stream_state = stream_state or {} kwargs = {"stream_state": stream_state} - end_datetime = min(self.end_datetime.get_datetime(self.config, **kwargs), datetime.datetime.now(tz=datetime.timezone.utc)) + end_datetime = min(self.end_datetime.get_datetime(self.config, **kwargs), datetime.datetime.now(tz=self._timezone)) lookback_delta = self._parse_timedelta(self.lookback_window.eval(self.config, **kwargs) if self.lookback_window else "0d") start_datetime = self.start_datetime.get_datetime(self.config, **kwargs) - lookback_delta start_datetime = min(start_datetime, end_datetime) @@ -151,7 +151,13 @@ def stream_slices(self, sync_mode: SyncMode, stream_state: Mapping[str, Any]) -> return dates def _format_datetime(self, dt: datetime.datetime): - return dt.strftime(self.datetime_format) + # strftime("%s") is unreliable because it ignores the time zone information and assumes the time zone of the system it's running on + # It's safer to use the timestamp() method than the %s directive + # See https://stackoverflow.com/a/4974930 + if self.datetime_format == "%s": + return str(int(dt.timestamp())) + else: + return dt.strftime(self.datetime_format) def _partition_daterange(self, start, end, step: datetime.timedelta): start_field = self.stream_slice_field_start.eval(self.config) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py index 41c714366072d..e2321ad607f21 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/test_datetime_stream_slicer.py @@ -481,7 +481,7 @@ def test_parse_date(test_name, input_date, date_format, expected_output_date): @pytest.mark.parametrize( "test_name, input_dt, datetimeformat, expected_output", [ - ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609488000"), + ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609459200"), ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "2021-01-01"), ], ) @@ -498,8 +498,6 @@ def test_format_datetime(test_name, input_dt, datetimeformat, expected_output): ) output_date = slicer._format_datetime(input_dt) - print(f"expected: {expected_output}") - print(f"actualoutput: {expected_output}") assert expected_output == output_date From e085a96b5a913822940180d1d2cf95e8a6951326 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Mon, 8 Aug 2022 18:38:17 -0700 Subject: [PATCH 8/9] Bump cdk version --- airbyte-cdk/python/CHANGELOG.md | 3 +++ airbyte-cdk/python/setup.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/airbyte-cdk/python/CHANGELOG.md b/airbyte-cdk/python/CHANGELOG.md index 13e992aea7448..e64c5f6257954 100644 --- a/airbyte-cdk/python/CHANGELOG.md +++ b/airbyte-cdk/python/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.1.70 +- Bugfix: Fix bug in DatetimeStreamSlicer's parsing method + ## 0.1.70 - Bugfix: DatetimeStreamSlicer cast interpolated result to string before converting to datetime - Bugfix: Set stream slicer's request options in SimpleRetriever diff --git a/airbyte-cdk/python/setup.py b/airbyte-cdk/python/setup.py index 22643e5fced3d..960bb620b55b8 100644 --- a/airbyte-cdk/python/setup.py +++ b/airbyte-cdk/python/setup.py @@ -15,7 +15,7 @@ setup( name="airbyte-cdk", - version="0.1.70", + version="0.1.71", description="A framework for writing Airbyte Connectors.", long_description=README, long_description_content_type="text/markdown", From 58cb6fa7b0c89db4a3eced5e926c00a5a69062aa Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Mon, 8 Aug 2022 18:52:59 -0700 Subject: [PATCH 9/9] bump to 0.1.72 --- airbyte-cdk/python/CHANGELOG.md | 6 +++--- airbyte-cdk/python/setup.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/airbyte-cdk/python/CHANGELOG.md b/airbyte-cdk/python/CHANGELOG.md index 37870ebff76b2..7f0fa5574a952 100644 --- a/airbyte-cdk/python/CHANGELOG.md +++ b/airbyte-cdk/python/CHANGELOG.md @@ -1,14 +1,14 @@ # Changelog +## 0.1.72 +- Bugfix: Fix bug in DatetimeStreamSlicer's parsing method + ## 0.1.71 - Refactor declarative package to dataclasses - Bugfix: Requester header always converted to string - Bugfix: Reset paginator state between stream slices - Bugfix: Record selector handles single records -## 0.1.70 -- Bugfix: Fix bug in DatetimeStreamSlicer's parsing method - ## 0.1.70 - Bugfix: DatetimeStreamSlicer cast interpolated result to string before converting to datetime - Bugfix: Set stream slicer's request options in SimpleRetriever diff --git a/airbyte-cdk/python/setup.py b/airbyte-cdk/python/setup.py index 960bb620b55b8..ff3a17f010518 100644 --- a/airbyte-cdk/python/setup.py +++ b/airbyte-cdk/python/setup.py @@ -15,7 +15,7 @@ setup( name="airbyte-cdk", - version="0.1.71", + version="0.1.72", description="A framework for writing Airbyte Connectors.", long_description=README, long_description_content_type="text/markdown",