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

validation.mddocs/

Query Validation

Validate GraphQL documents against schemas using specification-defined validation rules and custom validation logic. Ensures queries are well-formed, use valid fields and types, and follow GraphQL specification requirements before execution.

Capabilities

Document Validation

Validate complete GraphQL documents against a schema using all specification-defined rules.

def validate(
    schema: GraphQLSchema, 
    document_ast: DocumentNode, 
    rules: Optional[Collection[Type[ASTValidationRule]]] = None,
    max_errors: Optional[int] = None,
    type_info: Optional[TypeInfo] = None,
) -> List[GraphQLError]

Parameters:

  • schema: GraphQL schema to validate against
  • document_ast: Parsed GraphQL document AST to validate
  • rules: Optional custom validation rules (defaults to specified_rules)
  • max_errors: Maximum number of errors to collect before stopping
  • type_info: Optional type information context

Returns: List of validation errors found in the document

Usage Example

from graphql import validate, parse, build_schema

schema = build_schema('''
    type Query {
        user(id: ID!): User
        users: [User]
    }
    
    type User {
        id: ID!
        name: String
        email: String
    }
''')

# Valid query
valid_query_ast = parse('{ user(id: "123") { name email } }')
errors = validate(schema, valid_query_ast)
print(len(errors))  # 0

# Invalid query - unknown field
invalid_query_ast = parse('{ user(id: "123") { name invalidField } }')
errors = validate(schema, invalid_query_ast)
print(len(errors))  # 1
print(errors[0].message)  # Cannot query field "invalidField" on type "User"

Validation Context

Access validation state and type information during rule execution.

class ValidationContext:
    def __init__(
        self, 
        schema: GraphQLSchema, 
        document: DocumentNode, 
        type_info: TypeInfo, 
        on_error: Callable[[GraphQLError], None]
    )
    
    def report_error(self, error: GraphQLError) -> None
    def get_errors(self) -> List[GraphQLError]
    def get_schema(self) -> GraphQLSchema
    def get_document(self) -> DocumentNode
    def get_fragment(self, name: str) -> Optional[FragmentDefinitionNode]
    def get_fragment_spreads(self, node: SelectionSetNode) -> List[FragmentSpreadNode]
    def get_recursively_referenced_fragments(self, operation: OperationDefinitionNode) -> List[FragmentDefinitionNode]

class ASTValidationContext(ValidationContext):
    """Validation context for executable documents"""
    pass

class SDLValidationContext(ValidationContext):
    """Validation context for schema definition language documents"""
    pass

Validation Rules

All validation rules implement the ValidationRule interface and can be used individually or in combination.

class ValidationRule:
    def __init__(self, context: ValidationContext)
    
    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[VisitorAction]

class ASTValidationRule(ValidationRule):
    """Base class for executable document validation rules"""
    pass

class SDLValidationRule(ValidationRule):
    """Base class for schema definition language validation rules"""
    pass

# All specification-defined validation rules
specified_rules: List[Type[ValidationRule]]

Individual Validation Rules

Specification-defined validation rules that can be used individually or customized.

# Executable definition rules
class ExecutableDefinitionsRule(ASTValidationRule):
    """Ensures only executable definitions (operations and fragments) are present"""

class LoneAnonymousOperationRule(ASTValidationRule):
    """Ensures anonymous operations are alone in the document"""

class UniqueOperationNamesRule(ASTValidationRule):
    """Ensures operation names are unique within a document"""

# Field and fragment rules
class FieldsOnCorrectTypeRule(ASTValidationRule):
    """Ensures fields are queried on types that define them"""

class FragmentsOnCompositeTypesRule(ASTValidationRule):
    """Ensures fragments are on composite types"""

class KnownFragmentNamesRule(ASTValidationRule):
    """Ensures fragment spreads refer to defined fragments"""

class NoFragmentCyclesRule(ASTValidationRule):
    """Prevents circular fragment references"""

class UniqueFragmentNamesRule(ASTValidationRule):
    """Ensures fragment names are unique"""

class NoUnusedFragmentsRule(ASTValidationRule):
    """Ensures all fragments are used"""

class PossibleFragmentSpreadsRule(ASTValidationRule):
    """Ensures fragment spreads are possible"""

class OverlappingFieldsCanBeMergedRule(ASTValidationRule):
    """Complex rule ensuring field selection merging is valid"""

# Argument rules
class KnownArgumentNamesRule(ASTValidationRule):
    """Ensures arguments are defined on fields and directives"""

class UniqueArgumentNamesRule(ASTValidationRule):
    """Ensures argument names are unique per field/directive"""

class ProvidedRequiredArgumentsRule(ASTValidationRule):
    """Ensures required arguments are provided"""

# Variable rules
class UniqueVariableNamesRule(ASTValidationRule):
    """Ensures variable names are unique per operation"""

class NoUndefinedVariablesRule(ASTValidationRule):
    """Ensures all used variables are defined"""

class NoUnusedVariablesRule(ASTValidationRule):
    """Ensures all defined variables are used"""

class VariablesAreInputTypesRule(ASTValidationRule):
    """Ensures variables are input types"""

class VariablesInAllowedPositionRule(ASTValidationRule):
    """Ensures variable usage matches definitions"""

# Value and type rules
class ValuesOfCorrectTypeRule(ASTValidationRule):
    """Ensures values match their expected types"""

class ScalarLeafsRule(ASTValidationRule):
    """Ensures scalar fields don't have selections"""

# Directive rules
class KnownDirectivesRule(ASTValidationRule):
    """Ensures directives are defined and in valid locations"""

class UniqueDirectivesPerLocationRule(ASTValidationRule):
    """Ensures non-repeatable directives appear once per location"""

# Subscription rules
class SingleFieldSubscriptionsRule(ASTValidationRule):
    """Ensures subscriptions select only one root field"""

# Miscellaneous rules
class KnownTypeNamesRule(ASTValidationRule):
    """Ensures type names exist in the schema"""

class UniqueInputFieldNamesRule(ASTValidationRule):
    """Ensures input object field names are unique"""

SDL Validation Rules

Rules specific to validating schema definition language documents.

class LoneSchemaDefinitionRule(SDLValidationRule):
    """Ensures only one schema definition exists"""

class UniqueOperationTypesRule(SDLValidationRule):
    """Ensures operation types are unique in schema"""

class UniqueTypeNamesRule(SDLValidationRule):
    """Ensures type names are unique in schema"""

class UniqueEnumValueNamesRule(SDLValidationRule):
    """Ensures enum value names are unique per enum"""

class UniqueFieldDefinitionNamesRule(SDLValidationRule):
    """Ensures field names are unique per type"""

class UniqueArgumentDefinitionNamesRule(SDLValidationRule):
    """Ensures argument names are unique per field"""

class UniqueDirectiveNamesRule(SDLValidationRule):
    """Ensures directive names are unique in schema"""

class PossibleTypeExtensionsRule(SDLValidationRule):
    """Ensures type extensions are valid"""

Custom Validation Rules

Optional rules not defined by the GraphQL specification but useful for specific use cases.

class NoDeprecatedCustomRule(ASTValidationRule):
    """Prevents usage of deprecated fields and enum values"""

class NoSchemaIntrospectionCustomRule(ASTValidationRule):
    """Prevents introspection queries for security"""

Custom Rule Example

from graphql import ValidationRule, GraphQLError

class NoIntrospectionRule(ValidationRule):
    def enter_field(self, node, key, parent, path, ancestors):
        if node.name.value.startswith('__'):
            self.context.report_error(
                GraphQLError(
                    'Introspection is disabled',
                    nodes=[node]
                )
            )

# Use custom rule
from graphql import validate, specified_rules

custom_rules = list(specified_rules) + [NoIntrospectionRule]
errors = validate(schema, document_ast, rules=custom_rules)

Validation with Type Information

Use TypeInfo to provide enhanced validation with type context.

from graphql.utilities import TypeInfo

# Create type info for enhanced validation
type_info = TypeInfo(schema)
errors = validate(schema, document_ast, type_info=type_info)

Advanced Validation Example

from graphql import (
    validate, parse, build_schema, specified_rules,
    NoDeprecatedCustomRule, ValidationContext
)

schema = build_schema('''
    type Query {
        user(id: ID!): User
        deprecated_field: String @deprecated(reason: "Use user instead")
    }
    
    type User {
        id: ID!
        name: String
        old_name: String @deprecated
    }
''')

query = parse('''
    {
        user(id: "123") {
            name
            old_name
        }
        deprecated_field
    }
''')

# Validate with custom rules
all_rules = list(specified_rules) + [NoDeprecatedCustomRule]
errors = validate(schema, query_ast, rules=all_rules)

for error in errors:
    print(f"Error: {error.message}")
    if error.locations:
        for location in error.locations:
            print(f"  at line {location.line}, column {location.column}")

Types

# Import required types
from typing import List, Optional, Sequence, Callable, Type, Union
from graphql.type import GraphQLSchema
from graphql.language import DocumentNode, Node, FragmentDefinitionNode, OperationDefinitionNode, SelectionSetNode, FragmentSpreadNode
from graphql.error import GraphQLError
from graphql.utilities import TypeInfo
from graphql.language.visitor import VisitorAction

# Core validation types
ValidationRule = Type[ValidationRule]
ASTValidationRule = Type[ASTValidationRule]  
SDLValidationRule = Type[SDLValidationRule]

# Validation context types
ValidationContext = class ValidationContext
ASTValidationContext = class ASTValidationContext
SDLValidationContext = class SDLValidationContext

# Rule collections
specified_rules: List[Type[ValidationRule]]

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