diff --git a/planet/api/filters.py b/planet/api/filters.py index 60abaabb9..baa07d9e9 100644 --- a/planet/api/filters.py +++ b/planet/api/filters.py @@ -100,8 +100,10 @@ def not_filter(*predicates): def date_range(field_name, **kwargs): '''Build a DateRangeFilter. - Predicate arguments accept a value str that in ISO-8601 format or a value - that has a `isoformat` callable that returns an ISO-8601 str. + Predicate arguments accept a str that is ISO-8601 format or a value + that has an `isoformat` callable that returns an ISO-8601 compliant str. + + If no timezone is provided, UTC is assumed for RFC 3339 compatability. :raises: ValueError if predicate value does not parse @@ -116,7 +118,12 @@ def date_range(field_name, **kwargs): dt = strp_lenient(str(v)) if dt is None: raise ValueError("unable to use provided time: " + str(v)) - kwargs[k] = dt.isoformat() + 'Z' + iso_date = dt.isoformat() + if not dt.tzinfo: + # assume UTC for datetimes without an explicit timezone + # necessary for RFC 3339 vs ISO 8601 compatability + iso_date += 'Z' + kwargs[k] = iso_date return _filter('DateRangeFilter', config=kwargs, field_name=field_name) diff --git a/tests/test_filters.py b/tests/test_filters.py new file mode 100644 index 000000000..ccbcd7dd6 --- /dev/null +++ b/tests/test_filters.py @@ -0,0 +1,27 @@ +import pytest +from pytz import timezone +from datetime import datetime +from planet.api import filters + + +@pytest.mark.parametrize('dt, expected', [ + (datetime(1900, 1, 1, tzinfo=timezone("US/Central")), + {'field_name': 'acquired', + 'type': 'DateRangeFilter', + 'config': {'gte': '1900-01-01T00:00:00-05:51'}}), + + (datetime(1999, 12, 31), + {'field_name': 'acquired', + 'type': 'DateRangeFilter', + 'config': {'gte': '1999-12-31T00:00:00Z'}}), + + ("2018-01-01", + {'field_name': 'acquired', + 'type': 'DateRangeFilter', + 'config': {'gte': '2018-01-01T00:00:00Z'}}), +]) +def test_date_range(dt, expected): + fieldname = "acquired" + arg = "gte" + + assert filters.date_range(fieldname, **{arg: dt}) == expected diff --git a/tests/test_utils.py b/tests/test_utils.py index 00b440571..53dafbc81 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -148,7 +148,7 @@ def test_get_filename_from_url(url, expected): @pytest.mark.parametrize('content_type,check', [ (None, lambda x: re.match(r'^planet-[a-z0-9]{8}$', x, re.I) is not None), - ('image/tiff', lambda x: x.endswith('.tif')), + ('image/tiff', lambda x: x.endswith(('.tif', '.tiff'))), ]) def test_get_random_filename(content_type, check): assert check(utils.get_random_filename(content_type)) diff --git a/tox.ini b/tox.ini index a410f231e..ab3b9d2b6 100644 --- a/tox.ini +++ b/tox.ini @@ -4,10 +4,10 @@ # and then run "tox" from this directory. [tox] -envlist = py27, py34, py35, py36, py37 +envlist = py27, py36, py37 [testenv] deps = pytest commands = pip install -e .[dev] - pytest + pytest {posargs}