Skip to content

Collection.from_dict fails with type error if spatial extent is explicitly null #1551

@philvarner

Description

@philvarner

This code (being used for the pystac-client Quickstart):

from pystac_client import Client
from pystac import Collection
import json



client = Client.open("https://emc.spacebel.be")

collection_search = client.collection_search(
        q='SEALEVEL_EUR_PHY_L3_NRT_008_059',
    )
print(f"{collection_search.matched()} collections found")

for collection in collection_search.collections_as_dicts():
        print(collection.get("id"))
        print(json.dumps(collection.get("extent")))
        Collection.from_dict(collection)

This fails because the spatial extent of the collection is explicitly null. This collection advertises it is stac_version 1.0.0. Null extent is invalid wrt the spec, but the tooling should be more permissive it what it will process.

The extent is:

{
  "spatial": null,
  "temporal": {
    "interval": [
      [
        "2022-01-01T00:00:00.000Z",
        null
      ]
    ]
  }
}

Exception is:

TypeError                                 Traceback (most recent call last)
Cell In[12], line 10
      5 collection_search = client.collection_search(
      6         q='Sentinel-6',
      7     )
      8 print(f"{collection_search.matched()} collections found")
---> 10 for collection in collection_search.collections():
     11         print(collection.id)

File ~/code/stac-utils/pystac-client/pystac_client/collection_search.py:395, in CollectionSearch.collections(self)
    387 """Iterator that yields :class:`pystac.Collection` instances for each collection
    388 matching the given search parameters.
    389 
    390 Yields:
    391     Collection : each Collection matching the search criteria
    392 """
    393 for collection in self.collections_as_dicts():
    394     # already signed in collections_as_dicts
--> 395     yield Collection.from_dict(
    396         collection, root=self.client, preserve_dict=False
    397     )

File ~/code/stac-utils/pystac-client/.venv/lib/python3.12/site-packages/pystac/collection.py:654, in Collection.from_dict(cls, d, href, root, migrate, preserve_dict)
    652 description = d.pop("description")
    653 license = d.pop("license")
--> 654 extent = Extent.from_dict(d.pop("extent"))
    655 title = d.pop("title", None)
    656 stac_extensions = d.pop("stac_extensions", None)

File ~/code/stac-utils/pystac-client/.venv/lib/python3.12/site-packages/pystac/collection.py:366, in Extent.from_dict(d)
    358 @staticmethod
    359 def from_dict(d: dict[str, Any]) -> Extent:
    360     """Constructs an Extent from a dict.
    361 
    362     Returns:
    363         Extent: The Extent deserialized from the JSON dict.
    364     """
    365     return Extent(
--> 366         spatial=SpatialExtent.from_dict(d["spatial"]),
    367         temporal=TemporalExtent.from_dict(d["temporal"]),
    368         extra_fields={
    369             k: v for k, v in d.items() if k not in {"spatial", "temporal"}
    370         },
    371     )

File ~/code/stac-utils/pystac-client/.venv/lib/python3.12/site-packages/pystac/collection.py:118, in SpatialExtent.from_dict(d)
    110 @staticmethod
    111 def from_dict(d: dict[str, Any]) -> SpatialExtent:
    112     """Constructs a SpatialExtent from a dict.
    113 
    114     Returns:
    115         SpatialExtent: The SpatialExtent deserialized from the JSON dict.
    116     """
    117     return SpatialExtent(
--> 118         bboxes=d["bbox"], extra_fields={k: v for k, v in d.items() if k != "bbox"}
    119     )

TypeError: 'NoneType' object is not subscriptable

I think it would be reasonable (though not desired) to fail to deserialize invalid items, but with an explicit error as to why it could not be deserialized. In this case, it's just an accidental TypeError from trying to subscript None.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions