def dsl_gql( *operations: "DSLOperation", **operations_with_name: "DSLOperation" ) -> DocumentNode: r"""Given arguments instances of :class:`DSLOperation` containing GraphQL operations, generate a Document which can be executed later in a gql client or a gql session. Similar to the :func:`gql.gql` function but instead of parsing a python string to describe the request, we are using operations which have been generated dynamically using instances of :class:`DSLField`, generated by instances of :class:`DSLType` which themselves originated from a :class:`DSLSchema` class. :param \*operations: the GraphQL operations :type \*operations: DSLOperation (DSLQuery, DSLMutation, DSLSubscription) :param \**operations_with_name: the GraphQL operations with an operation name :type \**operations_with_name: DSLOperation (DSLQuery, DSLMutation, DSLSubscription) :return: a Document which can be later executed or subscribed by a :class:`Client <gql.client.Client>`, by an :class:`async session <gql.client.AsyncClientSession>` or by a :class:`sync session <gql.client.SyncClientSession>` :raises TypeError: if an argument is not an instance of :class:`DSLOperation` """ # Concatenate operations without and with name all_operations: Tuple["DSLOperation", ...] = ( *operations, *(operation for operation in operations_with_name.values()), ) # Set the operation name for name, operation in operations_with_name.items(): operation.name = name # Check the type for operation in all_operations: if not isinstance(operation, DSLOperation): raise TypeError( "Operations should be instances of DSLOperation " "(DSLQuery, DSLMutation or DSLSubscription).\n" f"Received: {type(operation)}." ) return DocumentNode( definitions=[ OperationDefinitionNode( operation=OperationType(operation.operation_type), selection_set=operation.selection_set, variable_definitions=FrozenList( operation.variable_definitions.get_ast_definitions() ), **({"name": NameNode(value=operation.name)} if operation.name else {}), ) for operation in all_operations ] )
def query(*fields, **kwargs): if "operation" not in kwargs: kwargs["operation"] = "query" return DocumentNode(definitions=[ OperationDefinitionNode( operation=OperationType(kwargs["operation"]), selection_set=SelectionSetNode( selections=FrozenList(selections(*fields))), ) ])
def operation_for_entities_fetch( selection_set: SelectionSetNode, variable_usages: VariableUsages, internal_fragments: set[FragmentDefinitionNode], ) -> DocumentNode: representations_variable = VariableNode(name=NameNode(value='representations')) return DocumentNode( definitions=list( chain( [ OperationDefinitionNode( operation=OperationType.QUERY, variable_definitions=list( chain( [ VariableDefinitionNode( variable=representations_variable, type=NonNullTypeNode( type=ListTypeNode( type=NonNullTypeNode( type=NamedTypeNode(name=NameNode(value='_Any')) ) ) ), ) ], map_fetch_node_to_variable_definitions(variable_usages), ) ), selection_set=SelectionSetNode( selections=[ FieldNode( name=NameNode(value='_entities'), arguments=[ ArgumentNode( name=NameNode( value=representations_variable.name.value ), value=representations_variable, ) ], selection_set=selection_set, ) ] ), ), ], internal_fragments, ) ) )
def operation_for_root_fetch( selection_set: SelectionSetNode, variable_usages: VariableUsages, internal_fragments: set[FragmentDefinitionNode], operation: Optional[OperationType] = None, ) -> DocumentNode: definitions: list[DefinitionNode] = [ OperationDefinitionNode( operation=operation, selection_set=selection_set, variable_definitions=map_fetch_node_to_variable_definitions(variable_usages), ) ] definitions.extend(internal_fragments) return DocumentNode(definitions=definitions)
def get_variable_usages( self, selection_set: SelectionSetNode, fragments: set[FragmentDefinitionNode] ) -> VariableUsages: usages: dict[str, VariableDefinitionNode] = {} # Construct a document of the selection set and fragment definitions so we # can visit them, adding all variable usages to the `usages` object. definitions: list[DefinitionNode] = [ OperationDefinitionNode(selection_set=selection_set, operation=OperationType.QUERY) ] definitions.extend(fragments) document = DocumentNode(definitions=definitions) this = self class VariableVisitor(Visitor): # noinspection PyMethodMayBeStatic def enter_variable(self, node: VariableNode): usages[node.name.value] = this.variable_definitions[node.name.value] visit(document, VariableVisitor()) return usages
def extract_extensions(ast: DocumentNode) -> DocumentNode: extensions = [ node for node in ast.definitions if node.kind in EXTENSION_KINDS ] return DocumentNode(definitions=extensions)