From 8351530914de3e07021e2dbcf43b95543f91a1f2 Mon Sep 17 00:00:00 2001 From: Theodore Reuter Date: Tue, 4 Feb 2025 15:55:36 -0500 Subject: [PATCH 1/3] fix: reworked search opportunity request model so limit and paginatino token are in POST body, and changed tests and implementation to refelct this change in the model --- src/stapi_fastapi/models/opportunity.py | 2 ++ src/stapi_fastapi/routers/product_router.py | 20 +++++++---------- tests/test_opportunity.py | 24 ++++++++++----------- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/stapi_fastapi/models/opportunity.py b/src/stapi_fastapi/models/opportunity.py index 930cfcf..54c1acf 100644 --- a/src/stapi_fastapi/models/opportunity.py +++ b/src/stapi_fastapi/models/opportunity.py @@ -22,6 +22,8 @@ class OpportunityRequest(BaseModel): # TODO: validate the CQL2 filter? filter: CQL2Filter | None = None model_config = ConfigDict(strict=True) + next: str | None = None + limit: int = 10 G = TypeVar("G", bound=Geometry) diff --git a/src/stapi_fastapi/routers/product_router.py b/src/stapi_fastapi/routers/product_router.py index 8dbd031..175c763 100644 --- a/src/stapi_fastapi/routers/product_router.py +++ b/src/stapi_fastapi/routers/product_router.py @@ -2,9 +2,9 @@ import logging import traceback -from typing import TYPE_CHECKING, Annotated, Self +from typing import TYPE_CHECKING, Self -from fastapi import APIRouter, Body, HTTPException, Request, Response, status +from fastapi import APIRouter, HTTPException, Request, Response, status from geojson_pydantic.geometries import Geometry from returns.maybe import Some from returns.result import Failure, Success @@ -165,8 +165,6 @@ async def search_opportunities( self, search: OpportunityRequest, request: Request, - next: Annotated[str | None, Body()] = None, - limit: Annotated[int, Body()] = 10, ) -> OpportunityCollection: """ Explore the opportunities available for a particular set of constraints @@ -175,18 +173,16 @@ async def search_opportunities( match await self.product._search_opportunities( self, search, - next, - limit, + search.next, + search.limit, request, ): case Success((features, Some(pagination_token))): links.append(self.order_link(request)) - body = { - "search": search.model_dump(mode="json"), - "next": pagination_token, - "limit": limit, - } - links.append(self.pagination_link(request, body)) + search.next = pagination_token + links.append( + self.pagination_link(request, search.model_dump(mode="json")) + ) case Success((features, Nothing)): # noqa: F841 links.append(self.order_link(request)) case Failure(e) if isinstance(e, ConstraintsException): diff --git a/tests/test_opportunity.py b/tests/test_opportunity.py index 389d47d..577ab1a 100644 --- a/tests/test_opportunity.py +++ b/tests/test_opportunity.py @@ -81,19 +81,17 @@ def test_search_opportunities_pagination( end_string = rfc3339_strftime(end, format) request_payload = { - "search": { - "geometry": { - "type": "Point", - "coordinates": [0, 0], - }, - "datetime": f"{start_string}/{end_string}", - "filter": { - "op": "and", - "args": [ - {"op": ">", "args": [{"property": "off_nadir"}, 0]}, - {"op": "<", "args": [{"property": "off_nadir"}, 45]}, - ], - }, + "geometry": { + "type": "Point", + "coordinates": [0, 0], + }, + "datetime": f"{start_string}/{end_string}", + "filter": { + "op": "and", + "args": [ + {"op": ">", "args": [{"property": "off_nadir"}, 0]}, + {"op": "<", "args": [{"property": "off_nadir"}, 45]}, + ], }, "limit": limit, } From 5a017874b54b7845b0d26408a4cab3c2f45dd931 Mon Sep 17 00:00:00 2001 From: Theodore Reuter Date: Tue, 4 Feb 2025 16:03:43 -0500 Subject: [PATCH 2/3] tests: fix other test that broke from OpportunityRequest model change --- tests/test_opportunity.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/tests/test_opportunity.py b/tests/test_opportunity.py index 577ab1a..bfb604d 100644 --- a/tests/test_opportunity.py +++ b/tests/test_opportunity.py @@ -24,19 +24,17 @@ def test_search_opportunities_response( end_string = rfc3339_strftime(end, format) request_payload = { - "search": { - "geometry": { - "type": "Point", - "coordinates": [0, 0], - }, - "datetime": f"{start_string}/{end_string}", - "filter": { - "op": "and", - "args": [ - {"op": ">", "args": [{"property": "off_nadir"}, 0]}, - {"op": "<", "args": [{"property": "off_nadir"}, 45]}, - ], - }, + "geometry": { + "type": "Point", + "coordinates": [0, 0], + }, + "datetime": f"{start_string}/{end_string}", + "filter": { + "op": "and", + "args": [ + {"op": ">", "args": [{"property": "off_nadir"}, 0]}, + {"op": "<", "args": [{"property": "off_nadir"}, 45]}, + ], }, "limit": 10, } From 8a4c3c33e2c12d9b48b210a59a59ab10a6198a09 Mon Sep 17 00:00:00 2001 From: Theodore Reuter Date: Tue, 4 Feb 2025 16:34:19 -0500 Subject: [PATCH 3/3] readability clean up on OpportunityRequest model --- src/stapi_fastapi/models/opportunity.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stapi_fastapi/models/opportunity.py b/src/stapi_fastapi/models/opportunity.py index 54c1acf..0de3385 100644 --- a/src/stapi_fastapi/models/opportunity.py +++ b/src/stapi_fastapi/models/opportunity.py @@ -21,10 +21,11 @@ class OpportunityRequest(BaseModel): geometry: Geometry # TODO: validate the CQL2 filter? filter: CQL2Filter | None = None - model_config = ConfigDict(strict=True) next: str | None = None limit: int = 10 + model_config = ConfigDict(strict=True) + G = TypeVar("G", bound=Geometry) P = TypeVar("P", bound=OpportunityProperties)