pystac
pystac copied to clipboard
Automatically modifying STAC objects using a custom `StacIO`
Following up from this discussion in the STAC Gitter. I created this issue for a discussion on the topic of ~automatically modifying STAC objects read with pystac
a la pystac_client
's support for automatically modifying results.
It is possible to define a custom StacIO
class that overrides the StacIO.stac_object_from_dict
method to pass the deserialized STAC object to a modifier function (e.g., planetary_computer.sign_inplace
) before returning it:
from functools import wraps
import planetary_computer
import pystac
from pystac.stac_io import DefaultStacIO, StacIO
# Define custom StacIO that overrides stac_object_from_dict to pass StacObject to signing modifier
class PCStacIO(DefaultStacIO):
@wraps(StacIO.stac_object_from_dict)
def stac_object_from_dict(
self,
*args,
**kwargs,
) -> pystac.STACObject:
return planetary_computer.sign_inplace(
super().stac_object_from_dict(*args, **kwargs)
)
# Usage:
item_href = "https://planetarycomputer.microsoft.com/api/stac/v1/collections/sentinel-2-l2a/items/S2B_MSIL2A_20240723T205029_R057_T16XDN_20240723T231445"
item = pystac.read_file(
item_href,
stac_io=PCStacIO(), # pass instance of PCStacIO
)
# Asset HREFs have been signed
print(item.assets)
# Alternatively, set PCStacIO as default StacIO
StacIO.set_default(PCStacIO)
item = pystac.read_file(item_href)
print(item.assets)
When I wrote the custom StacIO
class I naively expected that the pystac.Item.from_file
would use the StacIO.stac_object_from_dict
method, but that is not the case. Invoking the modifier requires reading the STAC objects with the pystac.read_file
method. This is because the pystac.STACObject.from_file
methods do not rely on StacIO.stac_object_from_dict
(in fact the latter relies on the former).
Thinking "out loud" about how to enable the pystac.STACObject.from_file
... add a _modifier
class variable that is a Callable[[Modifiable], STACObject]
and have the STACObject.from_file
methods optionally apply the _modifier
if it is set? I don't love it...
That said, it's not clear whether there is any demand for enabling this functionality when using the pystac.read_file
or separately and explicitly passing STAC objects to a modifier function approaches work just as well. Using the from_file
approach would appease mypy
w/o the need for cast
ing, but that's a pretty minor DevX nit tbh. Maybe this example is informative enough for the docs?
All feedback is welcome.