47 lines
1.2 KiB
Python
47 lines
1.2 KiB
Python
|
|
"""Pagination utilities for API responses."""
|
||
|
|
|
||
|
|
from typing import TypeVar
|
||
|
|
|
||
|
|
from pydantic import BaseModel
|
||
|
|
|
||
|
|
from schemas import PaginatedResponse
|
||
|
|
|
||
|
|
RecordT = TypeVar("RecordT", bound=BaseModel)
|
||
|
|
|
||
|
|
|
||
|
|
def calculate_total_pages(total: int, per_page: int) -> int:
|
||
|
|
"""Calculate total number of pages."""
|
||
|
|
return (total + per_page - 1) // per_page if total > 0 else 1
|
||
|
|
|
||
|
|
|
||
|
|
def calculate_offset(page: int, per_page: int) -> int:
|
||
|
|
"""Calculate the offset for a given page."""
|
||
|
|
return (page - 1) * per_page
|
||
|
|
|
||
|
|
|
||
|
|
def create_paginated_response(
|
||
|
|
records: list[RecordT],
|
||
|
|
total: int,
|
||
|
|
page: int,
|
||
|
|
per_page: int,
|
||
|
|
) -> PaginatedResponse[RecordT]:
|
||
|
|
"""
|
||
|
|
Create a paginated response with calculated metadata.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
records: List of records for the current page
|
||
|
|
total: Total count of all records (before pagination)
|
||
|
|
page: Current page number (1-indexed)
|
||
|
|
per_page: Number of records per page
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
A PaginatedResponse with all pagination metadata
|
||
|
|
"""
|
||
|
|
return PaginatedResponse[RecordT](
|
||
|
|
records=records,
|
||
|
|
total=total,
|
||
|
|
page=page,
|
||
|
|
per_page=per_page,
|
||
|
|
total_pages=calculate_total_pages(total, per_page),
|
||
|
|
)
|