Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Set created/updated item properties TDE-1147 #980

Merged
merged 3 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions scripts/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ def format_rfc_3339_nz_midnight_datetime_string(datetime_object: datetime) -> st
return format_rfc_3339_datetime_string(datetime_utc)


def utc_now() -> datetime:
"""
Get the current datetime with UTC time zone

Should return something close to the current time:
>>> current_timestamp = datetime.now().timestamp()
>>> current_timestamp - 5 < utc_now().timestamp() < current_timestamp + 5
True

Should have UTC time zone:
>>> utc_now().tzname()
'UTC'
"""
return datetime.now(tz=timezone.utc)


class NaiveDatetimeError(Exception):
def __init__(self) -> None:
super().__init__("Can't convert naive datetime to UTC")
3 changes: 2 additions & 1 deletion scripts/stac/imagery/create_stac.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from linz_logger import get_log

from scripts.datetimes import utc_now
from scripts.files.files_helper import get_file_name_from_path
from scripts.files.geotiff import get_extents
from scripts.gdal.gdal_helper import gdal_info
Expand Down Expand Up @@ -35,7 +36,7 @@ def create_item(

geometry, bbox = get_extents(gdalinfo_result)

item = ImageryItem(id_, file)
item = ImageryItem(id_, file, utc_now)
item.update_datetime(start_datetime, end_datetime)
item.update_spatial(geometry, bbox)
item.add_collection(collection_id)
Expand Down
7 changes: 5 additions & 2 deletions scripts/stac/imagery/item.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from typing import Any, Dict, Tuple
from datetime import datetime
from typing import Any, Callable, Dict, Tuple

from scripts.datetimes import format_rfc_3339_datetime_string
from scripts.files import fs
Expand All @@ -12,9 +13,10 @@
class ImageryItem:
stac: Dict[str, Any]

def __init__(self, id_: str, file: str) -> None:
def __init__(self, id_: str, file: str, now: Callable[[], datetime]) -> None:
file_content = fs.read(file)
file_modified_datetime = format_rfc_3339_datetime_string(modified(file))
now_string = format_rfc_3339_datetime_string(now())
self.stac = {
"type": "Feature",
"stac_version": STAC_VERSION,
Expand All @@ -32,6 +34,7 @@ def __init__(self, id_: str, file: str) -> None:
}
},
"stac_extensions": [StacExtensions.file.value],
"properties": {"created": now_string, "updated": now_string},
}

def update_datetime(self, start_datetime: str, end_datetime: str) -> None:
Expand Down
36 changes: 26 additions & 10 deletions scripts/stac/imagery/tests/collection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
from datetime import datetime, timezone
from shutil import rmtree
from tempfile import mkdtemp
from typing import Generator
from typing import Callable, Generator

import pytest
import shapely.geometry
from pytest_subtests import SubTests

from scripts.datetimes import format_rfc_3339_datetime_string
from scripts.files.fs import read
from scripts.stac.imagery.collection import ImageryCollection
from scripts.stac.imagery.item import ImageryItem
Expand Down Expand Up @@ -113,12 +114,20 @@ def test_interval_updated_from_existing(metadata: CollectionMetadata) -> None:
assert collection.stac["extent"]["temporal"]["interval"] == [["2021-01-27T00:00:00Z", "2021-02-20T00:00:00Z"]]


def fixed_now_function(now: datetime) -> Callable[[], datetime]:
def func() -> datetime:
return now

return func


def test_add_item(metadata: CollectionMetadata, subtests: SubTests) -> None:
collection = ImageryCollection(metadata)
item_file_path = "./scripts/tests/data/empty.tiff"
modified_datetime = datetime(2001, 2, 3, hour=4, minute=5, second=6, tzinfo=timezone.utc)
os.utime(item_file_path, times=(any_epoch_datetime().timestamp(), modified_datetime.timestamp()))
item = ImageryItem("BR34_5000_0304", item_file_path)
now = any_epoch_datetime()
item = ImageryItem("BR34_5000_0304", item_file_path, fixed_now_function(now))
geometry = {
"type": "Polygon",
"coordinates": [[1799667.5, 5815977.0], [1800422.5, 5815977.0], [1800422.5, 5814986.0], [1799667.5, 5814986.0]],
Expand All @@ -131,13 +140,17 @@ def test_add_item(metadata: CollectionMetadata, subtests: SubTests) -> None:

collection.add_item(item.stac)

with subtests.test():
assert {
"file:checksum": "122097b5d2b049c6ffdf608af28c4ba2744fad7f03046d1f58b2523402f30577f618",
"rel": "item",
"href": "./BR34_5000_0304.json",
"type": "application/json",
} in collection.stac["links"]
links = collection.stac["links"].copy()

with subtests.test(msg="File checksum heuristic"):
# The checksum changes based on the contents
assert links[1].pop("file:checksum").startswith("1220")

with subtests.test(msg="Main links content"):
assert [
{"href": "./collection.json", "rel": "self", "type": "application/json"},
{"rel": "item", "href": "./BR34_5000_0304.json", "type": "application/json"},
] == links

with subtests.test():
assert collection.stac["extent"]["temporal"]["interval"] == [[start_datetime, end_datetime]]
Expand All @@ -146,7 +159,10 @@ def test_add_item(metadata: CollectionMetadata, subtests: SubTests) -> None:
assert collection.stac["extent"]["spatial"]["bbox"] == [bbox]

for property_name in ["created", "updated"]:
with subtests.test(msg=f"{property_name} property"):
with subtests.test(msg=f"item properties.{property_name}"):
assert item.stac["properties"][property_name] == format_rfc_3339_datetime_string(now)

with subtests.test(msg=f"item assets.visual.{property_name}"):
assert item.stac["assets"]["visual"][property_name] == "2001-02-03T04:05:06Z"


Expand Down
5 changes: 3 additions & 2 deletions scripts/stac/imagery/tests/item_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from scripts.stac.imagery.collection import ImageryCollection
from scripts.stac.imagery.item import ImageryItem
from scripts.stac.imagery.metadata_constants import CollectionMetadata
from scripts.tests.datetimes_test import any_epoch_datetime


def test_imagery_stac_item(mocker: MockerFixture, subtests: SubTests) -> None:
Expand All @@ -23,7 +24,7 @@ def test_imagery_stac_item(mocker: MockerFixture, subtests: SubTests) -> None:
start_datetime = "2021-01-27T00:00:00Z"
end_datetime = "2021-01-27T00:00:00Z"

item = ImageryItem(id_, path)
item = ImageryItem(id_, path, any_epoch_datetime)
item.update_spatial(geometry, bbox)
item.update_datetime(start_datetime, end_datetime)
# checks
Expand Down Expand Up @@ -77,7 +78,7 @@ def test_imagery_add_collection(mocker: MockerFixture, subtests: SubTests) -> No
path = "./scripts/tests/data/empty.tiff"
id_ = get_file_name_from_path(path)
mocker.patch("scripts.files.fs.read", return_value=b"")
item = ImageryItem(id_, path)
item = ImageryItem(id_, path, any_epoch_datetime)

item.add_collection(collection.stac["id"])

Expand Down
Loading