diff --git a/airbyte_cdk/sources/declarative/auth/oauth.py b/airbyte_cdk/sources/declarative/auth/oauth.py index 3133a544..22e5a0d7 100644 --- a/airbyte_cdk/sources/declarative/auth/oauth.py +++ b/airbyte_cdk/sources/declarative/auth/oauth.py @@ -122,18 +122,24 @@ def __post_init__(self, parameters: Mapping[str, Any]) -> None: self._refresh_request_headers = InterpolatedMapping( self.refresh_request_headers or {}, parameters=parameters ) - if isinstance(self.token_expiry_date, (int, str)) and str(self.token_expiry_date).isdigit(): - self._token_expiry_date = parse(self.token_expiry_date) - else: - self._token_expiry_date = ( - parse( - InterpolatedString.create(self.token_expiry_date, parameters=parameters).eval( - self.config + try: + if ( + isinstance(self.token_expiry_date, (int, str)) + and str(self.token_expiry_date).isdigit() + ): + self._token_expiry_date = parse(self.token_expiry_date) + else: + self._token_expiry_date = ( + parse( + InterpolatedString.create( + self.token_expiry_date, parameters=parameters + ).eval(self.config) ) + if self.token_expiry_date + else now() - timedelta(days=1) ) - if self.token_expiry_date - else now() - timedelta(days=1) - ) + except ValueError as e: + raise ValueError(f"Invalid token expiry date format: {e}") self.use_profile_assertion = ( InterpolatedBoolean(self.use_profile_assertion, parameters=parameters) if isinstance(self.use_profile_assertion, str) diff --git a/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py b/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py index 6c879c94..df3065c0 100644 --- a/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +++ b/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py @@ -191,14 +191,19 @@ def _parse_token_expiration_date(self, value: Union[str, int]) -> AirbyteDateTim raise ValueError( f"Invalid token expiry date format {self.token_expiry_date_format}; a string representing the format is required." ) - return parse(str(value)) + try: + return parse(str(value)) + except ValueError as e: + raise ValueError(f"Invalid token expiry date format: {e}") else: try: # Only accept numeric values (as int/float/string) when no format specified seconds = int(float(str(value))) return add_seconds(now(), seconds) except (ValueError, TypeError): - raise ValueError(f"Invalid expires_in value: {value}. Expected number of seconds when no format specified.") + raise ValueError( + f"Invalid expires_in value: {value}. Expected number of seconds when no format specified." + ) @property def token_expiry_is_time_of_expiration(self) -> bool: diff --git a/airbyte_cdk/utils/datetime_helpers.py b/airbyte_cdk/utils/datetime_helpers.py index 4348dab9..e2675eaf 100644 --- a/airbyte_cdk/utils/datetime_helpers.py +++ b/airbyte_cdk/utils/datetime_helpers.py @@ -63,12 +63,12 @@ def parse(dt_str: Union[str, int]) -> AirbyteDateTime: - Falls back to dateutil.parser for other string formats Always returns a timezone-aware datetime (defaults to UTC if no timezone specified). """ - if isinstance(dt_str, int) or (isinstance(dt_str, str) and dt_str.isdigit()): - timestamp = int(dt_str) - # Always treat numeric values as Unix timestamps - dt_obj = datetime.fromtimestamp(timestamp, tz=timezone.utc) - return AirbyteDateTime.from_datetime(dt_obj) try: + if isinstance(dt_str, int) or (isinstance(dt_str, str) and dt_str.isdigit()): + # Always treat numeric values as Unix timestamps + timestamp = int(dt_str) + dt_obj = datetime.fromtimestamp(timestamp, tz=timezone.utc) + return AirbyteDateTime.from_datetime(dt_obj) dt_obj = parser.parse(str(dt_str)) if dt_obj.tzinfo is None: dt_obj = dt_obj.replace(tzinfo=timezone.utc)