Skip to content

Commit 451fd57

Browse files
authored
Merge branch 'main' into dependabot/pip/sphinx-8.1.3
2 parents 777d76d + 9f5249f commit 451fd57

File tree

6 files changed

+99
-11
lines changed

6 files changed

+99
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
- Add netCDF to pystac.media_type ([#1386](https://github.com/stac-utils/pystac/pull/1386))
1414
- Add convenience method for accessing pystac_client ([#1365](https://github.com/stac-utils/pystac/pull/1365))
1515
- Fix field ordering when saving `Item`s ([#1423](https://github.com/stac-utils/pystac/pull/1423))
16+
- Add keywords to common metadata ([#1443](https://github.com/stac-utils/pystac/pull/1443))
17+
- Add roles to common metadata ([#1444](https://github.com/stac-utils/pystac/pull/1444/files))
1618

1719
### Changed
1820

@@ -22,6 +24,7 @@
2224
- Add example of custom `StacIO` for Azure Blob Storage to docs ([#1372](https://github.com/stac-utils/pystac/pull/1372))
2325
- Noted that collection links can be used in non-item objects in STAC v1.1.0 ([#1393](https://github.com/stac-utils/pystac/pull/1393))
2426
- Move test, docs, and bench requirements out of pyproject.toml ([#1407](https://github.com/stac-utils/pystac/pull/1407))
27+
- Clarify inclusive datetime ranges, update default license, and ensure description is not empty ([#1445](https://github.com/stac-utils/pystac/pull/1445))
2528

2629
### Fixed
2730

pystac/collection.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,10 @@ class Collection(Catalog, Assets):
461461
be one of the values in :class`~pystac.CatalogType`.
462462
license : Collection's license(s) as a
463463
`SPDX License identifier <https://spdx.org/licenses/>`_,
464-
`various`, or `proprietary`. If collection includes
465-
data with multiple different licenses, use `various` and add a link for
466-
each. Defaults to 'proprietary'.
464+
or `other`. If collection includes data with multiple
465+
different licenses, use `other` and add a link for
466+
each. The licenses `various` and `proprietary` are deprecated.
467+
Defaults to 'other'.
467468
keywords : Optional list of keywords describing the collection.
468469
providers : Optional list of providers of this Collection.
469470
summaries : An optional map of property summaries,
@@ -528,7 +529,7 @@ def __init__(
528529
href: str | None = None,
529530
extra_fields: dict[str, Any] | None = None,
530531
catalog_type: CatalogType | None = None,
531-
license: str = "proprietary",
532+
license: str = "other",
532533
keywords: list[str] | None = None,
533534
providers: list[Provider] | None = None,
534535
summaries: Summaries | None = None,

pystac/common_metadata.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,18 @@ def description(self) -> str | None:
8080

8181
@description.setter
8282
def description(self, v: str | None) -> None:
83+
if v == "":
84+
raise ValueError("description cannot be an empty string")
8385
self._set_field("description", v)
8486

8587
# Date and Time Range
8688
@property
8789
def start_datetime(self) -> datetime | None:
88-
"""Get or set the object's start_datetime."""
90+
"""Get or set the object's start_datetime.
91+
92+
Note:
93+
``start_datetime`` is an inclusive datetime.
94+
"""
8995
return utils.map_opt(
9096
utils.str_to_datetime, self._get_field("start_datetime", str)
9197
)
@@ -96,7 +102,11 @@ def start_datetime(self, v: datetime | None) -> None:
96102

97103
@property
98104
def end_datetime(self) -> datetime | None:
99-
"""Get or set the item's end_datetime."""
105+
"""Get or set the item's end_datetime.
106+
107+
Note:
108+
``end_datetime`` is an inclusive datetime.
109+
"""
100110
return utils.map_opt(
101111
utils.str_to_datetime, self._get_field("end_datetime", str)
102112
)
@@ -108,7 +118,15 @@ def end_datetime(self, v: datetime | None) -> None:
108118
# License
109119
@property
110120
def license(self) -> str | None:
111-
"""Get or set the current license."""
121+
"""Get or set the current license. License should be provided
122+
as a `SPDX License identifier <https://spdx.org/licenses/>`_,
123+
or `other`. If object includes data with multiple
124+
different licenses, use `other` and add a link for
125+
each.
126+
127+
Note:
128+
The licenses `various` and `proprietary` are deprecated.
129+
"""
112130
return self._get_field("license", str)
113131

114132
@license.setter
@@ -213,3 +231,21 @@ def updated(self) -> datetime | None:
213231
@updated.setter
214232
def updated(self, v: datetime | None) -> None:
215233
self._set_field("updated", utils.map_opt(utils.datetime_to_str, v))
234+
235+
@property
236+
def keywords(self) -> list[str] | None:
237+
"""Get or set the keywords describing the STAC entity."""
238+
return self._get_field("keywords", list[str])
239+
240+
@keywords.setter
241+
def keywords(self, v: list[str] | None) -> None:
242+
self._set_field("keywords", v)
243+
244+
@property
245+
def roles(self) -> list[str] | None:
246+
"""Get or set the semantic roles of the entity."""
247+
return self._get_field("roles", list[str])
248+
249+
@roles.setter
250+
def roles(self, v: list[str] | None) -> None:
251+
self._set_field("roles", v)

pystac/item.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ class Item(STACObject, Assets):
5151
datetime : datetime associated with this item. If None,
5252
a start_datetime and end_datetime must be supplied.
5353
properties : A dictionary of additional metadata for the item.
54-
start_datetime : Optional start datetime, part of common metadata. This value
55-
will override any `start_datetime` key in properties.
56-
end_datetime : Optional end datetime, part of common metadata. This value
57-
will override any `end_datetime` key in properties.
54+
start_datetime : Optional inclusive start datetime, part of common metadata.
55+
This value will override any `start_datetime` key in properties.
56+
end_datetime : Optional inclusive end datetime, part of common metadata.
57+
This value will override any `end_datetime` key in properties.
5858
stac_extensions : Optional list of extensions the Item implements.
5959
href : Optional HREF for this item, which be set as the item's
6060
self link's HREF.

tests/data-files/item/sample-item-asset-properties.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
"start_datetime": "2017-05-01T13:22:30.040Z",
7575
"end_datetime": "2017-05-02T13:22:30.040Z",
7676
"license": "CC-BY-4.0",
77+
"keywords": ["keyword_a"],
78+
"roles": ["a_role"],
7779
"providers": [
7880
{
7981
"name": "USGS",

tests/test_common_metadata.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ def test_common_metadata_basics(self) -> None:
176176
x.common_metadata.description = example_description
177177
self.assertEqual(x.common_metadata.description, example_description)
178178
self.assertEqual(x.properties["description"], example_description)
179+
with self.assertRaises(ValueError):
180+
x.common_metadata.description = ""
179181

180182
# License
181183
license = "PDDL-1.0"
@@ -538,3 +540,47 @@ def test_updated(self) -> None:
538540
self.assertEqual(
539541
analytic.to_dict()["updated"], utils.datetime_to_str(set_value)
540542
)
543+
544+
def test_keywords(self) -> None:
545+
item = self.item.clone()
546+
cm = item.common_metadata
547+
analytic = item.assets["analytic"]
548+
analytic_cm = CommonMetadata(analytic)
549+
thumbnail = item.assets["thumbnail"]
550+
thumbnail_cm = CommonMetadata(thumbnail)
551+
552+
item_value = cm.keywords
553+
a2_known_value = ["keyword_a"]
554+
555+
# Get
556+
self.assertNotEqual(thumbnail_cm.keywords, item_value)
557+
self.assertEqual(thumbnail_cm.keywords, a2_known_value)
558+
559+
# Set
560+
set_value = ["keyword_b"]
561+
analytic_cm.keywords = set_value
562+
563+
self.assertEqual(analytic_cm.keywords, set_value)
564+
self.assertEqual(analytic.to_dict()["keywords"], set_value)
565+
566+
def test_roles(self) -> None:
567+
item = self.item.clone()
568+
cm = item.common_metadata
569+
analytic = item.assets["analytic"]
570+
analytic_cm = CommonMetadata(analytic)
571+
thumbnail = item.assets["thumbnail"]
572+
thumbnail_cm = CommonMetadata(thumbnail)
573+
574+
item_value = cm.roles
575+
a2_known_value = ["a_role"]
576+
577+
# Get
578+
self.assertNotEqual(thumbnail_cm.roles, item_value)
579+
self.assertEqual(thumbnail_cm.roles, a2_known_value)
580+
581+
# Set
582+
set_value = ["another_role"]
583+
analytic_cm.roles = set_value
584+
585+
self.assertEqual(analytic_cm.roles, set_value)
586+
self.assertEqual(analytic.to_dict()["roles"], set_value)

0 commit comments

Comments
 (0)