mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Improved tests and schema definition.
This commit is contained in:
		
							parent
							
								
									750bbfbc2c
								
							
						
					
					
						commit
						eafc9a102e
					
				| 
						 | 
				
			
			@ -6,6 +6,21 @@ from graphql.core.type import (
 | 
			
		|||
    GraphQLID as ID
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from graphene import signals
 | 
			
		||||
 | 
			
		||||
from graphene.core.schema import (
 | 
			
		||||
    Schema
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from graphene.env import (
 | 
			
		||||
    get_global_schema
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from graphene.core.types import (
 | 
			
		||||
    ObjectType,
 | 
			
		||||
    Interface
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from graphene.core.fields import (
 | 
			
		||||
    Field,
 | 
			
		||||
    StringField,
 | 
			
		||||
| 
						 | 
				
			
			@ -16,12 +31,6 @@ from graphene.core.fields import (
 | 
			
		|||
    NonNullField,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from graphene.core.types import (
 | 
			
		||||
    ObjectType,
 | 
			
		||||
    Interface,
 | 
			
		||||
    Schema
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from graphene.decorators import (
 | 
			
		||||
    resolve_only_args
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
import inspect
 | 
			
		||||
from graphql.core.type import (
 | 
			
		||||
    GraphQLField,
 | 
			
		||||
    GraphQLList,
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +10,7 @@ from graphql.core.type import (
 | 
			
		|||
    GraphQLArgument,
 | 
			
		||||
)
 | 
			
		||||
from graphene.utils import cached_property
 | 
			
		||||
from graphene.core.utils import get_object_type
 | 
			
		||||
from graphene.core.types import ObjectType
 | 
			
		||||
 | 
			
		||||
class Field(object):
 | 
			
		||||
    def __init__(self, field_type, resolve=None, null=True, args=None, description='', **extra_args):
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +26,7 @@ class Field(object):
 | 
			
		|||
    def contribute_to_class(self, cls, name):
 | 
			
		||||
        self.field_name = name
 | 
			
		||||
        self.object_type = cls
 | 
			
		||||
        self.schema = cls._meta.schema
 | 
			
		||||
        if isinstance(self.field_type, Field) and not self.field_type.object_type:
 | 
			
		||||
            self.field_type.contribute_to_class(cls, name)
 | 
			
		||||
        cls._meta.add_field(self)
 | 
			
		||||
| 
						 | 
				
			
			@ -42,12 +44,27 @@ class Field(object):
 | 
			
		|||
            resolve_fn = lambda root, args, info: root.resolve(self.field_name, args, info)
 | 
			
		||||
        return resolve_fn(instance, args, info)
 | 
			
		||||
 | 
			
		||||
    def get_object_type(self):
 | 
			
		||||
        field_type = self.field_type
 | 
			
		||||
        _is_class = inspect.isclass(field_type)
 | 
			
		||||
        if _is_class and issubclass(field_type, ObjectType):
 | 
			
		||||
            return field_type
 | 
			
		||||
        elif isinstance(field_type, basestring):
 | 
			
		||||
            if field_type == 'self':
 | 
			
		||||
                return self.object_type
 | 
			
		||||
            elif self.schema:
 | 
			
		||||
                return self.schema.get_type(field_type)
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def type(self):
 | 
			
		||||
        if isinstance(self.field_type, Field):
 | 
			
		||||
        field_type = self.field_type
 | 
			
		||||
        if isinstance(field_type, Field):
 | 
			
		||||
            field_type = self.field_type.type
 | 
			
		||||
        else:
 | 
			
		||||
            field_type = get_object_type(self.field_type, self.object_type)
 | 
			
		||||
            object_type = self.get_object_type()
 | 
			
		||||
            if object_type:
 | 
			
		||||
                field_type = object_type._meta.type
 | 
			
		||||
 | 
			
		||||
        field_type = self.type_wrapper(field_type)
 | 
			
		||||
        return field_type
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +1,19 @@
 | 
			
		|||
from graphene.env import get_global_schema
 | 
			
		||||
from graphene.utils import cached_property
 | 
			
		||||
 | 
			
		||||
DEFAULT_NAMES = ('app_label', 'description', 'name', 'interface',
 | 
			
		||||
DEFAULT_NAMES = ('description', 'name', 'interface', 'schema',
 | 
			
		||||
                 'type_name', 'interfaces',  'proxy')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Options(object):
 | 
			
		||||
    def __init__(self, meta=None, app_label=None):
 | 
			
		||||
    def __init__(self, meta=None, schema=None):
 | 
			
		||||
        self.meta = meta
 | 
			
		||||
        self.local_fields = []
 | 
			
		||||
        self.interface = False
 | 
			
		||||
        self.proxy = False
 | 
			
		||||
        self.schema = schema or get_global_schema()
 | 
			
		||||
        self.interfaces = []
 | 
			
		||||
        self.parents = []
 | 
			
		||||
        self.app_label = app_label
 | 
			
		||||
 | 
			
		||||
    def contribute_to_class(self, cls, name):
 | 
			
		||||
        cls._meta = self
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										73
									
								
								graphene/core/schema.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								graphene/core/schema.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
from graphql.core import graphql
 | 
			
		||||
from graphql.core.type import (
 | 
			
		||||
    GraphQLSchema
 | 
			
		||||
)
 | 
			
		||||
from graphene import signals
 | 
			
		||||
from graphene.utils import cached_property
 | 
			
		||||
# from graphene.relay.nodes import create_node_definitions
 | 
			
		||||
 | 
			
		||||
class Schema(object):
 | 
			
		||||
    _query = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self, query=None, mutation=None, name='Schema'):
 | 
			
		||||
        self.mutation = mutation
 | 
			
		||||
        self.query = query
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self._types = {}
 | 
			
		||||
        
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        return '<Schema: %s>' % str(self.name)
 | 
			
		||||
 | 
			
		||||
    # @cachedproperty
 | 
			
		||||
    # def node_definitions(self):
 | 
			
		||||
    #     return [object, object]
 | 
			
		||||
    #     # from graphene.relay import create_node_definitions
 | 
			
		||||
    #     # return create_node_definitions(schema=self)
 | 
			
		||||
 | 
			
		||||
    # @property
 | 
			
		||||
    # def Node(self):
 | 
			
		||||
    #     return self.node_definitions[0]
 | 
			
		||||
 | 
			
		||||
    # @property
 | 
			
		||||
    # def NodeField(self):
 | 
			
		||||
    #     return self.node_definitions[1]
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def query(self):
 | 
			
		||||
        return self._query
 | 
			
		||||
    @query.setter
 | 
			
		||||
    def query(self, query):
 | 
			
		||||
        if not query:
 | 
			
		||||
            return
 | 
			
		||||
        self._query = query
 | 
			
		||||
        self._query_type = query._meta.type
 | 
			
		||||
        self._schema = GraphQLSchema(query=self._query_type, mutation=self.mutation)
 | 
			
		||||
 | 
			
		||||
    def register_type(self, type):
 | 
			
		||||
        type_name = type._meta.type_name
 | 
			
		||||
        if type_name in self._types:
 | 
			
		||||
            raise Exception('Type name %s already registered in %r' % (type_name, self))
 | 
			
		||||
        self._types[type_name] = type
 | 
			
		||||
 | 
			
		||||
    def get_type(self, type_name):
 | 
			
		||||
        if type_name not in self._types:
 | 
			
		||||
            raise Exception('Type %s not found in %r' % (type_name, self))
 | 
			
		||||
        return self._types[type_name]
 | 
			
		||||
 | 
			
		||||
    def execute(self, request='', root=None, vars=None, operation_name=None):
 | 
			
		||||
        return graphql(
 | 
			
		||||
            self._schema,
 | 
			
		||||
            request=request,
 | 
			
		||||
            root=root or self.query(),
 | 
			
		||||
            vars=vars,
 | 
			
		||||
            operation_name=operation_name
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@signals.class_prepared.connect
 | 
			
		||||
def object_type_created(object_type):
 | 
			
		||||
    schema = object_type._meta.schema
 | 
			
		||||
    if schema:
 | 
			
		||||
        schema.register_type(object_type)
 | 
			
		||||
 | 
			
		||||
from graphene.env import get_global_schema
 | 
			
		||||
| 
						 | 
				
			
			@ -3,10 +3,8 @@ import six
 | 
			
		|||
 | 
			
		||||
from graphql.core.type import (
 | 
			
		||||
    GraphQLObjectType,
 | 
			
		||||
    GraphQLInterfaceType,
 | 
			
		||||
    GraphQLSchema
 | 
			
		||||
    GraphQLInterfaceType
 | 
			
		||||
)
 | 
			
		||||
from graphql.core import graphql
 | 
			
		||||
 | 
			
		||||
from graphene import signals
 | 
			
		||||
from graphene.core.options import Options
 | 
			
		||||
| 
						 | 
				
			
			@ -33,12 +31,9 @@ class ObjectTypeMeta(type):
 | 
			
		|||
            meta = attr_meta
 | 
			
		||||
        base_meta = getattr(new_class, '_meta', None)
 | 
			
		||||
 | 
			
		||||
        if '.' in module:
 | 
			
		||||
            app_label, _ = module.rsplit('.', 1)
 | 
			
		||||
        else:
 | 
			
		||||
            app_label = module
 | 
			
		||||
        schema = (base_meta and base_meta.schema)
 | 
			
		||||
 | 
			
		||||
        new_class.add_to_class('_meta', Options(meta, app_label))
 | 
			
		||||
        new_class.add_to_class('_meta', Options(meta, schema))
 | 
			
		||||
        if base_meta and base_meta.proxy:
 | 
			
		||||
            new_class._meta.interface = base_meta.interface
 | 
			
		||||
        # Add all attributes to the class.
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +49,8 @@ class ObjectTypeMeta(type):
 | 
			
		|||
                # Things without _meta aren't functional models, so they're
 | 
			
		||||
                # uninteresting parents.
 | 
			
		||||
                continue
 | 
			
		||||
            if base._meta.schema != new_class._meta.schema:
 | 
			
		||||
                raise Exception('The parent schema is not the same')
 | 
			
		||||
 | 
			
		||||
            parent_fields = base._meta.local_fields
 | 
			
		||||
            # Check for clashes between locally declared fields and those
 | 
			
		||||
| 
						 | 
				
			
			@ -138,19 +135,3 @@ class Interface(ObjectType):
 | 
			
		|||
    class Meta:
 | 
			
		||||
        interface = True
 | 
			
		||||
        proxy = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Schema(object):
 | 
			
		||||
    def __init__(self, query, mutation=None):
 | 
			
		||||
        self.query = query
 | 
			
		||||
        self.query_type = query._meta.type
 | 
			
		||||
        self._schema = GraphQLSchema(query=self.query_type, mutation=mutation)
 | 
			
		||||
 | 
			
		||||
    def execute(self, request='', root=None, vars=None, operation_name=None):
 | 
			
		||||
        return graphql(
 | 
			
		||||
            self._schema,
 | 
			
		||||
            request=request,
 | 
			
		||||
            root=root or self.query(),
 | 
			
		||||
            vars=vars,
 | 
			
		||||
            operation_name=operation_name
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
import inspect
 | 
			
		||||
 | 
			
		||||
from graphene.core.types import ObjectType
 | 
			
		||||
from graphene import signals
 | 
			
		||||
 | 
			
		||||
registered_object_types = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_object_type(field_type, object_type=None):
 | 
			
		||||
    native_type = get_type(field_type, object_type)
 | 
			
		||||
    if native_type:
 | 
			
		||||
        field_type = native_type._meta.type
 | 
			
		||||
    return field_type 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_type(field_type, object_type=None):
 | 
			
		||||
    _is_class = inspect.isclass(field_type)
 | 
			
		||||
    if _is_class and issubclass(field_type, ObjectType):
 | 
			
		||||
        return field_type
 | 
			
		||||
    elif isinstance(field_type, basestring):
 | 
			
		||||
        if field_type == 'self':
 | 
			
		||||
            return object_type
 | 
			
		||||
        else:
 | 
			
		||||
            object_type = get_registered_object_type(field_type, object_type)
 | 
			
		||||
            return object_type
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
def get_registered_object_type(name, object_type=None):
 | 
			
		||||
    app_label = None
 | 
			
		||||
    object_type_name = name
 | 
			
		||||
 | 
			
		||||
    if '.' in name:
 | 
			
		||||
        app_label, object_type_name = name.rsplit('.', 1)
 | 
			
		||||
    elif object_type:
 | 
			
		||||
        app_label = object_type._meta.app_label
 | 
			
		||||
 | 
			
		||||
    # Filter all registered object types which have the same name
 | 
			
		||||
    ots = [ot for ot in registered_object_types if ot._meta.type_name == object_type_name]
 | 
			
		||||
    # If the list have more than one object type with the name, filter by
 | 
			
		||||
    # the app_label
 | 
			
		||||
    if len(ots)>1 and app_label:
 | 
			
		||||
        ots = [ot for ot in ots if ot._meta.app_label == app_label]
 | 
			
		||||
 | 
			
		||||
    if len(ots)>1:
 | 
			
		||||
        raise Exception('Multiple ObjectTypes returned with the name %s' % name)
 | 
			
		||||
    if not ots:
 | 
			
		||||
        raise Exception('No ObjectType found with name %s' % name)
 | 
			
		||||
 | 
			
		||||
    return ots[0]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@signals.class_prepared.connect
 | 
			
		||||
def object_type_created(sender):
 | 
			
		||||
    registered_object_types.append(sender)
 | 
			
		||||
							
								
								
									
										9
									
								
								graphene/env.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								graphene/env.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
from graphene.core.schema import Schema
 | 
			
		||||
 | 
			
		||||
_global_schema = None
 | 
			
		||||
 | 
			
		||||
def get_global_schema():
 | 
			
		||||
	global _global_schema
 | 
			
		||||
	if not _global_schema:
 | 
			
		||||
		_global_schema = Schema(name='Global Schema')
 | 
			
		||||
	return _global_schema
 | 
			
		||||
| 
						 | 
				
			
			@ -1,85 +1,5 @@
 | 
			
		|||
import collections
 | 
			
		||||
 | 
			
		||||
from graphene import signals
 | 
			
		||||
from graphene.core.fields import Field, NativeField
 | 
			
		||||
from graphene.core.types import Interface
 | 
			
		||||
from graphene.core.utils import get_type
 | 
			
		||||
from graphene.utils import cached_property
 | 
			
		||||
 | 
			
		||||
from graphql_relay.node.node import (
 | 
			
		||||
    nodeDefinitions,
 | 
			
		||||
    globalIdField,
 | 
			
		||||
    fromGlobalId
 | 
			
		||||
)
 | 
			
		||||
from graphql_relay.connection.arrayconnection import (
 | 
			
		||||
    connectionFromArray
 | 
			
		||||
)
 | 
			
		||||
from graphql_relay.connection.connection import (
 | 
			
		||||
    connectionArgs,
 | 
			
		||||
    connectionDefinitions
 | 
			
		||||
from graphene.relay.nodes import (
 | 
			
		||||
	create_node_definitions
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
registered_nodes = {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getNode(globalId, *args):
 | 
			
		||||
    resolvedGlobalId = fromGlobalId(globalId)
 | 
			
		||||
    _type, _id = resolvedGlobalId.type, resolvedGlobalId.id
 | 
			
		||||
    if _type in registered_nodes:
 | 
			
		||||
        object_type = registered_nodes[_type]
 | 
			
		||||
        return object_type.get_node(_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getNodeType(obj):
 | 
			
		||||
    return obj._meta.type
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_nodeDefinitions = nodeDefinitions(getNode, getNodeType)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Node(Interface):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_graphql_type(cls):
 | 
			
		||||
        if cls is Node:
 | 
			
		||||
            # Return only nodeInterface when is the Node Inerface
 | 
			
		||||
            return _nodeDefinitions.nodeInterface
 | 
			
		||||
        return super(Node, cls).get_graphql_type()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NodeField(NativeField):
 | 
			
		||||
    field = _nodeDefinitions.nodeField
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ConnectionField(Field):
 | 
			
		||||
    def __init__(self, field_type, resolve=None, description=''):
 | 
			
		||||
        super(ConnectionField, self).__init__(field_type, resolve=resolve, 
 | 
			
		||||
                                              args=connectionArgs, description=description)
 | 
			
		||||
 | 
			
		||||
    def resolve(self, instance, args, info):
 | 
			
		||||
        resolved = super(ConnectionField, self).resolve(instance, args, info)
 | 
			
		||||
        if resolved:
 | 
			
		||||
            assert isinstance(resolved, collections.Iterable), 'Resolved value from the connection field have to be iterable'
 | 
			
		||||
            return connectionFromArray(resolved, args)
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def type(self):
 | 
			
		||||
        object_type = get_type(self.field_type, self.object_type)
 | 
			
		||||
        assert issubclass(object_type, Node), 'Only nodes have connections.'
 | 
			
		||||
        return object_type.connection
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@signals.class_prepared.connect
 | 
			
		||||
def object_type_created(object_type):
 | 
			
		||||
    if issubclass(object_type, Node):
 | 
			
		||||
        type_name = object_type._meta.type_name
 | 
			
		||||
        assert type_name not in registered_nodes, 'Two nodes with the same type_name: %s' % type_name
 | 
			
		||||
        registered_nodes[type_name] = object_type
 | 
			
		||||
        # def getId(*args, **kwargs):
 | 
			
		||||
        #     print '**GET ID', args, kwargs
 | 
			
		||||
        #     return 2
 | 
			
		||||
        field = NativeField(globalIdField(type_name))
 | 
			
		||||
        object_type.add_to_class('id', field)
 | 
			
		||||
        assert hasattr(object_type, 'get_node'), 'get_node classmethod not found in %s Node' % type_name
 | 
			
		||||
 | 
			
		||||
        connection = connectionDefinitions(type_name, object_type._meta.type).connectionType
 | 
			
		||||
        object_type.add_to_class('connection', connection)
 | 
			
		||||
from graphene.relay.relay import *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										37
									
								
								graphene/relay/nodes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								graphene/relay/nodes.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
from graphql_relay.node.node import (
 | 
			
		||||
    nodeDefinitions,
 | 
			
		||||
    fromGlobalId
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
def create_node_definitions(getNode=None, getNodeType=None, schema=None):
 | 
			
		||||
    from graphene.core.types import Interface
 | 
			
		||||
    from graphene.core.fields import Field, NativeField
 | 
			
		||||
    if not getNode:
 | 
			
		||||
        def getNode(globalId, *args):
 | 
			
		||||
            from graphene.env import get_global_schema
 | 
			
		||||
            _schema = schema or get_global_schema()
 | 
			
		||||
            resolvedGlobalId = fromGlobalId(globalId)
 | 
			
		||||
            _type, _id = resolvedGlobalId.type, resolvedGlobalId.id
 | 
			
		||||
            object_type = _schema.get_type(_type) 
 | 
			
		||||
            return object_type.get_node(_id)
 | 
			
		||||
 | 
			
		||||
    if not getNodeType:
 | 
			
		||||
        def getNodeType(obj):
 | 
			
		||||
            return obj._meta.type
 | 
			
		||||
 | 
			
		||||
    _nodeDefinitions = nodeDefinitions(getNode, getNodeType)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Node(Interface):
 | 
			
		||||
        @classmethod
 | 
			
		||||
        def get_graphql_type(cls):
 | 
			
		||||
            if cls is Node:
 | 
			
		||||
                # Return only nodeInterface when is the Node Inerface
 | 
			
		||||
                return _nodeDefinitions.nodeInterface
 | 
			
		||||
            return super(Node, cls).get_graphql_type()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class NodeField(NativeField):
 | 
			
		||||
        field = _nodeDefinitions.nodeField
 | 
			
		||||
 | 
			
		||||
    return Node, NodeField
 | 
			
		||||
							
								
								
									
										51
									
								
								graphene/relay/relay.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								graphene/relay/relay.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
import collections
 | 
			
		||||
 | 
			
		||||
from graphene import signals
 | 
			
		||||
from graphene.utils import cached_property
 | 
			
		||||
 | 
			
		||||
from graphql_relay.node.node import (
 | 
			
		||||
    globalIdField
 | 
			
		||||
)
 | 
			
		||||
from graphql_relay.connection.arrayconnection import (
 | 
			
		||||
    connectionFromArray
 | 
			
		||||
)
 | 
			
		||||
from graphql_relay.connection.connection import (
 | 
			
		||||
    connectionArgs,
 | 
			
		||||
    connectionDefinitions
 | 
			
		||||
)
 | 
			
		||||
from graphene.relay.nodes import create_node_definitions
 | 
			
		||||
from graphene.core.fields import Field, NativeField
 | 
			
		||||
 | 
			
		||||
Node, NodeField = create_node_definitions()
 | 
			
		||||
 | 
			
		||||
class ConnectionField(Field):
 | 
			
		||||
    def __init__(self, field_type, resolve=None, description=''):
 | 
			
		||||
        super(ConnectionField, self).__init__(field_type, resolve=resolve, 
 | 
			
		||||
                                              args=connectionArgs, description=description)
 | 
			
		||||
 | 
			
		||||
    def resolve(self, instance, args, info):
 | 
			
		||||
        resolved = super(ConnectionField, self).resolve(instance, args, info)
 | 
			
		||||
        if resolved:
 | 
			
		||||
            assert isinstance(resolved, collections.Iterable), 'Resolved value from the connection field have to be iterable'
 | 
			
		||||
            return connectionFromArray(resolved, args)
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def type(self):
 | 
			
		||||
        object_type = self.get_object_type()
 | 
			
		||||
        assert issubclass(object_type, Node), 'Only nodes have connections.'
 | 
			
		||||
        return object_type.connection
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@signals.class_prepared.connect
 | 
			
		||||
def object_type_created(object_type):
 | 
			
		||||
    if issubclass(object_type, Node):
 | 
			
		||||
        type_name = object_type._meta.type_name
 | 
			
		||||
        # def getId(*args, **kwargs):
 | 
			
		||||
        #     print '**GET ID', args, kwargs
 | 
			
		||||
        #     return 2
 | 
			
		||||
        field = NativeField(globalIdField(type_name))
 | 
			
		||||
        object_type.add_to_class('id', field)
 | 
			
		||||
        assert hasattr(object_type, 'get_node'), 'get_node classmethod not found in %s Node' % type_name
 | 
			
		||||
 | 
			
		||||
        connection = connectionDefinitions(type_name, object_type._meta.type).connectionType
 | 
			
		||||
        object_type.add_to_class('connection', connection)
 | 
			
		||||
| 
						 | 
				
			
			@ -18,15 +18,18 @@ from graphene.core.types import (
 | 
			
		|||
class Character(Interface):
 | 
			
		||||
    '''Character description'''
 | 
			
		||||
    name = StringField()
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        type_name = 'core.Character'
 | 
			
		||||
class Human(Character):
 | 
			
		||||
    '''Human description'''
 | 
			
		||||
    friends = StringField()
 | 
			
		||||
    class Meta:
 | 
			
		||||
        type_name = 'core.Human'
 | 
			
		||||
 | 
			
		||||
def test_interface():
 | 
			
		||||
    object_type = Character._meta.type
 | 
			
		||||
    assert Character._meta.interface == True
 | 
			
		||||
    assert Character._meta.type_name == 'Character'
 | 
			
		||||
    assert Character._meta.type_name == 'core.Character'
 | 
			
		||||
    assert isinstance(object_type, GraphQLInterfaceType)
 | 
			
		||||
    assert object_type.description == 'Character description'
 | 
			
		||||
    assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].field}
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +37,7 @@ def test_interface():
 | 
			
		|||
def test_object_type():
 | 
			
		||||
    object_type = Human._meta.type
 | 
			
		||||
    assert Human._meta.interface == False
 | 
			
		||||
    assert Human._meta.type_name == 'Human'
 | 
			
		||||
    assert Human._meta.type_name == 'core.Human'
 | 
			
		||||
    assert isinstance(object_type, GraphQLObjectType)
 | 
			
		||||
    assert object_type.description == 'Human description'
 | 
			
		||||
    assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].field, 'friends': Human._meta.fields_map['friends'].field}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ from pytest import raises
 | 
			
		|||
import graphene
 | 
			
		||||
from graphene import relay
 | 
			
		||||
 | 
			
		||||
schema = graphene.Schema()
 | 
			
		||||
 | 
			
		||||
class OtherNode(relay.Node):
 | 
			
		||||
    name = graphene.StringField()
 | 
			
		||||
| 
						 | 
				
			
			@ -28,14 +29,19 @@ def test_node_should_have_id_field():
 | 
			
		|||
    assert 'id' in OtherNode._meta.fields_map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_field_no_contributed_raises_error():
 | 
			
		||||
    with raises(Exception) as excinfo:
 | 
			
		||||
        class Ship(graphene.ObjectType):
 | 
			
		||||
            name = graphene.StringField()
 | 
			
		||||
# def test_field_no_contributed_raises_error():
 | 
			
		||||
#     with raises(Exception) as excinfo:
 | 
			
		||||
#         class Ship(graphene.ObjectType):
 | 
			
		||||
#             name = graphene.StringField()
 | 
			
		||||
#             class Meta:
 | 
			
		||||
#                 schema = schema
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        class Faction(relay.Node):
 | 
			
		||||
            name = graphene.StringField()
 | 
			
		||||
            ships = relay.ConnectionField(Ship)
 | 
			
		||||
 | 
			
		||||
    assert 'same type_name' in str(excinfo.value)
 | 
			
		||||
#         class Faction(relay.Node):
 | 
			
		||||
#             name = graphene.StringField()
 | 
			
		||||
#             ships = relay.ConnectionField(Ship)
 | 
			
		||||
#             @classmethod
 | 
			
		||||
#             def get_node(cls):
 | 
			
		||||
#                 pass
 | 
			
		||||
#             class Meta:
 | 
			
		||||
#                 schema = schema
 | 
			
		||||
#     assert 'same type_name' in str(excinfo.value)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,9 @@ class Query(graphene.ObjectType):
 | 
			
		|||
        id = graphene.Argument(graphene.String)
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        type_name = 'core.Query'
 | 
			
		||||
 | 
			
		||||
    @resolve_only_args
 | 
			
		||||
    def resolve_hero(self, episode):
 | 
			
		||||
        return wrap_character(getHero(episode))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ from .data import (
 | 
			
		|||
    getEmpire,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
schema = graphene.Schema()
 | 
			
		||||
 | 
			
		||||
class Ship(relay.Node):
 | 
			
		||||
    '''A ship in the Star Wars saga'''
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +20,8 @@ class Ship(relay.Node):
 | 
			
		|||
        if ship:
 | 
			
		||||
            return Ship(ship)
 | 
			
		||||
 | 
			
		||||
    # class Meta:
 | 
			
		||||
    #     schema = schema
 | 
			
		||||
 | 
			
		||||
class Faction(relay.Node):
 | 
			
		||||
    '''A faction in the Star Wars saga'''
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +38,9 @@ class Faction(relay.Node):
 | 
			
		|||
        if faction:
 | 
			
		||||
            return Faction(faction)
 | 
			
		||||
 | 
			
		||||
    # class Meta:
 | 
			
		||||
    #     schema = schema
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Query(graphene.ObjectType):
 | 
			
		||||
    rebels = graphene.Field(Faction)
 | 
			
		||||
| 
						 | 
				
			
			@ -50,4 +56,10 @@ class Query(graphene.ObjectType):
 | 
			
		|||
        return Faction(getEmpire())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Schema = graphene.Schema(query=Query)
 | 
			
		||||
    # class Meta:
 | 
			
		||||
    #     schema = schema
 | 
			
		||||
 | 
			
		||||
print '*CACA', schema._types
 | 
			
		||||
 | 
			
		||||
schema.query = Query
 | 
			
		||||
Schema = schema
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user