Skip to content

Commit b451b0f

Browse files
author
Phil Varner
committed
refactor use of starlette.datastructures.URL
1 parent bae2b49 commit b451b0f

File tree

4 files changed

+38
-41
lines changed

4 files changed

+38
-41
lines changed

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

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
GET_QUERYABLES,
4848
SEARCH_OPPORTUNITIES,
4949
)
50+
from stapi_fastapi.routers.utils import json_link
5051

5152
if TYPE_CHECKING:
5253
from stapi_fastapi.routers import RootRouter
@@ -201,28 +202,24 @@ async def _create_order(
201202

202203
def get_product(self, request: Request) -> ProductPydantic:
203204
links = [
204-
Link(
205+
json_link(
205206
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{GET_PRODUCT}"),
206207
rel="self",
207-
type=TYPE_JSON,
208208
),
209-
Link(
209+
json_link(
210210
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{CONFORMANCE}"),
211211
rel="conformance",
212-
type=TYPE_JSON,
213212
),
214-
Link(
213+
json_link(
215214
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{GET_QUERYABLES}"),
216215
rel="queryables",
217-
type=TYPE_JSON,
218216
),
219-
Link(
217+
json_link(
220218
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{GET_ORDER_PARAMETERS}"),
221219
rel="order-parameters",
222-
type=TYPE_JSON,
223220
),
224221
Link(
225-
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{CREATE_ORDER}"),
222+
href=str(self.url_for(request, f"{self.root_router.name}:{self.product.id}:{CREATE_ORDER}")),
226223
rel="create-order",
227224
type=TYPE_JSON,
228225
method="POST",
@@ -233,10 +230,9 @@ def get_product(self, request: Request) -> ProductPydantic:
233230
self.product.supports_async_opportunity_search and self.root_router.supports_async_opportunity_search
234231
):
235232
links.append(
236-
Link(
233+
json_link(
237234
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{SEARCH_OPPORTUNITIES}"),
238235
rel="opportunities",
239-
type=TYPE_JSON,
240236
),
241237
)
242238

@@ -396,7 +392,7 @@ async def create_order(self, payload: OrderPayload, request: Request, response:
396392

397393
def order_link(self, request: Request, opp_req: OpportunityPayload) -> Link:
398394
return Link(
399-
href=self.url_for(request, f"{self.root_router.name}:{self.product.id}:{CREATE_ORDER}"),
395+
href=str(self.url_for(request, f"{self.root_router.name}:{self.product.id}:{CREATE_ORDER}")),
400396
rel="create-order",
401397
type=TYPE_JSON,
402398
method="POST",
@@ -407,7 +403,7 @@ def pagination_link(self, request: Request, opp_req: OpportunityPayload, paginat
407403
body = opp_req.body()
408404
body["next"] = pagination_token
409405
return Link(
410-
href=request.url,
406+
href=str(request.url),
411407
rel="next",
412408
type=TYPE_JSON,
413409
method="POST",
@@ -427,14 +423,13 @@ async def get_opportunity_collection(
427423
):
428424
case Success(Some(opportunity_collection)):
429425
opportunity_collection.links.append(
430-
Link(
426+
json_link(
431427
href=self.url_for(
432428
request,
433429
f"{self.root_router.name}:{self.product.id}:{GET_OPPORTUNITY_COLLECTION}",
434430
opportunity_collection_id=opportunity_collection_id,
435431
),
436432
rel="self",
437-
type=TYPE_JSON,
438433
),
439434
)
440435
return opportunity_collection # type: ignore

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

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
GetOrderStatuses,
3030
)
3131
from stapi_fastapi.conformance import API as API_CONFORMANCE
32-
from stapi_fastapi.constants import TYPE_GEOJSON, TYPE_JSON
32+
from stapi_fastapi.constants import TYPE_GEOJSON
3333
from stapi_fastapi.errors import NotFoundError
3434
from stapi_fastapi.models.product import Product
3535
from stapi_fastapi.responses import GeoJSONResponse
@@ -46,6 +46,7 @@
4646
LIST_PRODUCTS,
4747
ROOT,
4848
)
49+
from stapi_fastapi.routers.utils import json_link
4950

5051
logger = logging.getLogger(__name__)
5152

@@ -174,44 +175,39 @@ def __init__(
174175

175176
def get_root(self, request: Request) -> RootResponse:
176177
links = [
177-
Link(
178+
json_link(
178179
href=self.url_for(request, f"{self.name}:{ROOT}"),
179180
rel="self",
180-
type=TYPE_JSON,
181181
),
182-
Link(
182+
json_link(
183183
href=self.url_for(request, self.openapi_endpoint_name),
184184
rel="service-description",
185-
type=TYPE_JSON,
186185
),
187186
Link(
188-
href=self.url_for(request, self.docs_endpoint_name),
187+
href=str(self.url_for(request, self.docs_endpoint_name)),
189188
rel="service-docs",
190189
type="text/html",
191190
),
192-
Link(
191+
json_link(
193192
href=self.url_for(request, f"{self.name}:{CONFORMANCE}"),
194193
rel="conformance",
195-
type=TYPE_JSON,
196194
),
197-
Link(
195+
json_link(
198196
href=self.url_for(request, f"{self.name}:{LIST_PRODUCTS}"),
199197
rel="products",
200-
type=TYPE_JSON,
201198
),
202199
Link(
203-
href=self.url_for(request, f"{self.name}:{LIST_ORDERS}"),
200+
href=str(self.url_for(request, f"{self.name}:{LIST_ORDERS}")),
204201
rel="orders",
205202
type=TYPE_GEOJSON,
206203
),
207204
]
208205

209206
if self.supports_async_opportunity_search:
210207
links.append(
211-
Link(
208+
json_link(
212209
href=self.url_for(request, f"{self.name}:{LIST_OPPORTUNITY_SEARCH_RECORDS}"),
213210
rel="opportunity-search-records",
214-
type=TYPE_JSON,
215211
),
216212
)
217213

@@ -236,10 +232,9 @@ def get_products(self, request: Request, next: str | None = None, limit: int = 1
236232
end = start + limit
237233
ids = self.product_ids[start:end]
238234
links = [
239-
Link(
235+
json_link(
240236
href=self.url_for(request, f"{self.name}:{LIST_PRODUCTS}"),
241237
rel="self",
242-
type=TYPE_JSON,
243238
),
244239
]
245240
if end > 0 and end < len(self.product_ids):
@@ -364,33 +359,30 @@ def generate_order_statuses_href(self, request: Request, order_id: str) -> URL:
364359
def order_links(self, order: Order[OrderStatus], request: Request) -> list[Link]:
365360
return [
366361
Link(
367-
href=self.generate_order_href(request, order.id),
362+
href=str(self.generate_order_href(request, order.id)),
368363
rel="self",
369364
type=TYPE_GEOJSON,
370365
),
371-
Link(
366+
json_link(
372367
href=self.generate_order_statuses_href(request, order.id),
373368
rel="monitor",
374-
type=TYPE_JSON,
375369
),
376370
]
377371

378372
def order_statuses_link(self, request: Request, order_id: str) -> Link:
379-
return Link(
373+
return json_link(
380374
href=self.url_for(
381375
request,
382376
f"{self.name}:{LIST_ORDER_STATUSES}",
383377
order_id=order_id,
384378
),
385379
rel="self",
386-
type=TYPE_JSON,
387380
)
388381

389382
def pagination_link(self, request: Request, name: str, pagination_token: str, limit: int, **kwargs: Any) -> Link:
390-
return Link(
383+
return json_link(
391384
href=self.url_for(request, name, **kwargs).include_query_params(next=pagination_token, limit=limit),
392385
rel="next",
393-
type=TYPE_JSON,
394386
)
395387

396388
async def get_opportunity_search_records(
@@ -482,10 +474,9 @@ def generate_opportunity_search_record_href(self, request: Request, search_recor
482474
def opportunity_search_record_self_link(
483475
self, opportunity_search_record: OpportunitySearchRecord, request: Request
484476
) -> Link:
485-
return Link(
477+
return json_link(
486478
href=self.generate_opportunity_search_record_href(request, opportunity_search_record.id),
487479
rel="self",
488-
type=TYPE_JSON,
489480
)
490481

491482
@property
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from stapi_pydantic import Link
2+
from starlette.datastructures import URL
3+
4+
from stapi_fastapi.constants import TYPE_JSON
5+
6+
7+
def json_link(href: URL, rel: str) -> Link:
8+
return Link(
9+
href=str(href),
10+
rel=rel,
11+
type=TYPE_JSON,
12+
)

stapi-pydantic/src/stapi_pydantic/shared.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
SerializerFunctionWrapHandler,
88
model_serializer,
99
)
10-
from starlette.datastructures import URL
1110

1211

1312
class Link(BaseModel):
@@ -23,7 +22,7 @@ class Link(BaseModel):
2322

2423
# redefining init is a hack to get str type to validate for `href`,
2524
# as str is ultimately coerced into an AnyUrl automatically anyway
26-
def __init__(self, href: AnyUrl | URL | str, **kwargs: Any) -> None:
25+
def __init__(self, href: AnyUrl | str, **kwargs: Any) -> None:
2726
super().__init__(href=str(href), **kwargs)
2827

2928
# overriding the default serialization to filter None field values from

0 commit comments

Comments
 (0)