subgrounds.pagination.strategies module#

Subgrounds pagination strategies

This module implements functions and data structures used to implement the two PaginationStrategies that Subgrounds offers.

For both strategies, pagination is done in four steps:

  1. Generate one or many PaginationNode objects per query document. These are tree-like data structures that extract all information about pagination fields (i.e.: fields that return lists of entities) while maintaining the nestedness relationship between each pagination field (i.e.: which is nested in which).

  2. The query document is normalized such that every pagination field in the query has:

    1. An ordering (i.e.: orderBy and orderDirection are specified)

    2. A first argument set to the firstN variable

    3. A skip argument set to the skipN variable

    4. A where filter with the filter name derived from the ordering and the value being a variable named lastOrderingValueN

    In other words, the query will be transformed in a form which allows Subgrounds to paginate automatically by simply setting the set of pagination variables (i.e.: firstN, skipN and lastOrderingValueN) to different values. Each field that requires pagination (i.e.: each field that yields a list) will have its own set of variables, hence the N post-fix.

    Example: The initial query

    query {
      items(
        orderBy: timestamp,
        orderDirection: desc,
        first: 10000
      ) {
        foo
      }
    }
    

    will be transformed to

    query($first0: Int, $skip0: Int, $lastOrderingValue0: BigInt) {
      items(
        orderBy: timestamp,
        orderDirection: desc,
        first: $first0,
        skip: $skip0,
        where: {
          timestamp_lt: $lastOrderingValue0
        }
      ) {
        foo
      }
    }
    
  3. For each data page, generate the values for the pagination variables (i.e.: firstN, skipN and `lastOrderingValueN`)

  4. If some variables are undefined (i.e.: they are present in the query document, but not given a value as part of step 3), then the document is pruned and all selections (and sub-selections) containing undefined variables are removed.

Depending on the strategy, the variable values computed at step 3 will change.

exception subgrounds.pagination.strategies.StopPagination(*args)#

Bases: Exception

exception subgrounds.pagination.strategies.SkipPagination(*args)#

Bases: Exception

class subgrounds.pagination.strategies.LegacyStrategyArgGenerator(pagination_nodes: 'list[PaginationNode]')#

Bases: object

active_idx: int = 0#
class Cursor(page_node: 'PaginationNode')#

Bases: object

inner_idx: int = 0#
filter_value: Any = None#
queried_entities: int = 0#
stop: bool = False#
page_count: int = 0#
keys: set[str]#
page_node: PaginationNode#
inner: list[subgrounds.pagination.strategies.LegacyStrategyArgGenerator.Cursor]#
property is_leaf#
update(data)#

Moves self cursor forward according to previous response data data :param data: Previous response data :type data: dict

Raises:

StopIteration -- _description_

step(data)#

Updates either self cursor or inner state machine depending on whether the inner state machine has reached its limit :param data: _description_ :type data: dict

first_arg_value()#
args()#

Returns the pagination arguments for the current state of the state machine :returns: _description_ :rtype: dict

reset()#

Reset state machine

cursor: list[Cursor]#
step(page_data=None)#
class subgrounds.pagination.strategies.LegacyStrategy(schema, document)#

Bases: object

schema: SchemaMeta#
arg_generator: LegacyStrategyArgGenerator#
normalized_doc: Document#
step(page_data=None)#
class subgrounds.pagination.strategies.ShallowStrategyArgGenerator(pagination_nodes: 'list[PaginationNode]')#

Bases: object

class Cursor(page_node, inner, inner_idx=0, filter_value=None, queried_entities=0, page_count=0)#

Bases: object

Class used to generate the pagination variables for a given tree of PaginationNode objects.

page_node#

The PaginationNode object which this cursor is iterating through.

Type:

subgrounds.pagination.preprocess.PaginationNode

inner#

The cursors for nested PaginationNodes, if any.

Type:

list[subgrounds.pagination.strategies.ShallowStrategyArgGenerator.Cursor]

inner_idx#

The index of the inner PaginationNode through which this cursor iterating.

Type:

int

filter_value#

The previous page's index value used to query the next data page. Depends on page_node.filter_field, e.g.: if page_node.filter_field is timestamp_gt, then filter_value will be the highest timestamp the entities returned in the previous data page.

Type:

Any

queried_entities#

Counter keeping track of the total number of queried entities.

Type:

int

stop#

Flag indicating whether or not to stop the cursor.

page_count#

Counter keeping track of the total number data pages queried.

Type:

int

keys#

Set keeping track of the keys of all queried entities to avoid duplicates.

page_node: PaginationNode#
inner: list[subgrounds.pagination.strategies.ShallowStrategyArgGenerator.Cursor]#
inner_idx: int = 0#
filter_value: Any = None#
queried_entities: int = 0#
page_count: int = 0#
static from_pagination_node(page_node)#
property is_leaf: bool#
property active_cursor: Optional[Cursor]#
iter(only_active=False)#
mapi(map_f, priority='self', counter=None)#
cursor: list[Cursor]#
iter_cursors()#
static update_cursor(cursor, data)#
step(page_data=None)#
class subgrounds.pagination.strategies.ShallowStrategy(schema, document)#

Bases: object

schema: SchemaMeta#
arg_generator: ShallowStrategyArgGenerator#
normalized_doc: Document#
step(page_data=None)#