39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
"""Общая пагинация и режим fetch_all."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from fastapi import HTTPException
|
||
|
||
DEFAULT_FETCH_ALL_MAX = 50_000
|
||
|
||
|
||
def slice_page(
|
||
items: list,
|
||
*,
|
||
offset: int,
|
||
limit: int,
|
||
fetch_all: bool = False,
|
||
max_all: int = DEFAULT_FETCH_ALL_MAX,
|
||
) -> tuple[list, int, int, int]:
|
||
"""
|
||
Возвращает (page, total, response_limit, response_offset).
|
||
При fetch_all — весь список (с проверкой max_all).
|
||
"""
|
||
total = len(items)
|
||
if fetch_all:
|
||
if total > max_all:
|
||
raise HTTPException(
|
||
status_code=400,
|
||
detail={
|
||
"code": "too_many_rows",
|
||
"message": (
|
||
f"Слишком много строк ({total}); максимум {max_all}. "
|
||
"Сузьте фильтры или используйте пагинацию."
|
||
),
|
||
"total": total,
|
||
"max": max_all,
|
||
},
|
||
)
|
||
return items, total, total, 0
|
||
return items[offset : offset + limit], total, limit, offset
|