22import traceback
33from typing import Any
44
5- from fastapi import APIRouter , HTTPException , Request , status
5+ from fastapi import HTTPException , Request , status
66from returns .maybe import Maybe , Some
77from returns .result import Failure , Success
88from stapi_pydantic import (
1818 ProductsCollection ,
1919 RootResponse ,
2020)
21+ from starlette .datastructures import URL
2122
2223from stapi_fastapi .backends .root_backend import (
2324 GetOpportunitySearchRecord ,
3233from stapi_fastapi .errors import NotFoundError
3334from stapi_fastapi .models .product import Product
3435from stapi_fastapi .responses import GeoJSONResponse
36+ from stapi_fastapi .routers .base import StapiFastapiBaseRouter
3537from stapi_fastapi .routers .product_router import ProductRouter
3638from stapi_fastapi .routers .route_names import (
3739 CONFORMANCE ,
4850logger = logging .getLogger (__name__ )
4951
5052
51- class RootRouter (APIRouter ):
53+ class RootRouter (StapiFastapiBaseRouter ):
5254 def __init__ (
5355 self ,
5456 get_orders : GetOrders ,
@@ -170,10 +172,6 @@ def __init__(
170172
171173 self .conformances = list (_conformances )
172174
173- @staticmethod
174- def url_for (request : Request , name : str , / , ** path_params : Any ) -> str :
175- return str (request .url_for (name , ** path_params ))
176-
177175 def get_root (self , request : Request ) -> RootResponse :
178176 links = [
179177 Link (
@@ -245,7 +243,7 @@ def get_products(self, request: Request, next: str | None = None, limit: int = 1
245243 ),
246244 ]
247245 if end > 0 and end < len (self .product_ids ):
248- links .append (self .pagination_link (request , self .product_ids [end ], limit ))
246+ links .append (self .pagination_link (request , f" { self . name } : { LIST_PRODUCTS } " , self .product_ids [end ], limit ))
249247 return ProductsCollection (
250248 products = [self .product_routers [product_id ].get_product (request ) for product_id in ids ],
251249 links = links ,
@@ -261,8 +259,8 @@ async def get_orders( # noqa: C901
261259 for order in orders :
262260 order .links .extend (self .order_links (order , request ))
263261 match maybe_pagination_token :
264- case Some (x ):
265- links .append (self .pagination_link (request , x , limit ))
262+ case Some (next_ ):
263+ links .append (self .pagination_link (request , f" { self . name } : { LIST_ORDERS } " , next_ , limit ))
266264 case Maybe .empty :
267265 pass
268266 match maybe_orders_count :
@@ -325,8 +323,12 @@ async def get_order_statuses(
325323 case Success (Some ((statuses , maybe_pagination_token ))):
326324 links .append (self .order_statuses_link (request , order_id ))
327325 match maybe_pagination_token :
328- case Some (x ):
329- links .append (self .pagination_link (request , x , limit ))
326+ case Some (next_ ):
327+ links .append (
328+ self .pagination_link (
329+ request , f"{ self .name } :{ LIST_ORDER_STATUSES } " , next_ , limit , order_id = order_id
330+ )
331+ )
330332 case Maybe .empty :
331333 pass
332334 case Success (Maybe .empty ):
@@ -353,10 +355,10 @@ def add_product(self, product: Product, *args: Any, **kwargs: Any) -> None:
353355 self .product_routers [product .id ] = product_router
354356 self .product_ids = [* self .product_routers .keys ()]
355357
356- def generate_order_href (self , request : Request , order_id : str ) -> str :
358+ def generate_order_href (self , request : Request , order_id : str ) -> URL :
357359 return self .url_for (request , f"{ self .name } :{ GET_ORDER } " , order_id = order_id )
358360
359- def generate_order_statuses_href (self , request : Request , order_id : str ) -> str :
361+ def generate_order_statuses_href (self , request : Request , order_id : str ) -> URL :
360362 return self .url_for (request , f"{ self .name } :{ LIST_ORDER_STATUSES } " , order_id = order_id )
361363
362364 def order_links (self , order : Order [OrderStatus ], request : Request ) -> list [Link ]:
@@ -384,13 +386,9 @@ def order_statuses_link(self, request: Request, order_id: str) -> Link:
384386 type = TYPE_JSON ,
385387 )
386388
387- def pagination_link (self , request : Request , pagination_token : str , limit : int ) -> Link :
388- href = str (request .url .include_query_params (next = pagination_token , limit = limit )).replace (
389- str (request .url_for (f"{ self .name } :{ ROOT } " )), self .url_for (request , f"{ self .name } :{ ROOT } " ), 1
390- )
391-
389+ def pagination_link (self , request : Request , name : str , pagination_token : str , limit : int , ** kwargs : Any ) -> Link :
392390 return Link (
393- href = href ,
391+ href = self . url_for ( request , name , ** kwargs ). include_query_params ( next = pagination_token , limit = limit ) ,
394392 rel = "next" ,
395393 type = TYPE_JSON ,
396394 )
@@ -404,8 +402,12 @@ async def get_opportunity_search_records(
404402 for record in records :
405403 record .links .append (self .opportunity_search_record_self_link (record , request ))
406404 match maybe_pagination_token :
407- case Some (x ):
408- links .append (self .pagination_link (request , x , limit ))
405+ case Some (next_ ):
406+ links .append (
407+ self .pagination_link (
408+ request , f"{ self .name } :{ LIST_OPPORTUNITY_SEARCH_RECORDS } " , next_ , limit
409+ )
410+ )
409411 case Maybe .empty :
410412 pass
411413 case Failure (ValueError ()):
@@ -470,7 +472,7 @@ async def get_opportunity_search_record_statuses(
470472 case _:
471473 raise AssertionError ("Expected code to be unreachable" )
472474
473- def generate_opportunity_search_record_href (self , request : Request , search_record_id : str ) -> str :
475+ def generate_opportunity_search_record_href (self , request : Request , search_record_id : str ) -> URL :
474476 return self .url_for (
475477 request ,
476478 f"{ self .name } :{ GET_OPPORTUNITY_SEARCH_RECORD } " ,
0 commit comments