Skip to content

Commit

Permalink
Make str_to_interval not return a tuple for single-value input (#692)
Browse files Browse the repository at this point in the history
* Do not return tuple for single-value input

* Add PR reference to changelog

* update from main

---------

Co-authored-by: vincentsarago <[email protected]>
  • Loading branch information
avbentem and vincentsarago authored May 22, 2024
1 parent 5a4d5b9 commit d2fd4a6
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
* Switch from `fastapi` to `fastapi-slim` to avoid installing unwanted dependencies. ([#687](https://github.com/stac-utils/stac-fastapi/pull/687))
* Replace Enum with `Literal` for `FilterLang`. ([#686](https://github.com/stac-utils/stac-fastapi/pull/686))
* Update stac-pydantic requirement to `~3.1` ([#697](https://github.com/stac-utils/stac-fastapi/pull/697))
* Fix datetime interval for GET Search when passing a single value ([#697](https://github.com/stac-utils/stac-fastapi/pull/697))

### Removed

* Pystac as it was just used for a datetime to string function. ([#690](https://github.com/stac-utils/stac-fastapi/pull/690))

### Fixed

* Make `str_to_interval` not return a tuple for single-value input (fixing `datetime` argument as passed to `get_search`). ([#692](https://github.com/stac-utils/stac-fastapi/pull/692))

## [3.0.0a0] - 2024-05-06

### Added
Expand Down
15 changes: 8 additions & 7 deletions stac_fastapi/types/stac_fastapi/types/rfc3339.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,17 @@ def parse_single_date(date_str: str) -> datetime:

def str_to_interval(interval: Optional[str]) -> Optional[DateTimeType]:
"""
Extract a tuple of datetime objects from an interval string defined by the OGC API.
The interval can either be a single datetime or a range with start and end datetime.
Extract a single datetime object or a tuple of datetime objects from an
interval string defined by the OGC API. The interval can either be a
single datetime or a range with start and end datetime.
Args:
interval (Optional[str]): The interval string to convert to datetime objects,
or None if no datetime is specified.
Returns:
Optional[DateTimeType]: A tuple of datetime.datetime objects or
None if input is None.
Optional[DateTimeType]: A single datetime.datetime object, a tuple of
datetime.datetime objects, or None if input is None.
Raises:
HTTPException: If the string is not valid for various reasons such as being empty,
Expand All @@ -122,11 +123,11 @@ def str_to_interval(interval: Optional[str]) -> Optional[DateTimeType]:
detail="Interval string contains more than one forward slash.",
)

if len(values) == 1:
values = [values[0], values[0]]

try:
start = parse_single_date(values[0]) if values[0] not in ["..", ""] else None
if len(values) == 1:
return start

end = (
parse_single_date(values[1])
if len(values) > 1 and values[1] not in ["..", ""]
Expand Down
42 changes: 30 additions & 12 deletions stac_fastapi/types/tests/test_rfc3339.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import timezone
from datetime import datetime, timezone

import pytest
from fastapi import HTTPException
Expand Down Expand Up @@ -86,31 +86,49 @@ def test_parse_valid_str_to_datetime(test_input):


@pytest.mark.parametrize("test_input", invalid_intervals)
def test_parse_invalid_interval_to_datetime(test_input):
def test_str_to_interval_with_invalid_interval(test_input):
with pytest.raises(HTTPException) as exc_info:
str_to_interval(test_input)
assert (
exc_info.value.status_code == 400
), "Should return a 400 status code for invalid intervals"
), "str_to_interval should return a 400 status code for invalid interval"


@pytest.mark.parametrize("test_input", valid_intervals)
def test_parse_valid_interval_to_datetime(test_input):
assert str_to_interval(test_input)
@pytest.mark.parametrize("test_input", invalid_datetimes)
def test_str_to_interval_with_invalid_datetime(test_input):
with pytest.raises(HTTPException) as exc_info:
str_to_interval(test_input)
assert (
exc_info.value.status_code == 400
), "str_to_interval should return a 400 status code for invalid datetime"


def test_now_functions() -> None:
now1 = now_in_utc()
now2 = now_in_utc()
@pytest.mark.parametrize("test_input", valid_intervals)
def test_str_to_interval_with_valid_interval(test_input):
assert isinstance(
str_to_interval(test_input), tuple
), "str_to_interval should return tuple for multi-value input"

assert now1 < now2
assert now1.tzinfo == timezone.utc

rfc3339_str_to_datetime(now_to_rfc3339_str())
@pytest.mark.parametrize("test_input", valid_datetimes)
def test_str_to_interval_with_valid_datetime(test_input):
assert isinstance(
str_to_interval(test_input), datetime
), "str_to_interval should return single datetime for single-value input"


def test_str_to_interval_with_none():
"""Test that str_to_interval returns None when provided with None."""
assert (
str_to_interval(None) is None
), "str_to_interval should return None when input is None"


def test_now_functions() -> None:
now1 = now_in_utc()
now2 = now_in_utc()

assert now1 < now2
assert now1.tzinfo == timezone.utc

rfc3339_str_to_datetime(now_to_rfc3339_str())

0 comments on commit d2fd4a6

Please sign in to comment.