CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-graphql-core

GraphQL-core is a Python port of GraphQL.js, the JavaScript reference implementation for GraphQL.

Pending
Overview
Eval results
Files

language.mddocs/

Language Processing and AST

Parse GraphQL documents into Abstract Syntax Trees (AST), manipulate AST nodes, and work with GraphQL source code. This module provides lexical analysis, parsing capabilities, and visitor patterns for AST traversal and manipulation.

Capabilities

Document Parsing

Parse GraphQL documents, values, and types from string sources into structured AST representations.

def parse(source: Union[str, Source]) -> DocumentNode
def parse_value(source: Union[str, Source]) -> ValueNode  
def parse_const_value(source: Union[str, Source]) -> ConstValueNode
def parse_type(source: Union[str, Source]) -> TypeNode

Parameters:

  • source: GraphQL source string or Source object to parse

Returns: Corresponding AST node type

Usage Examples

from graphql import parse, parse_value, parse_type

# Parse a complete GraphQL document
query = '''
    query GetUser($id: ID!) {
        user(id: $id) {
            name
            email
        }
    }
'''
document = parse(query)
print(document.kind)  # 'document'
print(len(document.definitions))  # 1

# Parse individual values
value_ast = parse_value('"hello world"')
print(value_ast.kind)  # 'string_value'
print(value_ast.value)  # 'hello world'

# Parse type expressions
type_ast = parse_type('[String!]!')
print(type_ast.kind)  # 'non_null_type'

Source Handling

Manage GraphQL source code with location tracking for enhanced error reporting and tooling.

class Source:
    def __init__(self, body: str, name: str = "GraphQL request", location_offset: SourceLocation = None)
    
    body: str
    name: str
    location_offset: SourceLocation

def get_location(source: Source, position: int) -> SourceLocation

class SourceLocation:
    line: int
    column: int

Usage Example

from graphql import Source, get_location, parse

source = Source('''
    query {
        user {
            name
        }
    }
''', name="user-query.graphql")

# Parse with source tracking
document = parse(source)

# Get location information
location = get_location(source, 20)
print(f"Line {location.line}, Column {location.column}")

Lexical Analysis

Tokenize GraphQL source code for custom parsing or analysis tools.

class Lexer:
    def __init__(self, source: Source)
    
    def next_token(self) -> Token
    def lookahead(self) -> Token

class Token:
    kind: TokenKind
    start: int
    end: int
    line: int
    column: int
    value: Optional[str]
    prev: Optional[Token]
    next: Optional[Token]

class TokenKind(Enum):
    SOF = "StartOfFile"
    EOF = "EndOfFile"
    BANG = "!"
    DOLLAR = "$"
    AMP = "&"
    PAREN_L = "("
    PAREN_R = ")"
    SPREAD = "..."
    COLON = ":"
    EQUALS = "="
    AT = "@"
    BRACKET_L = "["
    BRACKET_R = "]"
    BRACE_L = "{"
    PIPE = "|"
    BRACE_R = "}"
    NAME = "Name"
    INT = "Int"
    FLOAT = "Float"
    STRING = "String"
    BLOCK_STRING = "BlockString"
    COMMENT = "Comment"

Usage Example

from graphql import Source, Lexer, TokenKind

source = Source('{ hello world }')
lexer = Lexer(source)

token = lexer.next_token()
while token.kind != TokenKind.EOF:
    print(f"{token.kind.value}: {token.value}")
    token = lexer.next_token()

AST Printing

Convert AST nodes back to GraphQL string representation.

def print_ast(ast: Node) -> str

Usage Example

from graphql import parse, print_ast

document = parse('{ user { name email } }')
printed = print_ast(document)
print(printed)  # Formatted GraphQL string

AST Traversal and Manipulation

Visit and transform AST nodes using the visitor pattern.

def visit(root: Node, visitor: Visitor, visitor_keys: Optional[VisitorKeyMap] = None) -> Any

class Visitor:
    def enter(self, node: Node, key: Optional[str], parent: Optional[Node], path: List[Union[int, str]], ancestors: List[Node]) -> Optional[VisitorAction]
    def leave(self, node: Node, key: Optional[str], parent: Optional[Node], path: List[Union[int, str]], ancestors: List[Node]) -> Optional[Union[VisitorAction, Node]]

class ParallelVisitor:
    def __init__(self, visitors: Sequence[Visitor])

class VisitorAction(Enum):
    BREAK = object()
    SKIP = object() 
    REMOVE = object()
    IDLE = object()

# Visitor action constants
BREAK: VisitorAction
SKIP: VisitorAction
REMOVE: VisitorAction
IDLE: VisitorAction

Usage Example

from graphql import parse, visit, Visitor

class FieldNameCollector(Visitor):
    def __init__(self):
        self.field_names = []
    
    def enter(self, node, key, parent, path, ancestors):
        if node.kind == 'field':
            self.field_names.append(node.name.value)

document = parse('{ user { name email posts { title } } }')
collector = FieldNameCollector()
visit(document, collector)
print(collector.field_names)  # ['user', 'name', 'email', 'posts', 'title']

Location and Error Reporting

Print formatted location information for debugging and error reporting.

def print_location(location: Location) -> str
def print_source_location(source: Source, location: SourceLocation) -> str

class Location:
    start: int
    end: int
    start_token: Token
    end_token: Token
    source: Source

AST Node Types

Base Node Types

class Node:
    kind: str
    loc: Optional[Location]

class NameNode(Node):
    kind: str = 'name'
    value: str

class DocumentNode(Node):
    kind: str = 'document'
    definitions: List[DefinitionNode]

Definition Nodes

class DefinitionNode(Node):
    pass

class ExecutableDefinitionNode(DefinitionNode):
    pass

class OperationDefinitionNode(ExecutableDefinitionNode):
    kind: str = 'operation_definition'
    operation: OperationType
    name: Optional[NameNode]
    variable_definitions: Optional[List[VariableDefinitionNode]]
    directives: Optional[List[DirectiveNode]]
    selection_set: SelectionSetNode

class OperationType(Enum):
    QUERY = 'query'
    MUTATION = 'mutation'
    SUBSCRIPTION = 'subscription'

class FragmentDefinitionNode(ExecutableDefinitionNode):
    kind: str = 'fragment_definition'
    name: NameNode
    variable_definitions: Optional[List[VariableDefinitionNode]]
    type_condition: NamedTypeNode
    directives: Optional[List[DirectiveNode]]
    selection_set: SelectionSetNode

Selection Nodes

class SelectionNode(Node):
    pass

class FieldNode(SelectionNode):
    kind: str = 'field'
    alias: Optional[NameNode]
    name: NameNode
    arguments: Optional[List[ArgumentNode]]
    directives: Optional[List[DirectiveNode]]
    selection_set: Optional[SelectionSetNode]

class SelectionSetNode(Node):
    kind: str = 'selection_set'
    selections: List[SelectionNode]

class FragmentSpreadNode(SelectionNode):
    kind: str = 'fragment_spread'
    name: NameNode
    directives: Optional[List[DirectiveNode]]

class InlineFragmentNode(SelectionNode):
    kind: str = 'inline_fragment'
    type_condition: Optional[NamedTypeNode]
    directives: Optional[List[DirectiveNode]]
    selection_set: SelectionSetNode

Value Nodes

class ValueNode(Node):
    pass

class ConstValueNode(ValueNode):
    pass

class VariableNode(ValueNode):
    kind: str = 'variable'
    name: NameNode

class IntValueNode(ConstValueNode):
    kind: str = 'int_value'
    value: str

class FloatValueNode(ConstValueNode):
    kind: str = 'float_value'
    value: str

class StringValueNode(ConstValueNode):
    kind: str = 'string_value'
    value: str
    block: bool

class BooleanValueNode(ConstValueNode):
    kind: str = 'boolean_value'
    value: bool

class NullValueNode(ConstValueNode):
    kind: str = 'null_value'

class EnumValueNode(ConstValueNode):
    kind: str = 'enum_value'
    value: str

class ListValueNode(ValueNode):
    kind: str = 'list_value'
    values: List[ValueNode]

class ObjectValueNode(ValueNode):
    kind: str = 'object_value'
    fields: List[ObjectFieldNode]

class ObjectFieldNode(Node):
    kind: str = 'object_field'
    name: NameNode
    value: ValueNode

Type Nodes

class TypeNode(Node):
    pass

class NamedTypeNode(TypeNode):
    kind: str = 'named_type'
    name: NameNode

class ListTypeNode(TypeNode):
    kind: str = 'list_type'
    type: TypeNode

class NonNullTypeNode(TypeNode):
    kind: str = 'non_null_type'
    type: Union[NamedTypeNode, ListTypeNode]

Predicate Functions

def is_definition_node(node: Node) -> bool
def is_executable_definition_node(node: Node) -> bool
def is_selection_node(node: Node) -> bool
def is_value_node(node: Node) -> bool
def is_const_value_node(node: Node) -> bool
def is_type_node(node: Node) -> bool
def is_type_system_definition_node(node: Node) -> bool
def is_type_definition_node(node: Node) -> bool
def is_type_system_extension_node(node: Node) -> bool
def is_type_extension_node(node: Node) -> bool

Install with Tessl CLI

npx tessl i tessl/pypi-graphql-core

docs

error-handling.md

execution-engine.md

execution.md

index.md

language.md

type-system.md

utilities.md

validation.md

tile.json