From 8326d0213fa9ebe2c07754c61d5f7a23dbbd3e93 Mon Sep 17 00:00:00 2001 From: KingDarBoja Date: Sat, 19 Sep 2020 12:23:24 -0500 Subject: [PATCH] refactor: WIP introspection from schema using typeddict --- pyproject.toml | 1 + .../utilities/introspection_from_schema.py | 141 +++++++++++++++++- 2 files changed, 139 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cd2df1b2..5c4139d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ packages = [ [tool.poetry.dependencies] python = "^3.6" +typing-extensions = { version = "3.7.*", python = "~3.6" } [tool.poetry.dev-dependencies] pytest = "^5.4" diff --git a/src/graphql/utilities/introspection_from_schema.py b/src/graphql/utilities/introspection_from_schema.py index 64181617..b9312198 100644 --- a/src/graphql/utilities/introspection_from_schema.py +++ b/src/graphql/utilities/introspection_from_schema.py @@ -1,14 +1,149 @@ -from typing import Any, Dict +import sys + +from ..pyutils import FrozenList + +if sys.version_info < (3, 7): + from typing_extensions import TypedDict +else: + from typing import TypedDict, Optional, Generic, TypeVar + +from typing import Any from ..error import GraphQLError -from ..language import parse +from ..language import parse, DirectiveLocation from ..type import GraphQLSchema from .get_introspection_query import get_introspection_query __all__ = ["introspection_from_schema"] +# Based on the GraphQL-JS implementation +# https://github.com/graphql/graphql-js/blob/master/src/utilities/getIntrospectionQuery.js + +class IntrospectionType: + __slots__ = "name", "description" + + name: str + description: Optional[str] + +class IntrospectionScalarType(IntrospectionType): + description: Optional[str] + specified_by_url: Optional[str] + +class IntrospectionObjectType(IntrospectionType): + kind: str = "OBJECT" + fields: FrozenList["IntrospectionField"] + interfaces: FrozenList["IntrospectionInterfaceType"] + +class IntrospectionInterfaceType(IntrospectionType): + kind: str = "INTERFACE" + fields: FrozenList["IntrospectionField"] + interfaces: FrozenList["IntrospectionInterfaceType"] + possible_types: FrozenList["IntrospectionObjectType"] + +class IntrospectionUnionType (IntrospectionType): + kind: str = "UNION" + possible_types: FrozenList["IntrospectionNamedTypeRef"] + +class IntrospectionEnumType(IntrospectionType): + kind: str = "ENUM" + enum_values: FrozenList["IntrospectionEnumValue"] + +class IntrospectionInputObjectType(IntrospectionType): + kind: str = "INPUT_OBJECT" + input_fields: FrozenList["IntrospectionInputValue"] + +IntrospectionOutputType = ( + IntrospectionScalarType, + IntrospectionObjectType, + IntrospectionInterfaceType, + IntrospectionUnionType, + IntrospectionEnumType, +) + +IntrospectionInputType = ( + IntrospectionScalarType, + IntrospectionEnumType, + IntrospectionInputObjectType, +) + +# GraphQL Introspection Type +GIT = TypeVar("GIT", bound="IntrospectionType") + +class IntrospectionNamedTypeRef(IntrospectionType, Generic[GIT]): + kind: GIT["kind"] + name: str + +class IntrospectionListTypeRef(IntrospectionType, Generic[GIT]): + kind: str = 'LIST' + of_type: GIT + +IntrospectionTypeRef = ( + IntrospectionNamedTypeRef, + IntrospectionListTypeRef +) + +IntrospectionOutputTypeRef = ( + IntrospectionNamedTypeRef[IntrospectionType, IntrospectionOutputType] +) + +IntrospectionInputTypeRef = IntrospectionInputType + +class IntrospectionField: + name: str + description: Optional[str] + args: FrozenList["IntrospectionInputValue"] + type: IntrospectionOutputTypeRef + isDeprecated: bool + deprecationReason: Optional[str] + +class IntrospectionInputValue: + name: str + description: Optional[str] + type: IntrospectionInputTypeRef + defaultValue: Optional[str] + +class IntrospectionEnumValue: + name: str + description: Optional[str] + isDeprecated: bool + deprecationReason: Optional[str] + +# +# | IntrospectionScalarType +# | IntrospectionObjectType +# | IntrospectionInterfaceType +# | IntrospectionUnionType +# | IntrospectionEnumType +# | IntrospectionInputObjectType +# +# IntrospectionOutputType = +# | IntrospectionScalarType +# | IntrospectionObjectType +# | IntrospectionInterfaceType +# | IntrospectionUnionType +# | IntrospectionEnumType +# +# IntrospectionInputType = +# | IntrospectionScalarType +# | IntrospectionEnumType +# | IntrospectionInputObjectType + + +class IntrospectionDirective(TypedDict): + name: str + description: Optional[str] + isRepeatable: Optional[bool] + locations: FrozenList[DirectiveLocation] + args: FrozenList[IntrospectionInputValue] + -IntrospectionSchema = Dict[str, Any] +class IntrospectionSchema(TypedDict): + description: Optional[str] + queryType: IntrospectionNamedTypeRef[IntrospectionObjectType] + mutationType: Optional[IntrospectionNamedTypeRef[IntrospectionObjectType]] + subscriptionType: Optional[IntrospectionNamedTypeRef[IntrospectionObjectType]] + types: FrozenList[IntrospectionType] + directives: FrozenList[IntrospectionDirective] def introspection_from_schema(