Query#

Caution

This module will be broken into a subpackage in the future. As always, internal APIs are not subject to the semver policy this repo holds.

Query data structure module

This module contains various data structures in the form of dataclasses that are used to represent GraphQL queries in Subgrounds using an AST-like approach. To the extent possible, these dataclasses are immutable (i.e.: frozen=True) to enforce a functional programming style and reduce side-effects.

A typical Subgrounds request will have the following dataclass hierarchy:

DataRequest
└── Document
    └── Query
        ├── VariableDefinition
        │   └── InputValue
        └── Selection
            ├── Argument
            │   └── InputValue
            └── Selection
class subgrounds.query.VariableDefinition(name, type_, default=None)#

Representation of a GraphQL variable definition

name#

Name of the argument

Type:

str

type_#

GraphQL type of the argument

Type:

subgrounds.schema.TypeRef.T

default#

Default value of the variable. Defaults to None.

Type:

subgrounds.query.InputValue.T | None

property graphql: str#

Returns the GraphQL string representation of the variable definition

Example:

>>> vardef = VariableDefinition(
...   name='foo',
...   type_=TypeRef.NonNull(TypeRef.Named(name="Int", kind="SCALAR")),
...   default=InputValue.Int(100)
... )
>>> print(vardef.graphql)
$foo: Int! = 100
Returns:

The GraphQL string representation of the variable definition

class subgrounds.query.Argument(name: 'str', value: 'InputValue.T')#
class subgrounds.query.Selection(fmeta, alias=None, arguments=<factory>, selection=<factory>)#

Represents a GraphQL field selection.

fmeta#

The type definition of the field being selected.

Type:

subgrounds.schema.TypeMeta.FieldMeta

alias#

The alias of the field selection. Defaults to None.

Type:

str | None

arguments#

The arguments, if any, of the field selection. Defaults to [].

Type:

list[subgrounds.query.Argument]

selection#

The inner field selections, if any. Defaults to [].

Type:

list[subgrounds.query.Selection]

iter()#

Returns an iterator over all Selections of the current selection tree.

iter_args(recurse=True)#

Returns an iterator over all Arguments of the current Selection.

If recurse == True, then the iterator also includes Arguments of inner Selections.

filter(predicate)#

Returns a new Selection object containing all attributes of the current Selection if predicate(self) == True and None otherwise. The function if also applied recursively to inner Selections.

Parameters:

predicate (Callable[[Selection], bool]) -- _description_

Returns:

_description_

Return type:

subgrounds.query.Selection | None

filter_args(predicate, recurse=True)#

Returns a new Selection object which contains all attributes of the current Selection except for Arguments for which predicate(arg) == True.

If recurse == True, then the function is applied recursively to inner Selections

Parameters:
Returns:

_description_

Return type:

Selection

map(map_f, priority='self')#

Returns a new Selection object containing the same selection tree as the current Selection where each Selection object s is map_f(s)

Parameters:

map_f (Callable[[Selection], Selection]) -- Mapping function to apply to each Selection

Returns:

_description_

Return type:

Selection

map_args(map_f, recurse=True)#
Replaces each Argument arg in the current Selection with

map_f(arg) and returns a new Selection object containing the modified arguments.

If recurse == True, then the function is applied recursively to inner Selections.

Parameters:
Returns:

_description_

Return type:

Selection

contains_list()#

Returns True i.f.f. the selection self selects a field of type list.

Parameters:

self -- The selection to traverse

Returns:

True if selection or nested selections selects a list field. False otherwise.

Return type:

bool

split()#

Returns a list of selections where each of the selections corresponds to a single selection path from the root to a leaf for each leaf selected in self.

Example (simplified, does not show all attributes):

>>> select = Selection('foo', inner=[
...   Selection('bar', inner=[
...     Selection('field0', inner=[]),
...     Selection('field1', inner=[]),
...   ]),
...   Selection('x', inner=[])
... ])
>>> split(select)
[
  Selection(
    'foo', inner=[Selection('bar', inner=[Selection('field0', inner=[])])]),
  Selection(
    'foo', inner=[Selection('bar', inner=[Selection('field1', inner=[])])]),
  Selection(
    'foo', inner=[Selection('x', inner=[])]),
]
Parameters:

self -- The selection to split

Returns:

The split selections

Return type:

list[subgrounds.query.Selection]

add(new_selections)#

Returns a new selection consisting of a copy of self expanded with the selection(s) new_selections. It is assumed that new_selections are inner selections of the root selection self.

Parameters:
Returns:

self expanded with

new_selections

Return type:

The resulting new selection, i.e.

remove(to_remove)#

Returns a new Selection object consisting of a copy of self without the selections in selections_to_remove.

Parameters:

to_remove (subgrounds.query.Selection | list[subgrounds.query.Selection]) -- The selection(s) to remove from self

Returns:

self without

selections_to_remove

Return type:

The new trimmed down selection, i.e.

variable_args(recurse=True)#

Returns all arguments in the current selection which have been given a variable as value.

If recurse == True, then the function is applied recursively to inner selections.

Parameters:

recurse (bool) -- _description_. Defaults to True.

Returns:

_description_

Return type:

Iterator[Argument]

static merge(selections)#

Returns a list of Selection objects resulting from merging selections to the extent possible.

Parameters:

merged (selections The selections to be) --

Returns:

_description_

Return type:

list[subgrounds.query.Selection]

contains(other)#

Returns True i.f.f. the Selection other is a subtree of the Selection self and False otherwise

Parameters:
  • self -- The selection

  • other (Selection) -- The subselection

Returns:

True i.f.f. other is in self

Return type:

bool

contains_argument(argname, recurse=True)#

Returns True i.f.f. there is an Argument object in self named argname. If recurse is True, then the method also checks the nested selections for an argument named argname.

Parameters:
  • argname (str) -- The name of the argument

  • recurse (bool) -- Flag indicating whether or not the method should be run recursively on nested selections. Defaults to True.

Returns:

True i.f.f. there is an argument named argname in self

Return type:

bool

get_argument(argname, recurse=True)#

Returns an Argument object corresponding to the argument in the Selection object select with name argname. If select does not contain such an argument and recurse is True, then the function is called recursively on select's inner selections. If no such argument is found in select or its inner selections, then the function raises an exception.

Parameters:
  • argname (str) -- The name of the argument to find

  • recurse (bool) -- Flag indicating whether or not the method should be run recursively on nested selections. Defaults to True.

Raises:

KeyError -- If no argument named argname exists in the selection self.

Returns:

The argument in select with name argname (if any).

Return type:

subgrounds.query.Argument | None

get_argument_by_variable(varname, recurse=True)#

Returns an Argument object corresponding to the argument in the Selection object select whose value is a variable named varname. If select does not contain such an argument and recurse is True, then the function is called recursively on select's inner selections. If no such argument is found in select or its inner selections, then the function raises an exception

Parameters:
  • varname (str) -- The name of the variable to find

  • recurse (bool) -- Flag indicating whether or not the method should be run recursively. Defaults to True.

Raises:

KeyError -- If no argument with variable value named varname exists in the selection self.

Returns:

The argument in select with variable value named varname

if it exists

Return type:

subgrounds.query.Argument | None

substitute_arg(argname, replacement, recurse=True)#

Returns a new Selection object containing the same data as self with the argument named argname replaced with replacement. If recurse is True, then the method is called recursively on self's inner selections and the substitution is also applied to the latter.

Parameters:
Returns:

_description_

Return type:

Selection

prune_undefined(variables)#

Return a new Selection containing the subtree of the current Selection where all argument InputValues are defined, i.e.: each argument's InputValue is either

1) not of type InputValue.Variable or 2) of type InputValue.Variable and the variable name is contained in variables.

Parameters:

variables (Iterator[str]) -- An iterator over defined variables

Returns:

A new pruned Selection object

Return type:

subgrounds.query.Selection | None

class subgrounds.query.Query(name: 'str | None' = None, selection: 'list[Selection]' = <factory>, variables: 'list[VariableDefinition]' = <factory>)#
property graphql: str#

Returns a string containing a GraphQL query matching the current query

Returns:

The string containing the GraphQL query

iter()#

Returns an iterator over all Selections of the selection tree of the current Query.

iter_args()#

Returns an iterator over all Arguments of the selection tree of the current Query.

iter_vardefs()#

Returns an iterator over all VariableDefinitions of the selection tree of the current Query.

filter(predicate)#

Returns a new Query object containing all selections s that satisfy predicate(s) == True.

Parameters:

predicate (Callable[[Selection], bool]) -- _description_

Returns:

_description_

Return type:

Query

filter_args(predicate)#

Returns a new Query object containing all selections arguments arg that satisfy predicate(arg) == True.

Parameters:

predicate (Callable[[Argument], bool]) -- _description_

Returns:

_description_

Return type:

Query

map(map_f, priority='self')#
Applies the function map_f to each Selection in the current

Query and returns a new Query object containing the resulting Selections.

Parameters:

map_f (Callable[[Selection], Selection]) -- Mapping function to apply to each Selection

Returns:

_description_

Return type:

Query

map_args(map_f)#
Applies the function map_f to each Argument in the current

Query and returns a new Query object containing the resulting Arguments.

Parameters:

map_f (Callable[[Argument], Argument]) -- _description_

Returns:

_description_

Return type:

Query

add(other)#

Returns a new Query containing all selections in :attr:'self' along with the new selections in other

Parameters:
Returns:

A new Query objects containing all selections

Return type:

Query

remove(other)#

Returns a new Query object containing all selections in self minus the subquery or selection(s) specified in other.

Note: other does not need to be a "full" selection (i.e.: a selection all the way to leaves of the GraphQL schema).

Example:

>>> og_selection = Selection(
...     TypeMeta.FieldMeta(
...         'pair',
...         description="",
...         args=[],
...         type=TypeRef.non_null_list("Pair", kind="OBJECT")
...     ),
...     None,
...     [],
...     [
...         Selection(
...             TypeMeta.FieldMeta(
...                 'token0',
...                 description="",
...                 args=[],
...                 type=TypeRef.Named(name="Token", kind="OBJECT")
...             ),
...             None,
...             [],
...             [
...                 Selection(
...                     TypeMeta.FieldMeta(
...                         'id',
...                         description="",
...                         args=[],
...                         type=TypeRef.Named(name="String", kind="SCALAR")
...                     ),
...                     None,
...                     [],
...                     []
...                 ),
...                 Selection(
...                     TypeMeta.FieldMeta(
...                         'name',
...                         description="",
...                         args=[],
...                         type=TypeRef.Named(name="String", kind="SCALAR")
...                     ),
...                     None,
...                     [],
...                     []
...                 ),
...                 Selection(
...                     TypeMeta.FieldMeta(
...                         'symbol',
...                         description="",
...                         args=[],
...                         type=TypeRef.Named(name="String", kind="SCALAR")
...                     ),
...                     None,
...                     [],
...                     []
...                 ),
...             ]
...         )
...     ]
... )
>>> selection_to_remove = Selection(
...     TypeMeta.FieldMeta(
...         'token0',
...         description="",
...         args=[],
...         type=TypeRef.Named(name="Token", kind="OBJECT")
...     ),
...     None,
...     [],
...     []
... )
>>> og_selection.remove(selection_to_remove)
Selection(
    TypeMeta.FieldMeta(
        'pair',
        description="",
        args=[],
        type=TypeRef.non_null_list("Pair", kind="OBJECT")
    ),
    None,
    [],
    []
)
Parameters:
  • query (Query) -- The query to which a selection has to be removed

  • other (Query | Selection | list[Selection]) -- The subquery or selection(s) to remove from self

Returns:

A new Query object containing the original query selections

minus other

Return type:

Query

contains_selection(selection)#

Returns True i.f.f. the selection tree selection is present in query.

Parameters:
  • query (Query) -- A query object

  • selection (Selection) -- The selection to be found (or not) in query

Returns:

True if the selection is present in query, False

otherwise.

Return type:

bool

static contains(query, other)#

Returns True i.f.f. all selections in other are contained in query. In other words, returns true i.f.f. other is a subset of query.

Note: other does not need to include "full" selections (i.e.: selections all the way to leaves of the GraphQL schema).

Parameters:
  • query (Query) -- The query that is to be checked

  • other (Query) -- The query that has to be in query

Returns:

True i.f.f. all selections in other are contained in query,

otherwise False

Return type:

bool

static select(query, other)#

Returns a new Query

Parameters:
  • query (Query) -- [description]

  • other (Query) -- [description]

Returns:

[description]

Return type:

Query

class subgrounds.query.Fragment(name: 'str', type_: 'TypeRef.T', selection: 'list[Selection]' = <factory>, variables: 'list[VariableDefinition]' = <factory>)#
class subgrounds.query.Document(url: 'str', query: 'Query', fragments: 'list[Fragment]' = <factory>, variables: 'dict[str, Any]' = <factory>)#
map(map_f)#

Applies the function map_f to each Selection in the current Document and returns a new Document object containing the resulting Selections.

Parameters:

map_f (Callable[[Selection], Selection]) -- Mapping function to apply to each Selection

Returns:

_description_

Return type:

Query

map_args(map_f)#

Applies the function map_f to each Argument in the current Document and returns a new Document object containing the resulting Arguments.

Parameters:

map_f (Callable[[Argument], Argument]) -- _description_

Returns:

_description_

Return type:

Selection

prune_undefined(variables)#

Returns a new Document object that contains the subset of the current Document's query containing only the Selections for which all its arguments are defined (i.e.: either constants or variables in variables).

Parameters:

variables (dict[str, Any]) -- _description_

Returns:

_description_

Return type:

Document

class subgrounds.query.DocumentResponse(url: 'str', data: 'dict[str, Any]' = <factory>)#
class subgrounds.query.DataRequest(documents: 'list[Document]' = <factory>)#
class subgrounds.query.DataResponse(responses: 'list[DocumentResponse]' = <factory>)#
subgrounds.query.selections_of_object(schema, object_)#

Returns generator of Selection objects that selects all non-list fields of GraphQL Object of Interface object_.

Parameters:
  • schema (SchemaMeta) -- _description_

  • object (TypeMeta.ObjectMeta | TypeMeta.InterfaceMeta) -- _description_

Yields:

_type_ -- _description_