Skip to content

Commit

Permalink
FIX: Don't make pystac a mandatory requirement
Browse files Browse the repository at this point in the history
  • Loading branch information
remi-braun committed Jul 29, 2024
1 parent ef7e00b commit 9299196
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 61 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- FIX: Handle wrongly recognized Planet products because of the recursive nested mtd in the Reader ([#169](https://github.com/sertit/eoreader/issues/169))
- FIX: Force the loading of `DimapV1` bands in `float32`
- FIX: Handle the case where fiona isn't installed anymore (with `geopandas 1.0`)
- FIX: Don't make `pystac` a mandatory requirement
- OPTIM: Search correctly nested metadata in the Reader (without accidentally using a recursive glob)
- CI: Fix S3 endpoint management with `sertit>=1.37`

Expand Down
11 changes: 1 addition & 10 deletions eoreader/products/optical/landsat_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import xarray as xr
from lxml import etree
from lxml.builder import E
from pystac import Item
from rasterio.enums import Resampling
from sertit import AnyPath, path, rasters, rasters_rio
from sertit.misc import ListEnum
Expand Down Expand Up @@ -1865,16 +1864,8 @@ def __init__(
super_kwargs = kwargs.copy()

# Get STAC Item
self.item = None
self.item = self._set_item(product_path, **super_kwargs)
""" STAC Item of the product """
self.item = super_kwargs.pop("item", None)
if self.item is None:
try:
self.item = Item.from_file(product_path)
except TypeError:
raise InvalidProductError(
"You should either fill 'product_path' or 'item'."
)

if not self._is_mpc():
self.default_clients = [
Expand Down
12 changes: 1 addition & 11 deletions eoreader/products/optical/s2_e84_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import numpy as np
import xarray as xr
from lxml import etree
from pystac import Item
from rasterio.enums import Resampling
from sertit import AnyPath, files, path, rasters_rio
from sertit.files import CustomDecoder
Expand Down Expand Up @@ -795,16 +794,7 @@ def __init__(
super_kwargs = kwargs.copy()

# Get STAC Item
self.item = None
""" STAC Item of the product """
self.item = super_kwargs.pop("item", None)
if self.item is None:
try:
self.item = Item.from_file(product_path)
except TypeError:
raise InvalidProductError(
"You should either fill 'product_path' or 'item'."
)
self.item = self._set_item(product_path, **super_kwargs)

if not self._is_mpc():
self.default_clients = [self.get_e84_client(), self.get_sinergise_client()]
Expand Down
12 changes: 1 addition & 11 deletions eoreader/products/optical/s2_mpc_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@
import numpy as np
import xarray as xr
from lxml import etree
from pystac import Item
from sertit import AnyPath
from sertit.types import AnyPathStrType, AnyPathType

from eoreader import EOREADER_NAME
from eoreader.bands import BandNames
from eoreader.exceptions import InvalidProductError
from eoreader.products import S2E84Product
from eoreader.products.optical.optical_product import RawUnits
from eoreader.products.stac_product import StacProduct
Expand All @@ -54,16 +52,8 @@ def __init__(
super_kwargs = kwargs.copy()

# Get STAC Item
self.item = None
self.item = self._set_item(product_path, **super_kwargs)
""" STAC Item of the product """
self.item = super_kwargs.pop("item", None)
if self.item is None:
try:
self.item = Item.from_file(product_path)
except TypeError:
raise InvalidProductError(
"You should either fill 'product_path' or 'item'."
)

self.default_clients = []
self.clients = super_kwargs.pop("client", self.default_clients)
Expand Down
11 changes: 1 addition & 10 deletions eoreader/products/optical/s2_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import xarray as xr
from affine import Affine
from lxml import etree
from pystac import Item
from rasterio import errors, features, transform
from rasterio.crs import CRS
from rasterio.enums import Resampling
Expand Down Expand Up @@ -1725,16 +1724,8 @@ def __init__(
super_kwargs = kwargs.copy()

# Get STAC Item
self.item = None
self.item = self._set_item(product_path, **super_kwargs)
""" STAC Item of the product """
self.item = super_kwargs.pop("item", None)
if self.item is None:
try:
self.item = Item.from_file(product_path)
except TypeError:
raise InvalidProductError(
"You should either fill 'product_path' or 'item'."
)

if not self._is_mpc():
self.default_clients = [
Expand Down
11 changes: 1 addition & 10 deletions eoreader/products/sar/s1_rtc_mpc_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from typing import Union

from lxml import etree
from pystac import Item
from sertit import AnyPath, path, xml
from sertit.types import AnyPathStrType

Expand Down Expand Up @@ -61,16 +60,8 @@ def __init__(
super_kwargs = kwargs.copy()

# Get STAC Item
self.item = None
self.item = self._set_item(product_path, **super_kwargs)
""" STAC Item of the product """
self.item = super_kwargs.pop("item", None)
if self.item is None:
try:
self.item = Item.from_file(product_path)
except TypeError:
raise InvalidProductError(
"You should either fill 'product_path' or 'item'."
)

# Nothing here works for MPC
self.default_clients = []
Expand Down
33 changes: 33 additions & 0 deletions eoreader/products/stac_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,19 @@
from lxml import etree
from rasterio import crs
from sertit import geometry, path, rasters, vectors
from sertit.types import AnyPathStrType

from eoreader import EOREADER_NAME, cache
from eoreader.exceptions import InvalidProductError
from eoreader.products.product import Product
from eoreader.stac import PROJ_EPSG
from eoreader.utils import simplify

try:
from pystac import Item
except ModuleNotFoundError:
from typing import Any as Item

LOGGER = logging.getLogger(EOREADER_NAME)


Expand All @@ -45,6 +52,32 @@ class StacProduct(Product):
clients = None
default_clients = None

def _set_item(self, product_path: AnyPathStrType, **kwargs) -> Item:
"""
Set the STAC Item as member
Args:
product_path (AnyPathStrType): Product path
**kwargs: Other argumlents
"""
item = kwargs.pop("item", None)
if item is None:
try:
import pystac

item = pystac.Item.from_file(product_path)
except ModuleNotFoundError:
raise InvalidProductError(
"You should install 'pystac' to use STAC Products."
)

except TypeError:
raise InvalidProductError(
"You should either fill 'product_path' or 'item'."
)

return item

@cache
def extent(self) -> gpd.GeoDataFrame:
"""
Expand Down
42 changes: 33 additions & 9 deletions eoreader/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,24 @@
from typing import Union
from zipfile import BadZipFile

import pystac
import validators
from pystac import Item
from sertit import AnyPath, path, strings
from sertit.misc import ListEnum
from sertit.types import AnyPathStrType

from eoreader import EOREADER_NAME
from eoreader.exceptions import InvalidProductError

try:
import pystac
from pystac import Item

PYSTAC_INSTALLED = True
except ModuleNotFoundError:
from typing import Any as Item

PYSTAC_INSTALLED = False

LOGGER = logging.getLogger(EOREADER_NAME)


Expand Down Expand Up @@ -512,16 +520,32 @@ def open(
Returns:
Product: EOReader's product
"""
# If an URL is given, it must point to an URL translatable to a STAC Item
prod = None
# If a URL is given, it must point to a URL translatable to a STAC Item
if validators.url(product_path):
try:
product_path = pystac.Item.from_file(product_path)
except Exception:
raise InvalidProductError(
f"Cannot convert your URL ({product_path}) to a STAC Item."
if PYSTAC_INSTALLED:
try:
product_path = Item.from_file(product_path)
is_stac = True
except Exception:
raise InvalidProductError(
f"Cannot convert your URL ({product_path}) to a STAC Item."
)
else:
raise ModuleNotFoundError(
"You should install 'pystac' to use STAC Products."
)
# Check path (first check URL as they are also strings)
elif path.is_path(product_path):
is_stac = False
else:
# Check STAC Item
if PYSTAC_INSTALLED:
is_stac = isinstance(product_path, pystac.Item)
else:
is_stac = False

if isinstance(product_path, Item):
if is_stac:
prod = self._open_stac_item(product_path, output_path, remove_tmp, **kwargs)
else:
# If not an Item, it should be a path to somewhere
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ methodtools
matplotlib

# MPC, AWS and STAC
# /!\ Should not be mandatory requirements!
pystac[validation]
stac-asset
planetary_computer

0 comments on commit 9299196

Please sign in to comment.