Skip to content

Commit 9a35025

Browse files
author
Phil Varner
committed
add typing to support variable OrderStatus objects
1 parent 3f766b1 commit 9a35025

3 files changed

Lines changed: 20 additions & 16 deletions

File tree

stapi-fastapi/src/stapi_fastapi/backends/root_backend.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
OrderStatus,
1212
)
1313

14+
T = TypeVar("T", bound=OrderStatus)
15+
1416
GetOrders = Callable[
1517
[str | None, int, Request],
16-
Coroutine[Any, Any, ResultE[tuple[list[Order[OrderStatus]], Maybe[str], Maybe[int]]]],
18+
Coroutine[Any, Any, ResultE[tuple[list[Order[T]], Maybe[str], Maybe[int]]]],
1719
]
1820
"""
1921
Type alias for an async function that returns a list of existing Orders.
@@ -48,9 +50,6 @@
4850
"""
4951

5052

51-
T = TypeVar("T", bound=OrderStatus)
52-
53-
5453
GetOrderStatuses = Callable[
5554
[str, str | None, int, Request],
5655
Coroutine[Any, Any, ResultE[Maybe[tuple[list[T], Maybe[str]]]]],

stapi-fastapi/src/stapi_fastapi/routers/product_router.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import logging
44
import traceback
5-
from typing import TYPE_CHECKING, Any
5+
from typing import TYPE_CHECKING, Any, TypeVar
66

77
from fastapi import (
88
Depends,
@@ -68,7 +68,10 @@ def get_prefer(prefer: str | None = Header(None)) -> str | None:
6868
return Prefer(prefer)
6969

7070

71-
def build_conformances(product: Product, root_router: RootRouter) -> list[str]:
71+
T = TypeVar("T", bound=OrderStatus)
72+
73+
74+
def build_conformances(product: Product, root_router: RootRouter[T]) -> list[str]:
7275
# FIXME we can make this check more robust
7376
if not any(conformance.startswith("https://geojson.org/schema/") for conformance in product.conformsTo):
7477
raise ValueError("product conformance does not contain at least one geojson conformance")
@@ -90,7 +93,7 @@ class ProductRouter(StapiFastapiBaseRouter):
9093
def __init__( # noqa
9194
self,
9295
product: Product,
93-
root_router: RootRouter,
96+
root_router: RootRouter[T],
9497
*args: Any,
9598
**kwargs: Any,
9699
) -> None:

stapi-fastapi/src/stapi_fastapi/routers/root_router.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import traceback
3-
from typing import Any
3+
from typing import Any, Generic, TypeVar
44

55
from fastapi import HTTPException, Request, status
66
from fastapi.datastructures import URL
@@ -50,11 +50,13 @@
5050

5151
logger = logging.getLogger(__name__)
5252

53+
T = TypeVar("T", bound=OrderStatus)
5354

54-
class RootRouter(StapiFastapiBaseRouter):
55+
56+
class RootRouter(StapiFastapiBaseRouter, Generic[T]):
5557
def __init__(
5658
self,
57-
get_orders: GetOrders,
59+
get_orders: GetOrders[T],
5860
get_order: GetOrder,
5961
get_order_statuses: GetOrderStatuses | None = None, # type: ignore
6062
get_opportunity_search_records: GetOpportunitySearchRecords | None = None,
@@ -240,7 +242,7 @@ def get_products(self, request: Request, next: str | None = None, limit: int = 1
240242

241243
async def get_orders( # noqa: C901
242244
self, request: Request, next: str | None = None, limit: int = 10
243-
) -> OrderCollection[OrderStatus]:
245+
) -> OrderCollection[T]:
244246
links: list[Link] = []
245247
orders_count: int | None = None
246248
match await self._get_orders(next, limit, request):
@@ -271,13 +273,13 @@ async def get_orders( # noqa: C901
271273
case _:
272274
raise AssertionError("Expected code to be unreachable")
273275

274-
return OrderCollection(
276+
return OrderCollection[T](
275277
features=orders,
276278
links=links,
277279
number_matched=orders_count,
278280
)
279281

280-
async def get_order(self, order_id: str, request: Request) -> Order[OrderStatus]:
282+
async def get_order(self, order_id: str, request: Request) -> Order[T]:
281283
"""
282284
Get details for order with `order_id`.
283285
"""
@@ -306,7 +308,7 @@ async def get_order_statuses(
306308
request: Request,
307309
next: str | None = None,
308310
limit: int = 10,
309-
) -> OrderStatuses: # type: ignore
311+
) -> OrderStatuses[T]:
310312
links: list[Link] = []
311313
match await self._get_order_statuses(order_id, next, limit, request):
312314
case Success(Some((statuses, maybe_pagination_token))):
@@ -350,7 +352,7 @@ def generate_order_href(self, request: Request, order_id: str) -> URL:
350352
def generate_order_statuses_href(self, request: Request, order_id: str) -> URL:
351353
return self.url_for(request, f"{self.name}:{LIST_ORDER_STATUSES}", order_id=order_id)
352354

353-
def order_links(self, order: Order[OrderStatus], request: Request) -> list[Link]:
355+
def order_links(self, order: Order[T], request: Request) -> list[Link]:
354356
return [
355357
Link(
356358
href=self.generate_order_href(request, order.id),
@@ -464,7 +466,7 @@ def opportunity_search_record_self_link(
464466
return json_link("self", self.generate_opportunity_search_record_href(request, opportunity_search_record.id))
465467

466468
@property
467-
def _get_order_statuses(self) -> GetOrderStatuses: # type: ignore
469+
def _get_order_statuses(self) -> GetOrderStatuses[T]:
468470
if not self.__get_order_statuses:
469471
raise AttributeError("Root router does not support order status history")
470472
return self.__get_order_statuses

0 commit comments

Comments
 (0)