Skip to content

Commit 7e99b63

Browse files
committed
Implement schema_printer util
* Implement partial tests.
1 parent b67be8b commit 7e99b63

File tree

2 files changed

+289
-0
lines changed

2 files changed

+289
-0
lines changed

graphql/core/utils/schema_printer.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
from ..language.printer import print_ast
2+
from ..type.definition import (
3+
GraphQLEnumType,
4+
GraphQLInputObjectType,
5+
GraphQLInterfaceType,
6+
GraphQLObjectType,
7+
GraphQLScalarType,
8+
GraphQLUnionType
9+
)
10+
from .ast_from_value import ast_from_value
11+
from .is_nullish import is_nullish
12+
13+
14+
def print_schema(schema):
15+
return _print_filtered_schema(schema, _is_defined_type)
16+
17+
18+
def print_introspection_schema(schema):
19+
return _print_filtered_schema(schema, _is_introspection_type)
20+
21+
22+
def _is_defined_type(typename):
23+
return not _is_introspection_type(typename) and not _is_builtin_scalar(typename)
24+
25+
26+
def _is_introspection_type(typename):
27+
return typename.startswith('__')
28+
29+
30+
_builtin_scalars = frozenset(['String', 'Boolean', 'Int', 'Float', 'ID'])
31+
32+
33+
def _is_builtin_scalar(typename):
34+
return typename in _builtin_scalars
35+
36+
37+
def _print_filtered_schema(schema, type_filter):
38+
return '\n\n'.join(
39+
_print_type(type)
40+
for typename, type in sorted(schema.get_type_map().items())
41+
if type_filter(typename)
42+
) + '\n'
43+
44+
45+
def _print_type(type):
46+
if isinstance(type, GraphQLScalarType):
47+
return _print_scalar(type)
48+
49+
elif isinstance(type, GraphQLObjectType):
50+
return _print_object(type)
51+
52+
elif isinstance(type, GraphQLInterfaceType):
53+
return _print_interface(type)
54+
55+
elif isinstance(type, GraphQLUnionType):
56+
return _print_union(type)
57+
58+
elif isinstance(type, GraphQLEnumType):
59+
return _print_enum(GraphQLEnumType)
60+
61+
assert isinstance(type, GraphQLInputObjectType)
62+
return _print_input_object(GraphQLInputObjectType)
63+
64+
65+
def _print_scalar(type):
66+
return 'scalar {}'.format(type.name)
67+
68+
69+
def _print_object(type):
70+
interfaces = type.get_interfaces()
71+
implemented_interfaces = \
72+
' implements {}'.format(', '.join(i.name for i in interfaces)) if interfaces else ''
73+
74+
return (
75+
'type {}{} {{\n'
76+
'{}\n'
77+
'}}'
78+
).format(type.name, implemented_interfaces, _print_fields(type))
79+
80+
81+
def _print_interface(type):
82+
return (
83+
'interface {} {{\n'
84+
'{}\n'
85+
'}}'
86+
).format(type.name, _print_fields(type))
87+
88+
89+
def _print_union(type):
90+
return 'union {} = {}'.format(type.name, ' | '.join(str(t) for t in type.get_possible_types()))
91+
92+
93+
def _print_enum(type):
94+
return (
95+
'enum {} {{\n'
96+
'{}\n'
97+
'}}'
98+
).format(type.name, '\n'.join(' ' + v.name for v in type.get_values()))
99+
100+
101+
def _print_input_object(type):
102+
return (
103+
'input {} {{\n'
104+
'{}\n'
105+
'}}'
106+
).format(type.name, '\n'.join(' ' + _print_input_value(field) for field in type.get_fields().values()))
107+
108+
109+
def _print_fields(type):
110+
return '\n'.join(' {}{}: {}'.format(f.name, _print_args(f), f.type) for f in type.get_fields().values())
111+
112+
113+
def _print_args(field):
114+
if not field.args:
115+
return ''
116+
117+
return '({})'.format(', '.join(_print_input_value(arg) for arg in field.args))
118+
119+
120+
def _print_input_value(arg):
121+
if not is_nullish(arg.default_value):
122+
default_value = ' = ' + print_ast(ast_from_value(arg.default_value, arg.type))
123+
else:
124+
default_value = ''
125+
126+
return '{}: {}{}'.format(arg.name, arg.type, default_value)
127+
128+
129+
__all__ = ['print_schema', 'print_introspection_schema']
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
from collections import OrderedDict
2+
from graphql.core.type.definition import GraphQLField, GraphQLArgument
3+
from graphql.core.utils.schema_printer import print_schema, print_introspection_schema
4+
from graphql.core.utils.is_nullish import is_nullish
5+
from graphql.core.language.printer import print_ast
6+
from graphql.core.type import (
7+
GraphQLSchema,
8+
GraphQLInputObjectType,
9+
GraphQLScalarType,
10+
GraphQLObjectType,
11+
GraphQLInterfaceType,
12+
GraphQLUnionType,
13+
GraphQLEnumType,
14+
GraphQLString,
15+
GraphQLInt,
16+
GraphQLBoolean,
17+
GraphQLList,
18+
GraphQLNonNull,
19+
)
20+
21+
22+
def print_for_test(schema):
23+
return '\n' + print_schema(schema)
24+
25+
26+
def print_single_field_schema(field_config):
27+
Root = GraphQLObjectType(
28+
name='Root',
29+
fields={
30+
'singleField': field_config
31+
}
32+
)
33+
return print_for_test(GraphQLSchema(Root))
34+
35+
36+
def test_prints_string_field():
37+
output = print_single_field_schema(GraphQLField(GraphQLString))
38+
assert output == '''
39+
type Root {
40+
singleField: String
41+
}
42+
'''
43+
44+
45+
def test_prints_list_string_field():
46+
output = print_single_field_schema(GraphQLField(GraphQLList(GraphQLString)))
47+
assert output == '''
48+
type Root {
49+
singleField: [String]
50+
}
51+
'''
52+
53+
54+
def test_prints_non_null_list_string_field():
55+
output = print_single_field_schema(GraphQLField(GraphQLNonNull(GraphQLList(GraphQLString))))
56+
assert output == '''
57+
type Root {
58+
singleField: [String]!
59+
}
60+
'''
61+
62+
63+
def test_prints_list_non_null_string_field():
64+
output = print_single_field_schema(GraphQLField((GraphQLList(GraphQLNonNull(GraphQLString)))))
65+
assert output == '''
66+
type Root {
67+
singleField: [String!]
68+
}
69+
'''
70+
71+
72+
def test_prints_non_null_list_non_null_string_field():
73+
output = print_single_field_schema(GraphQLField(GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLString)))))
74+
assert output == '''
75+
type Root {
76+
singleField: [String!]!
77+
}
78+
'''
79+
80+
81+
def test_prints_object_field():
82+
FooType = GraphQLObjectType(
83+
name='Foo',
84+
fields={
85+
'str': GraphQLField(GraphQLString)
86+
}
87+
)
88+
89+
Root = GraphQLObjectType(
90+
name='Root',
91+
fields={
92+
'foo': GraphQLField(FooType)
93+
}
94+
)
95+
96+
Schema = GraphQLSchema(Root)
97+
98+
output = print_for_test(Schema)
99+
100+
assert output == '''
101+
type Foo {
102+
str: String
103+
}
104+
105+
type Root {
106+
foo: Foo
107+
}
108+
'''
109+
110+
111+
def test_prints_string_field_with_int_arg():
112+
output = print_single_field_schema(GraphQLField(
113+
type=GraphQLString,
114+
args={'argOne': GraphQLArgument(GraphQLInt)}
115+
))
116+
assert output == '''
117+
type Root {
118+
singleField(argOne: Int): String
119+
}
120+
'''
121+
122+
123+
def test_prints_string_field_with_int_arg_with_default():
124+
output = print_single_field_schema(GraphQLField(
125+
type=GraphQLString,
126+
args={'argOne': GraphQLArgument(GraphQLInt, default_value=2)}
127+
))
128+
assert output == '''
129+
type Root {
130+
singleField(argOne: Int = 2): String
131+
}
132+
'''
133+
134+
135+
def test_prints_string_field_with_non_null_int_arg():
136+
output = print_single_field_schema(GraphQLField(
137+
type=GraphQLString,
138+
args={'argOne': GraphQLArgument(GraphQLNonNull(GraphQLInt))}
139+
))
140+
assert output == '''
141+
type Root {
142+
singleField(argOne: Int!): String
143+
}
144+
'''
145+
146+
147+
def test_prints_string_field_with_multiple_args():
148+
output = print_single_field_schema(GraphQLField(
149+
type=GraphQLString,
150+
args=OrderedDict([
151+
('argOne', GraphQLArgument(GraphQLInt)),
152+
('argTwo', GraphQLArgument(GraphQLString))
153+
])
154+
))
155+
156+
assert output == '''
157+
type Root {
158+
singleField(argOne: Int, argTwo: String): String
159+
}
160+
'''

0 commit comments

Comments
 (0)