Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions graphlayer/graphql/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ def generate_graphql_type(graph_type):
(snake_case_to_camel_case(field.name), to_graphql_input_field(field))
for field in graph_type.fields
),
description=graph_type.description,
))

elif isinstance(graph_type, schema.InterfaceType):
return graphql.GraphQLNonNull(graphql.GraphQLInterfaceType(
name=graph_type.name,
fields=to_graphql_fields(graph_type.fields),
resolve_type=lambda: None,
description=graph_type.description,
))

elif isinstance(graph_type, schema.ListType):
Expand All @@ -74,6 +76,7 @@ def generate_graphql_type(graph_type):
to_graphql_type(interface).of_type
for interface in graph_type.interfaces
),
description=graph_type.description,
))

else:
Expand All @@ -85,7 +88,7 @@ def to_graphql_input_field(graph_field):
if graph_field.has_default and isinstance(graphql_type, graphql.GraphQLNonNull):
graphql_type = graphql_type.of_type

return graphql.GraphQLInputField(type_=graphql_type)
return graphql.GraphQLInputField(type_=graphql_type, description=graph_field.description)
Comment on lines 88 to +91

def to_graphql_fields(graph_fields):
return lambda: iterables.to_dict(
Expand All @@ -100,6 +103,7 @@ def to_graphql_field(graph_field):
(snake_case_to_camel_case(param.name), to_graphql_argument(param))
for param in graph_field.params
),
description=graph_field.description,
)

def to_graphql_argument(param):
Expand All @@ -108,7 +112,7 @@ def to_graphql_argument(param):
if param.has_default and isinstance(graphql_type, graphql.GraphQLNonNull):
graphql_type = graphql_type.of_type

return graphql.GraphQLArgument(type_=graphql_type)
return graphql.GraphQLArgument(type_=graphql_type, description=param.description)

graphql_query_type = to_graphql_type(query_type).of_type
if mutation_type is None:
Expand Down
38 changes: 25 additions & 13 deletions graphlayer/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ def __str__(self):


class InputObjectType(object):
def __init__(self, name, fields):
def __init__(self, name, fields, description=None):
self.name = name
self.fields = Fields(name, fields)
self.instance_type = memoize(self._create_instance_type)
self.description = description

def _create_instance_type(self):
name = self.name
Expand Down Expand Up @@ -222,15 +223,16 @@ def coerce(self, value):
raise _coercion_error(value, self.name)


def input_field(name, type, default=_undefined):
return InputField(name, type, default)
def input_field(name, type, default=_undefined, description=None):
return InputField(name, type, default, description=description)


class InputField(object):
def __init__(self, name, type, default):
def __init__(self, name, type, default, description=None):
self.name = name
self.type = type
self.default = default
self.description = description

@property
def has_default(self):
Expand All @@ -241,9 +243,10 @@ def __repr__(self):


class InterfaceType(object):
def __init__(self, name, fields):
def __init__(self, name, fields, description=None):
self.name = name
self.fields = Fields(name, fields)
self.description = description

def __call__(self, *field_queries):
return ObjectQuery.create(self, field_queries=field_queries)
Expand Down Expand Up @@ -399,11 +402,12 @@ def __str__(self):


class ObjectType(object):
def __init__(self, name, fields, interfaces=None):
def __init__(self, name, fields, interfaces=None, description=None):
if interfaces is None:
interfaces = ()

self.name = name
self.description = description
if not callable(fields):
fields = lambdaize(fields)
def owned_fields():
Expand Down Expand Up @@ -579,21 +583,28 @@ class Args(object):
pass


def field(name, type, params=None):
def field(name, type, params=None, description=None):
if params is None:
params = ()
return Field(owner_type=None, name=name, type=type, params=params)
return Field(owner_type=None, name=name, type=type, params=params, description=description)


class Field(object):
def __init__(self, owner_type, name, type, params):
def __init__(self, owner_type, name, type, params, description=None):
self.owner_type = owner_type
self.name = name
self.type = type
self.params = Params(name, params)
self.description = description

def with_owner_type(self, owner_type):
return Field(owner_type=owner_type, name=self.name, type=self.type, params=self.params)
return Field(
owner_type=owner_type,
name=self.name,
type=self.type,
params=self.params,
description=self.description,
)

def __call__(self, *args):
field_queries, field_args = _partition_by_type(args, (FieldQuery, Argument))
Expand Down Expand Up @@ -731,15 +742,16 @@ def key(key, field_query):
)


def param(name, type, default=_undefined):
return Parameter(name=name, type=type, default=default)
def param(name, type, default=_undefined, description=None):
return Parameter(name=name, type=type, default=default, description=description)


class Parameter(object):
def __init__(self, name, type, default):
def __init__(self, name, type, default, description=None):
self.name = name
self.type = type
self.default = default
self.description = description

@property
def has_default(self):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def read(fname):

setup(
name='graphlayer',
version='0.4.0',
version='0.5.0',
description='High-performance library for implementing GraphQL APIs',
long_description=read("README.rst"),
author='Michael Williamson',
Expand Down
115 changes: 106 additions & 9 deletions tests/graphql/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,82 @@ def test_object_type_is_converted_to_non_null_graphql_object_type():
))


def test_object_type_description_is_converted_to_graphql_object_type_description():
graph_type = g.ObjectType("Obj", description="An object.", fields=(
g.field("value", type=g.String),
))

assert_that(to_graphql_type(graph_type), is_graphql_non_null(
is_graphql_object_type(description=equal_to("An object.")),
))


def test_field_description_is_converted_to_graphql_field_description():
graph_type = g.ObjectType("Obj", fields=(
g.field("value", type=g.String, description="A value."),
))

assert_that(to_graphql_type(graph_type), is_graphql_non_null(
is_graphql_object_type(
fields=is_mapping({
"value": is_graphql_field(description=equal_to("A value.")),
}),
),
))


def test_param_description_is_converted_to_graphql_argument_description():
graph_type = g.ObjectType("Obj", fields=(
g.field("value", type=g.String, params=(
g.param("arg", g.Int, description="An argument."),
)),
))

assert_that(to_graphql_type(graph_type), is_graphql_non_null(
is_graphql_object_type(
fields=is_mapping({
"value": is_graphql_field(args=is_mapping({
"arg": is_graphql_argument(description=equal_to("An argument.")),
})),
}),
),
))


def test_interface_type_description_is_converted_to_graphql_interface_type_description():
graph_type = g.InterfaceType("Item", description="An item.", fields=(
g.field("value", type=g.String),
))

assert_that(to_graphql_type(graph_type), is_graphql_non_null(
is_graphql_interface_type(name="Item", description=equal_to("An item.")),
))


def test_input_object_type_description_is_converted_to_graphql_input_object_type_description():
graph_type = g.InputObjectType("Obj", description="An input object.", fields=(
g.input_field("value", type=g.String),
))

assert_that(to_graphql_input_type(graph_type), is_graphql_non_null(
is_graphql_input_object_type(name="Obj", description=equal_to("An input object.")),
))


def test_input_field_description_is_converted_to_graphql_input_field_description():
graph_type = g.InputObjectType("Obj", fields=(
g.input_field("value", type=g.String, description="A value."),
))

assert_that(to_graphql_input_type(graph_type), is_graphql_non_null(
is_graphql_input_object_type(
fields=is_mapping({
"value": is_graphql_input_field(description=equal_to("A value.")),
}),
),
))


def test_object_type_field_names_are_converted_from_snake_case_to_camel_case():
graph_type = g.ObjectType("Obj", fields=(
g.field("field_name", type=g.String),
Expand Down Expand Up @@ -273,37 +349,48 @@ def is_graphql_enum_value(value):
)


def is_graphql_input_field(type):
def is_graphql_input_field(type=None, description=None):
if type is None:
type = anything
if description is None:
description = anything

return all_of(
is_instance(graphql.GraphQLInputField),
has_attrs(type=type),
has_attrs(type=type, description=description),
)


def is_graphql_input_object_type(name=None, fields=None):
def is_graphql_input_object_type(name=None, fields=None, description=None):
if name is None:
name = anything
if fields is None:
fields = anything
if description is None:
description = anything

return all_of(
is_instance(graphql.GraphQLInputObjectType),
has_attrs(
name=name,
fields=fields,
description=description,
),
)


def is_graphql_interface_type(name, fields=None):
def is_graphql_interface_type(name, fields=None, description=None):
if fields is None:
fields = anything
if description is None:
description = anything

return all_of(
is_instance(graphql.GraphQLInterfaceType),
has_attrs(
name=name,
fields=fields,
description=description,
),
)

Expand All @@ -322,7 +409,7 @@ def is_graphql_non_null(element_matcher):
)


def is_graphql_object_type(name=None, fields=None, interfaces=None):
def is_graphql_object_type(name=None, fields=None, interfaces=None, description=None):
if name is None:
name = anything

Expand All @@ -332,35 +419,45 @@ def is_graphql_object_type(name=None, fields=None, interfaces=None):
if interfaces is None:
interfaces = anything

if description is None:
description = anything

return all_of(
is_instance(graphql.GraphQLObjectType),
has_attrs(
name=name,
fields=fields,
interfaces=interfaces,
description=description,
),
)


def is_graphql_field(type=None, args=None):
def is_graphql_field(type=None, args=None, description=None):
if type is None:
type = anything

if args is None:
args = anything

if description is None:
description = anything

return all_of(
is_instance(graphql.GraphQLField),
has_attrs(type=type, args=args),
has_attrs(type=type, args=args, description=description),
)


def is_graphql_argument(type=None):
def is_graphql_argument(type=None, description=None):
if type is None:
type = anything

if description is None:
description = anything

return all_of(
is_instance(graphql.GraphQLArgument),
has_attrs(type=type),
has_attrs(type=type, description=description),
)

Loading