Skip to content

Commit

Permalink
fix #1483 (#1484)
Browse files Browse the repository at this point in the history
* fix #1483

* add a test for #1483

* fix: rewrite cassette

* fix: formatting

---------

Co-authored-by: Pete Gadomski <[email protected]>
  • Loading branch information
remicres and gadomski authored Dec 17, 2024
1 parent 97f87cb commit e611092
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 2 deletions.
6 changes: 4 additions & 2 deletions pystac/extensions/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,10 @@ def apply(
or bitfields is None
and classes is not None
), "Must set exactly one of `classes` or `bitfields`"
self.classes = classes
self.bitfields = bitfields
if classes:
self.classes = classes
if bitfields:
self.bitfields = bitfields

@property
def classes(self) -> list[Classification] | None:
Expand Down
153 changes: 153 additions & 0 deletions tests/extensions/cassettes/test_classification/test_apply_classes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
interactions:
- request:
body: null
headers:
Connection:
- close
Host:
- stac-extensions.github.io
User-Agent:
- Python-urllib/3.12
method: GET
uri: https://stac-extensions.github.io/classification/v2.0.0/schema.json
response:
body:
string: "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\":
\"https://stac-extensions.github.io/classification/v2.0.0/schema.json#\",\n
\ \"title\": \"Classification Extension\",\n \"description\": \"STAC Classification
Extension for STAC Items and STAC Collections.\",\n \"type\": \"object\",\n
\ \"required\": [\"stac_extensions\"],\n \"properties\": {\n \"stac_extensions\":
{\n \"type\": \"array\",\n \"contains\": {\n \"const\": \"https://stac-extensions.github.io/classification/v2.0.0/schema.json\"\n
\ }\n }\n },\n \"oneOf\": [\n {\n \"$comment\": \"This is
the schema for STAC Items.\",\n \"type\": \"object\",\n \"required\":
[\"type\", \"properties\", \"assets\"],\n \"properties\": {\n \"type\":
{\n \"const\": \"Feature\"\n },\n \"properties\": {\n
\ \"$comment\": \"This validates the fields in Item Properties, but
does not require them.\",\n \"allOf\": [\n {\n \"$ref\":
\"#/definitions/fields\"\n },\n {\n \"$ref\":
\"#/definitions/ml_model_output\"\n }\n ]\n },\n
\ \"assets\": {\n \"$comment\": \"This validates the fields
in Item Assets (including in Raster Band Objects), but does not require them.\",\n
\ \"type\": \"object\",\n \"additionalProperties\": {\n \"allOf\":
[\n {\n \"$ref\": \"#/definitions/fields\"\n },\n
\ {\n \"$ref\": \"#/definitions/raster_bands\"\n
\ },\n {\n \"$ref\": \"#/definitions/ml_model_output\"\n
\ }\n ]\n }\n }\n }\n },\n
\ {\n \"$comment\": \"This is the schema for STAC Collections.\",\n
\ \"type\": \"object\",\n \"required\": [\"type\"],\n \"properties\":
{\n \"type\": {\n \"const\": \"Collection\"\n },\n
\ \"assets\": {\n \"$comment\": \"This validates the fields
in Collection Assets, but does not require them.\",\n \"type\": \"object\",\n
\ \"additionalProperties\": {\n \"allOf\": [\n {\n
\ \"$ref\": \"#/definitions/fields\"\n },\n {\n
\ \"$ref\": \"#/definitions/raster_bands\"\n },\n
\ {\n \"$ref\": \"#/definitions/ml_model_output\"\n
\ }\n ]\n }\n },\n \"item_assets\":
{\n \"$comment\": \"This validates the fields in Item Asset Definitions,
but does not require them.\",\n \"type\": \"object\",\n \"additionalProperties\":
{\n \"allOf\": [\n {\n \"$ref\": \"#/definitions/fields\"\n
\ },\n {\n \"$ref\": \"#/definitions/raster_bands\"\n
\ },\n {\n \"$ref\": \"#/definitions/ml_model_output\"\n
\ }\n ]\n }\n },\n \"summaries\":
{\n \"$comment\": \"This validates the fields in Summaries, but does
not require them.\",\n \"$ref\": \"#/definitions/fields\"\n }\n
\ }\n }\n ],\n \"definitions\": {\n \"require_any_field\": {\n
\ \"$comment\": \"Please list all fields here so that we can force the
existance of one of them in other parts of the schemas.\",\n \"anyOf\":
[\n {\n \"required\": [\"classification:bitfields\"]\n },\n
\ {\n \"required\": [\"classification:classes\"]\n }\n
\ ]\n },\n \"fields\": {\n \"$comment\": \"Add your new fields
here. Don't require them here, do that above in the corresponding schema.\",\n
\ \"type\": \"object\",\n \"properties\": {\n \"classification:bitfields\":
{\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"minItems\":
1,\n \"items\": {\n \"$ref\": \"#/definitions/bit_field_object\"\n
\ }\n },\n \"classification:classes\": {\n \"type\":
\"array\",\n \"uniqueItems\": true,\n \"minItems\": 1,\n
\ \"items\": {\n \"$ref\": \"#/definitions/class_object\"\n
\ }\n }\n },\n \"patternProperties\": {\n \"^(?!classification:)\":
{}\n },\n \"additionalProperties\": false\n },\n \"class_object\":
{\n \"$comment\": \"Object for storing classes\",\n \"type\": \"object\",\n
\ \"required\": [\"value\", \"name\"],\n \"properties\": {\n \"value\":
{\n \"type\": \"integer\"\n },\n \"description\": {\n
\ \"type\": \"string\"\n },\n \"name\": {\n \"type\":
\"string\",\n \"pattern\": \"^[0-9A-Za-z-_]+$\"\n },\n \"title\":
{\n \"type\": \"string\"\n },\n \"color_hint\": {\n
\ \"type\": \"string\",\n \"pattern\": \"^([0-9A-Fa-f]{6})$\"\n
\ },\n \"nodata\": {\n \"type\": \"boolean\"\n },\n
\ \"percentage\": {\n \"type\": \"number\",\n \"minimum\":
0,\n \"maximum\": 100\n },\n \"count\": {\n \"type\":
\"integer\",\n \"minimum\": 0\n }\n }\n },\n \"bit_field_object\":
{\n \"$comment\": \"Object for storing bit fields\",\n \"type\":
\"object\",\n \"required\": [\"offset\", \"length\", \"classes\"],\n
\ \"properties\": {\n \"offset\": {\n \"type\": \"integer\",\n
\ \"minimum\": 0\n },\n \"length\": {\n \"type\":
\"integer\",\n \"minimum\": 1\n },\n \"classes\": {\n
\ \"type\": \"array\",\n \"uniqueItems\": true,\n \"minItems\":
1,\n \"items\": {\n \"$ref\": \"#/definitions/class_object\"\n
\ }\n },\n \"roles\": {\n \"type\": \"array\",\n
\ \"uniqueItems\": true,\n \"minItems\": 1,\n \"items\":
{\n \"type\": \"string\"\n }\n },\n \"description\":
{\n \"type\": \"string\"\n },\n \"name\": {\n \"type\":
\"string\",\n \"pattern\": \"^[0-9A-Za-z-_]+$\"\n }\n }\n
\ },\n \"raster_bands\": {\n \"$comment\": \"Classification fields
on the Raster Extension raster:bands object\",\n \"type\": \"object\",\n
\ \"properties\": {\n \"raster:bands\": {\n \"type\":
\"array\",\n \"items\": {\n \"$ref\": \"#/definitions/fields\"\n
\ }\n }\n }\n },\n \"ml_model_output\": {\n \"$comment\":
\"Classification fields on the MLM Extension mlm:output objects (https://crim-ca.github.io/mlm-extension/v1.0.0/schema.json).\",\n
\ \"description\": \"Describes the classes embedded in the output of the
ML model following inference.\",\n \"type\": \"object\",\n \"properties\":
{\n \"mlm:output\": {\n \"type\": \"array\",\n \"items\":
{\n \"$ref\": \"#/definitions/fields\"\n }\n }\n
\ }\n }\n }\n}\n"
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- '*'
Age:
- '0'
Cache-Control:
- max-age=600
Connection:
- close
Content-Length:
- '6554'
Content-Type:
- application/json; charset=utf-8
Date:
- Tue, 17 Dec 2024 23:25:05 GMT
ETag:
- '"66487a48-199a"'
Last-Modified:
- Sat, 18 May 2024 09:52:08 GMT
Server:
- GitHub.com
Strict-Transport-Security:
- max-age=31556952
Vary:
- Accept-Encoding
Via:
- 1.1 varnish
X-Cache:
- MISS
X-Cache-Hits:
- '0'
X-Fastly-Request-ID:
- eaacd335ebd5f2b35eecf0fbe0ad4f9d82ef2870
X-GitHub-Request-Id:
- CB53:15BE6F:C16B48:D70A6A:67620851
X-Served-By:
- cache-den-kden1300056-DEN
X-Timer:
- S1734477906.551532,VS0,VE74
expires:
- Tue, 17 Dec 2024 23:35:05 GMT
permissions-policy:
- interest-cohort=()
x-proxy-cache:
- MISS
status:
code: 200
message: OK
version: 1
19 changes: 19 additions & 0 deletions tests/extensions/test_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,25 @@ def test_apply_bitfields(plain_item: Item) -> None:
)


@pytest.mark.vcr()
def test_apply_classes(plain_item: Item) -> None:
ClassificationExtension.add_to(plain_item)
ClassificationExtension.ext(plain_item).apply(
classes=[
Classification.create(name="no", value=0),
Classification.create(name="yes", value=1),
]
)
plain_item.validate()
assert (
ClassificationExtension.ext(plain_item).classes is not None
and len(
cast(list[Classification], ClassificationExtension.ext(plain_item).classes)
)
== 2
)


def test_create_classes(plain_item: Item) -> None:
ClassificationExtension.add_to(plain_item)
ext = ClassificationExtension.ext(plain_item)
Expand Down

0 comments on commit e611092

Please sign in to comment.