This commit is contained in:
Christian Mantha
2026-03-02 19:10:52 -05:00
commit 2ca0b9ef7c
28907 changed files with 5233713 additions and 0 deletions

View File

@@ -0,0 +1,302 @@
from textwrap import dedent
from typing import Any, Dict, List, Optional, Union
from ..language import DirectiveLocation
try:
from typing import Literal, TypedDict
except ImportError: # Python < 3.8
from typing_extensions import Literal, TypedDict
__all__ = [
"get_introspection_query",
"IntrospectionDirective",
"IntrospectionEnumType",
"IntrospectionField",
"IntrospectionInputObjectType",
"IntrospectionInputValue",
"IntrospectionInterfaceType",
"IntrospectionListType",
"IntrospectionNonNullType",
"IntrospectionObjectType",
"IntrospectionQuery",
"IntrospectionScalarType",
"IntrospectionSchema",
"IntrospectionType",
"IntrospectionTypeRef",
"IntrospectionUnionType",
]
def get_introspection_query(
descriptions: bool = True,
specified_by_url: bool = False,
directive_is_repeatable: bool = False,
schema_description: bool = False,
input_value_deprecation: bool = False,
input_object_one_of: bool = False,
) -> str:
"""Get a query for introspection.
Optionally, you can exclude descriptions, include specification URLs,
include repeatability of directives, and specify whether to include
the schema description as well.
"""
maybe_description = "description" if descriptions else ""
maybe_specified_by_url = "specifiedByURL" if specified_by_url else ""
maybe_directive_is_repeatable = "isRepeatable" if directive_is_repeatable else ""
maybe_schema_description = maybe_description if schema_description else ""
maybe_input_object_one_of = "isOneOf" if input_object_one_of else ""
def input_deprecation(string: str) -> Optional[str]:
return string if input_value_deprecation else ""
return dedent(
f"""
query IntrospectionQuery {{
__schema {{
{maybe_schema_description}
queryType {{ name }}
mutationType {{ name }}
subscriptionType {{ name }}
types {{
...FullType
}}
directives {{
name
{maybe_description}
{maybe_directive_is_repeatable}
locations
args{input_deprecation("(includeDeprecated: true)")} {{
...InputValue
}}
}}
}}
}}
fragment FullType on __Type {{
kind
name
{maybe_description}
{maybe_specified_by_url}
{maybe_input_object_one_of}
fields(includeDeprecated: true) {{
name
{maybe_description}
args{input_deprecation("(includeDeprecated: true)")} {{
...InputValue
}}
type {{
...TypeRef
}}
isDeprecated
deprecationReason
}}
inputFields{input_deprecation("(includeDeprecated: true)")} {{
...InputValue
}}
interfaces {{
...TypeRef
}}
enumValues(includeDeprecated: true) {{
name
{maybe_description}
isDeprecated
deprecationReason
}}
possibleTypes {{
...TypeRef
}}
}}
fragment InputValue on __InputValue {{
name
{maybe_description}
type {{ ...TypeRef }}
defaultValue
{input_deprecation("isDeprecated")}
{input_deprecation("deprecationReason")}
}}
fragment TypeRef on __Type {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
ofType {{
kind
name
}}
}}
}}
}}
}}
}}
}}
}}
}}
}}
"""
)
# Unfortunately, the following type definitions are a bit simplistic
# because of current restrictions in the typing system (mypy):
# - no recursion, see https://github.com/python/mypy/issues/731
# - no generic typed dicts, see https://github.com/python/mypy/issues/3863
# simplified IntrospectionNamedType to avoids cycles
SimpleIntrospectionType = Dict[str, Any]
class MaybeWithDescription(TypedDict, total=False):
description: Optional[str]
class WithName(MaybeWithDescription):
name: str
class MaybeWithSpecifiedByUrl(TypedDict, total=False):
specifiedByURL: Optional[str]
class WithDeprecated(TypedDict):
isDeprecated: bool
deprecationReason: Optional[str]
class MaybeWithDeprecated(TypedDict, total=False):
isDeprecated: bool
deprecationReason: Optional[str]
class IntrospectionInputValue(WithName, MaybeWithDeprecated):
type: SimpleIntrospectionType # should be IntrospectionInputType
defaultValue: Optional[str]
class IntrospectionField(WithName, WithDeprecated):
args: List[IntrospectionInputValue]
type: SimpleIntrospectionType # should be IntrospectionOutputType
class IntrospectionEnumValue(WithName, WithDeprecated):
pass
class MaybeWithIsRepeatable(TypedDict, total=False):
isRepeatable: bool
class IntrospectionDirective(WithName, MaybeWithIsRepeatable):
locations: List[DirectiveLocation]
args: List[IntrospectionInputValue]
class IntrospectionScalarType(WithName, MaybeWithSpecifiedByUrl):
kind: Literal["scalar"]
class IntrospectionInterfaceType(WithName):
kind: Literal["interface"]
fields: List[IntrospectionField]
interfaces: List[SimpleIntrospectionType] # should be InterfaceType
possibleTypes: List[SimpleIntrospectionType] # should be NamedType
class IntrospectionObjectType(WithName):
kind: Literal["object"]
fields: List[IntrospectionField]
interfaces: List[SimpleIntrospectionType] # should be InterfaceType
class IntrospectionUnionType(WithName):
kind: Literal["union"]
possibleTypes: List[SimpleIntrospectionType] # should be NamedType
class IntrospectionEnumType(WithName):
kind: Literal["enum"]
enumValues: List[IntrospectionEnumValue]
class IntrospectionInputObjectType(WithName):
kind: Literal["input_object"]
inputFields: List[IntrospectionInputValue]
isOneOf: bool
IntrospectionType = Union[
IntrospectionScalarType,
IntrospectionObjectType,
IntrospectionInterfaceType,
IntrospectionUnionType,
IntrospectionEnumType,
IntrospectionInputObjectType,
]
IntrospectionOutputType = Union[
IntrospectionScalarType,
IntrospectionObjectType,
IntrospectionInterfaceType,
IntrospectionUnionType,
IntrospectionEnumType,
]
IntrospectionInputType = Union[
IntrospectionScalarType, IntrospectionEnumType, IntrospectionInputObjectType
]
class IntrospectionListType(TypedDict):
kind: Literal["list"]
ofType: SimpleIntrospectionType # should be IntrospectionType
class IntrospectionNonNullType(TypedDict):
kind: Literal["non_null"]
ofType: SimpleIntrospectionType # should be IntrospectionType
IntrospectionTypeRef = Union[
IntrospectionType, IntrospectionListType, IntrospectionNonNullType
]
class IntrospectionSchema(MaybeWithDescription):
queryType: IntrospectionObjectType
mutationType: Optional[IntrospectionObjectType]
subscriptionType: Optional[IntrospectionObjectType]
types: List[IntrospectionType]
directives: List[IntrospectionDirective]
# The root typed dictionary for schema introspections.
# Note: We don't use class syntax here since the key looks like a private attribute.
IntrospectionQuery = TypedDict(
"IntrospectionQuery",
{"__schema": IntrospectionSchema},
)