Skip to content
This repository was archived by the owner on Apr 2, 2025. It is now read-only.

Commit 5f873cd

Browse files
author
Phil Varner
authored
refactor Order and OrderCollection to not extend Feature and FeatureCollection (#111)
1 parent 490c526 commit 5f873cd

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ none
4646
- Order field `id` must be a string, instead of previously allowing int. This is because while an
4747
order ID may an integral numeric value, it is not a "number" in the sense that math will be performed
4848
order ID values, so string represents this better.
49+
- Order and OrderCollection extend _GeoJsonBase instead of Feature and FeatureCollection, to allow for tighter
50+
constraints on fields
4951

5052
### Deprecated
5153

src/stapi_fastapi/models/order.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
from enum import StrEnum
2-
from typing import Any, Generic, Literal, Optional, TypeVar
2+
from typing import Any, Dict, Generic, Iterator, Literal, Optional, TypeVar, Union
33

4-
from geojson_pydantic import Feature, FeatureCollection
4+
from geojson_pydantic.base import _GeoJsonBase
55
from geojson_pydantic.geometries import Geometry
66
from pydantic import (
77
AwareDatetime,
88
BaseModel,
99
ConfigDict,
1010
Field,
1111
StrictStr,
12+
field_validator,
1213
)
1314

1415
from stapi_fastapi.models.opportunity import OpportunityProperties
1516
from stapi_fastapi.models.shared import Link
1617
from stapi_fastapi.types.datetime_interval import DatetimeInterval
1718
from stapi_fastapi.types.filter import CQL2Filter
1819

20+
Props = TypeVar("Props", bound=Union[Dict[str, Any], BaseModel])
21+
Geom = TypeVar("Geom", bound=Geometry)
22+
1923

2024
class OrderParameters(BaseModel):
2125
model_config = ConfigDict(extra="forbid")
@@ -71,14 +75,43 @@ class OrderProperties(BaseModel):
7175
model_config = ConfigDict(extra="allow")
7276

7377

74-
class Order(Feature[Geometry, OrderProperties]):
78+
# derived from geojson_pydantic.Feature
79+
class Order(_GeoJsonBase):
7580
# We need to enforce that orders have an id defined, as that is required to
7681
# retrieve them via the API
7782
id: StrictStr
7883
type: Literal["Feature"] = "Feature"
84+
85+
geometry: Geometry = Field(...)
86+
properties: OrderProperties = Field(...)
87+
7988
links: list[Link] = Field(default_factory=list)
8089

90+
__geojson_exclude_if_none__ = {"bbox", "id"}
91+
92+
@field_validator("geometry", mode="before")
93+
def set_geometry(cls, geometry: Any) -> Any:
94+
"""set geometry from geo interface or input"""
95+
if hasattr(geometry, "__geo_interface__"):
96+
return geometry.__geo_interface__
97+
98+
return geometry
8199

82-
class OrderCollection(FeatureCollection[Order]):
100+
101+
# derived from geojson_pydantic.FeatureCollection
102+
class OrderCollection(_GeoJsonBase):
83103
type: Literal["FeatureCollection"] = "FeatureCollection"
104+
features: list[Order]
84105
links: list[Link] = Field(default_factory=list)
106+
107+
def __iter__(self) -> Iterator[Order]: # type: ignore [override]
108+
"""iterate over features"""
109+
return iter(self.features)
110+
111+
def __len__(self) -> int:
112+
"""return features length"""
113+
return len(self.features)
114+
115+
def __getitem__(self, index: int) -> Order:
116+
"""get feature at a given index"""
117+
return self.features[index]

0 commit comments

Comments
 (0)