Skip to content

Commit

Permalink
refactor Order and OrderCollection to not extend Feature and FeatureC…
Browse files Browse the repository at this point in the history
…ollection
  • Loading branch information
philvarner committed Nov 22, 2024
1 parent 3125efc commit 099b500
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ none
- Order field `id` must be a string, instead of previously allowing int. This is because while an
order ID may an integral numeric value, it is not a "number" in the sense that math will be performed
order ID values, so string represents this better.
- Order and OrderCollection extend _GeoJsonBase instead of Feature and FeatureCollection, to allow for tighter
constraints on fields

### Deprecated

Expand Down
41 changes: 37 additions & 4 deletions src/stapi_fastapi/models/order.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
from enum import Enum
from typing import Any, Generic, Literal, Optional, TypeVar
from typing import Any, Dict, Generic, Iterator, Literal, Optional, TypeVar, Union

from geojson_pydantic import Feature, FeatureCollection
from geojson_pydantic.base import _GeoJsonBase
from geojson_pydantic.geometries import Geometry
from pydantic import (
AwareDatetime,
BaseModel,
ConfigDict,
Field,
StrictStr,
field_validator,
)

from stapi_fastapi.models.opportunity import OpportunityProperties
from stapi_fastapi.models.shared import Link
from stapi_fastapi.types.datetime_interval import DatetimeInterval
from stapi_fastapi.types.filter import CQL2Filter

Props = TypeVar("Props", bound=Union[Dict[str, Any], BaseModel])
Geom = TypeVar("Geom", bound=Geometry)


class OrderParameters(BaseModel):
model_config = ConfigDict(extra="forbid")
Expand Down Expand Up @@ -71,14 +75,43 @@ class OrderProperties(BaseModel):
model_config = ConfigDict(extra="allow")


class Order(Feature[Geometry, OrderProperties]):
# derived from geojson_pydantic.Feature
class Order(_GeoJsonBase):
# We need to enforce that orders have an id defined, as that is required to
# retrieve them via the API
id: StrictStr
type: Literal["Feature"] = "Feature"

geometry: Geometry | None = Field(...)
properties: OrderProperties | None = Field(...)

links: list[Link] = Field(default_factory=list)

__geojson_exclude_if_none__ = {"bbox", "id"}

@field_validator("geometry", mode="before")
def set_geometry(cls, geometry: Any) -> Any:
"""set geometry from geo interface or input"""
if hasattr(geometry, "__geo_interface__"):
return geometry.__geo_interface__

return geometry

class OrderCollection(FeatureCollection[Order]):

# derived from geojson_pydantic.FeatureCollection
class OrderCollection(_GeoJsonBase):
type: Literal["FeatureCollection"] = "FeatureCollection"
features: list[Order]
links: list[Link] = Field(default_factory=list)

def __iter__(self) -> Iterator[Order]: # type: ignore [override]
"""iterate over features"""
return iter(self.features)

def __len__(self) -> int:
"""return features length"""
return len(self.features)

def __getitem__(self, index: int) -> Order:
"""get feature at a given index"""
return self.features[index]

0 comments on commit 099b500

Please sign in to comment.