fix(api): wrap pre-paginated list responses
This commit is contained in:
+42
-20
@@ -201,18 +201,39 @@ def _with_header_project_context(endpoint, route_name: str):
|
||||
|
||||
def _with_pagination(endpoint):
|
||||
signature = inspect.signature(endpoint)
|
||||
if "limit" in signature.parameters or "offset" in signature.parameters:
|
||||
return endpoint
|
||||
handler_limit_parameter = "limit" if "limit" in signature.parameters else None
|
||||
handler_offset_parameter = next(
|
||||
(
|
||||
parameter_name
|
||||
for parameter_name in ("offset", "skip")
|
||||
if parameter_name in signature.parameters
|
||||
),
|
||||
None,
|
||||
)
|
||||
handler_handles_pagination = bool(
|
||||
handler_limit_parameter or handler_offset_parameter
|
||||
)
|
||||
|
||||
@wraps(endpoint)
|
||||
async def wrapper(*args, **kwargs):
|
||||
limit = kwargs.pop("_rest_limit")
|
||||
offset = kwargs.pop("_rest_offset")
|
||||
if handler_handles_pagination:
|
||||
limit = kwargs.get(handler_limit_parameter, 0)
|
||||
offset = kwargs.get(handler_offset_parameter, 0)
|
||||
else:
|
||||
limit = kwargs.pop("_rest_limit")
|
||||
offset = kwargs.pop("_rest_offset")
|
||||
result = endpoint(*args, **kwargs)
|
||||
if inspect.isawaitable(result):
|
||||
result = await result
|
||||
if not isinstance(result, list):
|
||||
return result
|
||||
if handler_handles_pagination:
|
||||
return Page(
|
||||
items=result,
|
||||
total=offset + len(result),
|
||||
limit=limit or len(result),
|
||||
offset=offset,
|
||||
)
|
||||
return Page(
|
||||
items=result[offset : offset + limit],
|
||||
total=len(result),
|
||||
@@ -221,22 +242,23 @@ def _with_pagination(endpoint):
|
||||
)
|
||||
|
||||
parameters = list(signature.parameters.values())
|
||||
parameters.extend(
|
||||
[
|
||||
inspect.Parameter(
|
||||
"_rest_limit",
|
||||
kind=inspect.Parameter.KEYWORD_ONLY,
|
||||
annotation=int,
|
||||
default=Query(100, ge=1, le=1000, alias="limit"),
|
||||
),
|
||||
inspect.Parameter(
|
||||
"_rest_offset",
|
||||
kind=inspect.Parameter.KEYWORD_ONLY,
|
||||
annotation=int,
|
||||
default=Query(0, ge=0, alias="offset"),
|
||||
),
|
||||
]
|
||||
)
|
||||
if not handler_handles_pagination:
|
||||
parameters.extend(
|
||||
[
|
||||
inspect.Parameter(
|
||||
"_rest_limit",
|
||||
kind=inspect.Parameter.KEYWORD_ONLY,
|
||||
annotation=int,
|
||||
default=Query(100, ge=1, le=1000, alias="limit"),
|
||||
),
|
||||
inspect.Parameter(
|
||||
"_rest_offset",
|
||||
kind=inspect.Parameter.KEYWORD_ONLY,
|
||||
annotation=int,
|
||||
default=Query(0, ge=0, alias="offset"),
|
||||
),
|
||||
]
|
||||
)
|
||||
wrapper.__signature__ = signature.replace(parameters=parameters)
|
||||
return wrapper
|
||||
|
||||
|
||||
Reference in New Issue
Block a user