diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 4c5c705b3..f4a40416b 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -85,7 +85,13 @@ jobs: cd stac_fastapi/api && pipenv run pytest -svvv env: ENVIRONMENT: testing - + + - name: Run test suite + run: | + cd stac_fastapi/types && pipenv run pytest -svvv + env: + ENVIRONMENT: testing + - name: Run test suite run: | cd stac_fastapi/sqlalchemy && pipenv run pytest -svvv diff --git a/CHANGES.md b/CHANGES.md index 5fe0a9f99..ae2bd0f1e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ ### Removed ### Fixed +* `ciso8601` fails to build in some environments, instead use `pyiso8601` to parse datetimes. ## [2.4.0] diff --git a/stac_fastapi/types/setup.py b/stac_fastapi/types/setup.py index 3d9f77ef9..85f4e6c1f 100644 --- a/stac_fastapi/types/setup.py +++ b/stac_fastapi/types/setup.py @@ -11,7 +11,7 @@ "pydantic[dotenv]", "stac_pydantic==2.0.*", "pystac==1.*", - "ciso8601~=2.2.0", + "iso8601~=1.0.2", ] extra_reqs = { diff --git a/stac_fastapi/types/stac_fastapi/types/rfc3339.py b/stac_fastapi/types/stac_fastapi/types/rfc3339.py index 0ba460034..6e3f97761 100644 --- a/stac_fastapi/types/stac_fastapi/types/rfc3339.py +++ b/stac_fastapi/types/stac_fastapi/types/rfc3339.py @@ -1,16 +1,18 @@ """rfc3339.""" - +import re from datetime import datetime, timezone from typing import Optional, Tuple -import ciso8601 +import iso8601 from pystac.utils import datetime_to_str +RFC33339_PATTERN = r"^(\d\d\d\d)\-(\d\d)\-(\d\d)(T|t)(\d\d):(\d\d):(\d\d)([.]\d+)?(Z|([-+])(\d\d):(\d\d))$" + def rfc3339_str_to_datetime(s: str) -> datetime: """Convert a string conforming to RFC 3339 to a :class:`datetime.datetime`. - Uses :meth:`ciso8601.parse_rfc3339` under the hood. + Uses :meth:`iso8601.parse_date` under the hood. Args: s (str) : The string to convert to :class:`datetime.datetime`. @@ -21,7 +23,16 @@ def rfc3339_str_to_datetime(s: str) -> datetime: Raises: ValueError: If the string is not a valid RFC 3339 string. """ - return ciso8601.parse_rfc3339(s) + # Uppercase the string + s = s.upper() + + # Match against RFC3339 regex. + result = re.match(RFC33339_PATTERN, s) + if not result: + raise ValueError("Invalid RFC3339 datetime.") + + # Parse with pyiso8601 + return iso8601.parse_date(s) def str_to_interval(