Skip to main content
Glama
pagination.py4.08 kB
"""Pagination utilities for memory search and retrieval operations. This module provides shared pagination logic for tools that return lists of memories. Supports standard pagination patterns with page numbers and page sizes. """ from __future__ import annotations from typing import Any, Generic, TypeVar from ..security.validators import validate_positive_int # Default page size for all pagination operations DEFAULT_PAGE_SIZE = 10 # Maximum page size to prevent DoS via oversized responses MAX_PAGE_SIZE = 100 T = TypeVar("T") class PaginatedResult(Generic[T]): """Container for paginated results with metadata.""" def __init__( self, items: list[T], total_count: int, page: int, page_size: int, ): """Initialize paginated result. Args: items: List of items for current page total_count: Total number of items across all pages page: Current page number (1-indexed) page_size: Number of items per page """ self.items = items self.total_count = total_count self.page = page self.page_size = page_size @property def total_pages(self) -> int: """Calculate total number of pages.""" if self.page_size == 0: return 0 return (self.total_count + self.page_size - 1) // self.page_size @property def has_more(self) -> bool: """Check if there are more pages after current page.""" return self.page < self.total_pages @property def has_previous(self) -> bool: """Check if there are pages before current page.""" return self.page > 1 def to_dict(self) -> dict[str, Any]: """Convert to dictionary for API responses. Returns: Dictionary with pagination metadata """ return { "page": self.page, "page_size": self.page_size, "total_count": self.total_count, "total_pages": self.total_pages, "has_more": self.has_more, "has_previous": self.has_previous, } def validate_pagination_params( page: int | None = None, page_size: int | None = None, ) -> tuple[int, int]: """Validate and normalize pagination parameters. Args: page: Page number (1-indexed), defaults to 1 page_size: Number of items per page, defaults to DEFAULT_PAGE_SIZE Returns: Tuple of (validated_page, validated_page_size) Raises: ValueError: If pagination parameters are invalid """ # Default to first page if not specified if page is None: page = 1 # Default to standard page size if not specified if page_size is None: page_size = DEFAULT_PAGE_SIZE # Validate page number page = validate_positive_int(page, "page", min_value=1) # Validate page size page_size = validate_positive_int( page_size, "page_size", min_value=1, max_value=MAX_PAGE_SIZE, ) return page, page_size def paginate_list( items: list[T], page: int, page_size: int, ) -> PaginatedResult[T]: """Paginate a list of items. Args: items: Complete list of items to paginate page: Page number (1-indexed) page_size: Number of items per page Returns: PaginatedResult containing the requested page of items Examples: >>> items = list(range(25)) # 0-24 >>> result = paginate_list(items, page=1, page_size=10) >>> result.items [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> result.total_count 25 >>> result.has_more True """ total_count = len(items) # Calculate start and end indices for this page start_idx = (page - 1) * page_size end_idx = start_idx + page_size # Extract the page items page_items = items[start_idx:end_idx] return PaginatedResult( items=page_items, total_count=total_count, page=page, page_size=page_size, )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/prefrontalsys/mnemex'

If you have feedback or need assistance with the MCP directory API, please join our Discord server