Added documentation

This commit is contained in:
Syrus Akbary 2016-08-16 21:29:59 -07:00
parent f53c26c7ab
commit af9e51e58d
12 changed files with 99 additions and 13 deletions

View File

@ -7,6 +7,14 @@ from .utils import (yank_fields_from_attrs, get_base_fields,
class AbstractTypeMeta(type): class AbstractTypeMeta(type):
'''
AbstractType Definition
When we want to share fields across multiple types, like a Interface,
a ObjectType and a Input ObjectType we can use AbstractTypes for defining
our fields that the other types will inherit from.
'''
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
# Also ensure initialization is only performed for subclasses of # Also ensure initialization is only performed for subclasses of

View File

@ -4,6 +4,10 @@ from ..utils.orderedtype import OrderedType
class Dynamic(OrderedType): class Dynamic(OrderedType):
'''
A Dynamic Type let us get the type in runtime when we generate
the schema. So we can have lazy fields.
'''
def __init__(self, type, _creation_counter=None): def __init__(self, type, _creation_counter=None):
super(Dynamic, self).__init__(_creation_counter=_creation_counter) super(Dynamic, self).__init__(_creation_counter=_creation_counter)

View File

@ -50,6 +50,13 @@ class EnumTypeMeta(type):
class Enum(six.with_metaclass(EnumTypeMeta, UnmountedType)): class Enum(six.with_metaclass(EnumTypeMeta, UnmountedType)):
'''
Enum Type Definition
Some leaf values of requests and input values are Enums. GraphQL serializes
Enum values as strings, however internally Enums can be represented by any
kind of type, often integers.
'''
def get_type(self): def get_type(self):
return type(self) return type(self)

View File

@ -39,6 +39,14 @@ class InputObjectTypeMeta(AbstractTypeMeta):
class InputObjectType(six.with_metaclass(InputObjectTypeMeta, UnmountedType)): class InputObjectType(six.with_metaclass(InputObjectTypeMeta, UnmountedType)):
'''
Input Object Type Definition
An input object defines a structured collection of fields which may be
supplied to a field argument.
Using `NonNull` will ensure that a value must be provided by the query
'''
@classmethod @classmethod
def get_type(cls): def get_type(cls):

View File

@ -39,6 +39,15 @@ class InterfaceMeta(AbstractTypeMeta):
class Interface(six.with_metaclass(InterfaceMeta)): class Interface(six.with_metaclass(InterfaceMeta)):
'''
Interface Type Definition
When a field can return one of a heterogeneous set of types, a Interface type
is used to describe what types are possible, what fields are in common across
all types, as well as a function to determine which type is actually used
when the field is resolved.
'''
resolve_type = None resolve_type = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -56,6 +56,12 @@ class ObjectTypeMeta(AbstractTypeMeta):
class ObjectType(six.with_metaclass(ObjectTypeMeta)): class ObjectType(six.with_metaclass(ObjectTypeMeta)):
'''
Object Type Definition
Almost all of the GraphQL types you define will be object types. Object types
have a name, but most importantly describe their fields.
'''
@classmethod @classmethod
def is_type_of(cls, root, context, info): def is_type_of(cls, root, context, info):

View File

@ -11,12 +11,10 @@ from .unmountedtype import UnmountedType
class ScalarTypeMeta(type): class ScalarTypeMeta(type):
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
super_new = super(ScalarTypeMeta, cls).__new__
# Also ensure initialization is only performed for subclasses of Model # Also ensure initialization is only performed for subclasses of Model
# (excluding Model class itself). # (excluding Model class itself).
if not is_base_type(bases, ScalarTypeMeta): if not is_base_type(bases, ScalarTypeMeta):
return super_new(cls, name, bases, attrs) return type.__new__(cls, name, bases, attrs)
options = Options( options = Options(
attrs.pop('Meta', None), attrs.pop('Meta', None),
@ -24,13 +22,21 @@ class ScalarTypeMeta(type):
description=attrs.get('__doc__'), description=attrs.get('__doc__'),
) )
return super_new(cls, name, bases, dict(attrs, _meta=options)) return type.__new__(cls, name, bases, dict(attrs, _meta=options))
def __str__(cls): # noqa: N802 def __str__(cls): # noqa: N802
return cls._meta.name return cls._meta.name
class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)): class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
'''
Scalar Type Definition
The leaf values of any request and input values to arguments are
Scalars (or Enums) and are defined with a name and a series of functions
used to parse input from ast or variables and to ensure validity.
'''
serialize = None serialize = None
parse_value = None parse_value = None
parse_literal = None parse_literal = None

View File

@ -9,15 +9,14 @@ from graphql.utils.schema_printer import print_schema
from .typemap import TypeMap, is_graphene_type from .typemap import TypeMap, is_graphene_type
# from ..utils.get_graphql_type import get_graphql_type
# from graphql.type.schema import assert_object_implements_interface
# from collections import defaultdict
class Schema(GraphQLSchema): class Schema(GraphQLSchema):
'''
Schema Definition
A Schema is created by supplying the root types of each type of operation,
query and mutation (optional). A schema definition is then supplied to the
validator and executor.
'''
def __init__(self, query=None, mutation=None, subscription=None, def __init__(self, query=None, mutation=None, subscription=None,
directives=None, types=None, executor=None, middlewares=None): directives=None, types=None, executor=None, middlewares=None):

View File

@ -16,12 +16,30 @@ class Structure(UnmountedType):
class List(Structure): class List(Structure):
'''
List Modifier
A list is a kind of type marker, a wrapping type which points to another
type. Lists are often created within the context of defining the fields of
an object type.
'''
def __str__(self): def __str__(self):
return '[{}]'.format(self.of_type) return '[{}]'.format(self.of_type)
class NonNull(Structure): class NonNull(Structure):
'''
Non-Null Modifier
A non-null is a kind of type marker, a wrapping type which points to another
type. Non-null types enforce that their values are never null and can ensure
an error is raised if this ever occurs during a request. It is useful for
fields which you can make a strong guarantee on non-nullability, for example
usually the id field of a database row will never be null.
Note: the enforcement of non-nullability occurs within the executor.
'''
def __str__(self): def __str__(self):
return '{}!'.format(self.of_type) return '{}!'.format(self.of_type)

View File

@ -31,6 +31,14 @@ class UnionMeta(type):
class Union(six.with_metaclass(UnionMeta)): class Union(six.with_metaclass(UnionMeta)):
'''
Union Type Definition
When a field can return one of a heterogeneous set of types, a Union type
is used to describe what types are possible as well as providing a function
to determine which type is actually used when the field is resolved.
'''
resolve_type = None resolve_type = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -4,7 +4,7 @@ from ..utils.orderedtype import OrderedType
class UnmountedType(OrderedType): class UnmountedType(OrderedType):
''' '''
This class acts a proxy for a Graphene Type, so it can be mounted This class acts a proxy for a Graphene Type, so it can be mounted
as Field, InputField or Argument. dynamically as Field, InputField or Argument.
Instead of writing Instead of writing
>>> class MyObjectType(ObjectType): >>> class MyObjectType(ObjectType):

View File

@ -7,6 +7,9 @@ from .unmountedtype import UnmountedType
def merge(*dicts): def merge(*dicts):
'''
Merge the dicts into one
'''
merged = OrderedDict() merged = OrderedDict()
for _dict in dicts: for _dict in dicts:
merged.update(_dict) merged.update(_dict)
@ -14,6 +17,9 @@ def merge(*dicts):
def get_base_fields(bases, _as=None): def get_base_fields(bases, _as=None):
'''
Get all the fields in the given bases
'''
fields = OrderedDict() fields = OrderedDict()
from ..types import AbstractType, Interface from ..types import AbstractType, Interface
# We allow inheritance in AbstractTypes and Interfaces but not ObjectTypes # We allow inheritance in AbstractTypes and Interfaces but not ObjectTypes
@ -50,6 +56,9 @@ def mount_as(unmounted_field, _as):
def get_field_as(value, _as=None): def get_field_as(value, _as=None):
'''
Get type mounted
'''
if isinstance(value, (Field, InputField, Dynamic)): if isinstance(value, (Field, InputField, Dynamic)):
return value return value
elif isinstance(value, UnmountedType): elif isinstance(value, UnmountedType):
@ -57,6 +66,10 @@ def get_field_as(value, _as=None):
def yank_fields_from_attrs(attrs, _as=None): def yank_fields_from_attrs(attrs, _as=None):
'''
Extract all the fields in given attributes (dict)
and return them ordered
'''
fields_with_names = [] fields_with_names = []
for attname, value in list(attrs.items()): for attname, value in list(attrs.items()):
field = get_field_as(value, _as) field = get_field_as(value, _as)