1from textwrap import dedent
2from typing import Optional
3
4__all__ = ["get_introspection_query"]
5
6
7def get_introspection_query(
8    descriptions: bool = True,
9    specified_by_url: bool = False,
10    directive_is_repeatable: bool = False,
11    schema_description: bool = False,
12    input_value_deprecation: bool = False,
13) -> str:
14    """Get a query for introspection.
15
16    Optionally, you can exclude descriptions, include specification URLs,
17    include repeatability of directives, and specify whether to include
18    the schema description as well.
19    """
20    maybe_description = "description" if descriptions else ""
21    maybe_specified_by_url = "specifiedByUrl" if specified_by_url else ""
22    maybe_directive_is_repeatable = "isRepeatable" if directive_is_repeatable else ""
23    maybe_schema_description = maybe_description if schema_description else ""
24
25    def input_deprecation(string: str) -> Optional[str]:
26        return string if input_value_deprecation else ""
27
28    return dedent(
29        f"""
30        query IntrospectionQuery {{
31          __schema {{
32            {maybe_schema_description}
33            queryType {{ name }}
34            mutationType {{ name }}
35            subscriptionType {{ name }}
36            types {{
37              ...FullType
38            }}
39            directives {{
40              name
41              {maybe_description}
42              {maybe_directive_is_repeatable}
43              locations
44              args{input_deprecation("(includeDeprecated: true)")} {{
45                ...InputValue
46              }}
47            }}
48          }}
49        }}
50
51        fragment FullType on __Type {{
52          kind
53          name
54          {maybe_description}
55          {maybe_specified_by_url}
56          fields(includeDeprecated: true) {{
57            name
58            {maybe_description}
59            args{input_deprecation("(includeDeprecated: true)")} {{
60              ...InputValue
61            }}
62            type {{
63              ...TypeRef
64            }}
65            isDeprecated
66            deprecationReason
67          }}
68          inputFields{input_deprecation("(includeDeprecated: true)")} {{
69            ...InputValue
70          }}
71          interfaces {{
72            ...TypeRef
73          }}
74          enumValues(includeDeprecated: true) {{
75            name
76            {maybe_description}
77            isDeprecated
78            deprecationReason
79          }}
80          possibleTypes {{
81            ...TypeRef
82          }}
83        }}
84
85        fragment InputValue on __InputValue {{
86          name
87          {maybe_description}
88          type {{ ...TypeRef }}
89          defaultValue
90          {input_deprecation("isDeprecated")}
91          {input_deprecation("deprecationReason")}
92        }}
93
94        fragment TypeRef on __Type {{
95          kind
96          name
97          ofType {{
98            kind
99            name
100            ofType {{
101              kind
102              name
103              ofType {{
104                kind
105                name
106                ofType {{
107                  kind
108                  name
109                  ofType {{
110                    kind
111                    name
112                    ofType {{
113                      kind
114                      name
115                      ofType {{
116                        kind
117                        name
118                      }}
119                    }}
120                  }}
121                }}
122              }}
123            }}
124          }}
125        }}
126        """
127    )
128