mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
First relay version
This commit is contained in:
parent
f2bc5eddd5
commit
9a84d595a1
|
@ -3,7 +3,7 @@ sudo: false
|
|||
python:
|
||||
- 2.7
|
||||
install:
|
||||
- pip install pytest pytest-cov coveralls flake8 six
|
||||
- pip install pytest pytest-cov coveralls flake8 six blinker
|
||||
- pip install git+https://github.com/dittos/graphqllib.git # Last version of graphqllib
|
||||
- pip install graphql-relay
|
||||
- python setup.py develop
|
||||
|
|
|
@ -26,3 +26,7 @@ from graphene.core.types import (
|
|||
from graphene.decorators import (
|
||||
resolve_only_args
|
||||
)
|
||||
|
||||
from graphene.relay import (
|
||||
Relay
|
||||
)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import inspect
|
||||
from graphql.core.type import (
|
||||
GraphQLField,
|
||||
GraphQLList,
|
||||
|
@ -9,8 +8,8 @@ from graphql.core.type import (
|
|||
GraphQLID,
|
||||
GraphQLArgument,
|
||||
)
|
||||
from graphene.core.types import ObjectType, Interface
|
||||
from graphene.utils import cached_property
|
||||
from graphene.core.utils import get_object_type
|
||||
|
||||
class Field(object):
|
||||
def __init__(self, field_type, resolve=None, null=True, args=None, description='', **extra_args):
|
||||
|
@ -45,16 +44,11 @@ class Field(object):
|
|||
|
||||
@cached_property
|
||||
def type(self):
|
||||
field_type = self.field_type
|
||||
_is_class = inspect.isclass(field_type)
|
||||
if _is_class and issubclass(field_type, ObjectType):
|
||||
field_type = field_type._meta.type
|
||||
elif isinstance(field_type, Field):
|
||||
field_type = field_type.type
|
||||
elif field_type == 'self':
|
||||
field_type = self.object_type._meta.type
|
||||
if isinstance(self.field_type, Field):
|
||||
field_type = self.field_type.type
|
||||
else:
|
||||
field_type = get_object_type(self.field_type, self.object_type)
|
||||
field_type = self.type_wrapper(field_type)
|
||||
|
||||
return field_type
|
||||
|
||||
def type_wrapper(self, field_type):
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from graphene.utils import cached_property
|
||||
|
||||
DEFAULT_NAMES = ('description', 'name', 'interface', 'type_name', 'interfaces', 'proxy')
|
||||
DEFAULT_NAMES = ('description', 'name', 'interface',
|
||||
'type_name', 'interfaces', 'proxy')
|
||||
|
||||
|
||||
class Options(object):
|
||||
def __init__(self, meta=None):
|
||||
|
|
|
@ -8,8 +8,10 @@ from graphql.core.type import (
|
|||
)
|
||||
from graphql.core import graphql
|
||||
|
||||
from graphene import signals
|
||||
from graphene.core.options import Options
|
||||
|
||||
|
||||
class ObjectTypeMeta(type):
|
||||
def __new__(cls, name, bases, attrs):
|
||||
super_new = super(ObjectTypeMeta, cls).__new__
|
||||
|
@ -20,7 +22,10 @@ class ObjectTypeMeta(type):
|
|||
|
||||
module = attrs.pop('__module__')
|
||||
doc = attrs.pop('__doc__', None)
|
||||
new_class = super_new(cls, name, bases, {'__module__': module, '__doc__': doc})
|
||||
new_class = super_new(cls, name, bases, {
|
||||
'__module__': module,
|
||||
'__doc__': doc
|
||||
})
|
||||
attr_meta = attrs.pop('Meta', None)
|
||||
if not attr_meta:
|
||||
meta = getattr(new_class, 'Meta', None)
|
||||
|
@ -51,7 +56,7 @@ class ObjectTypeMeta(type):
|
|||
# moment).
|
||||
for field in parent_fields:
|
||||
if field.field_name in field_names:
|
||||
raise FieldError(
|
||||
raise Exception(
|
||||
'Local field %r in class %r clashes '
|
||||
'with field of similar name from '
|
||||
'base class %r' % (field.field_name, name, base.__name__)
|
||||
|
@ -61,8 +66,12 @@ class ObjectTypeMeta(type):
|
|||
new_class._meta.interfaces.append(base)
|
||||
# new_class._meta.parents.extend(base._meta.parents)
|
||||
|
||||
new_class._prepare()
|
||||
return new_class
|
||||
|
||||
def _prepare(cls):
|
||||
signals.class_prepared.send(cls)
|
||||
|
||||
def add_to_class(cls, name, value):
|
||||
# We should call the contribute_to_class method only if it's bound
|
||||
if not inspect.isclass(value) and hasattr(value, 'contribute_to_class'):
|
||||
|
@ -73,7 +82,9 @@ class ObjectTypeMeta(type):
|
|||
|
||||
class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
||||
def __init__(self, instance=None):
|
||||
signals.pre_init.send(self.__class__, instance=instance)
|
||||
self.instance = instance
|
||||
signals.post_init.send(self.__class__, instance=self)
|
||||
|
||||
def get_field(self, field):
|
||||
return getattr(self.instance, field, None)
|
||||
|
|
30
graphene/core/utils.py
Normal file
30
graphene/core/utils.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
import inspect
|
||||
|
||||
from graphene.core.types import ObjectType
|
||||
from graphene import signals
|
||||
|
||||
registered_object_types = []
|
||||
|
||||
|
||||
def get_object_type(field_type, object_type=None):
|
||||
_is_class = inspect.isclass(field_type)
|
||||
if _is_class and issubclass(field_type, ObjectType):
|
||||
field_type = field_type._meta.type
|
||||
elif isinstance(field_type, basestring):
|
||||
if field_type == 'self':
|
||||
field_type = object_type._meta.type
|
||||
else:
|
||||
object_type = get_registered_object_type(field_type)
|
||||
field_type = object_type._meta.type
|
||||
return field_type
|
||||
|
||||
|
||||
def get_registered_object_type(name):
|
||||
for object_type in registered_object_types:
|
||||
if object_type._meta.type_name == name:
|
||||
return object_type
|
||||
return None
|
||||
|
||||
@signals.class_prepared.connect
|
||||
def object_type_created(sender):
|
||||
registered_object_types.append(sender)
|
|
@ -0,0 +1,2 @@
|
|||
class Relay(object):
|
||||
pass
|
5
graphene/signals.py
Normal file
5
graphene/signals.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from blinker import Signal
|
||||
|
||||
class_prepared = Signal()
|
||||
pre_init = Signal()
|
||||
post_init = Signal()
|
1
setup.py
1
setup.py
|
@ -48,6 +48,7 @@ setup(
|
|||
|
||||
install_requires=[
|
||||
'six',
|
||||
'blinker',
|
||||
'graphqllib',
|
||||
'graphql-relay'
|
||||
],
|
||||
|
|
|
@ -18,7 +18,7 @@ def wrap_character(character):
|
|||
class Character(graphene.Interface):
|
||||
id = graphene.IDField()
|
||||
name = graphene.StringField()
|
||||
friends = graphene.ListField('self')
|
||||
friends = graphene.ListField('Character')
|
||||
appearsIn = graphene.ListField(Episode)
|
||||
|
||||
def resolve_friends(self, args, *_):
|
||||
|
|
61
tests/starwars_relay/schema.py
Normal file
61
tests/starwars_relay/schema.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
import graphene
|
||||
from graphene import resolve_only_args
|
||||
|
||||
from .data import getHero, getHuman, getCharacter, getDroid, Human as _Human, Droid as _Droid
|
||||
|
||||
Episode = graphene.Enum('Episode', dict(
|
||||
NEWHOPE = 4,
|
||||
EMPIRE = 5,
|
||||
JEDI = 6
|
||||
))
|
||||
|
||||
def wrap_character(character):
|
||||
if isinstance(character, _Human):
|
||||
return Human(character)
|
||||
elif isinstance(character, _Droid):
|
||||
return Droid(character)
|
||||
|
||||
class Character(graphene.Interface):
|
||||
id = graphene.IDField()
|
||||
name = graphene.StringField()
|
||||
friends = graphene.ListField('self')
|
||||
appearsIn = graphene.ListField(Episode)
|
||||
|
||||
def resolve_friends(self, args, *_):
|
||||
return [wrap_character(getCharacter(f)) for f in self.instance.friends]
|
||||
|
||||
class Human(Character):
|
||||
homePlanet = graphene.StringField()
|
||||
|
||||
|
||||
class Droid(Character):
|
||||
primaryFunction = graphene.StringField()
|
||||
|
||||
|
||||
class Query(graphene.ObjectType):
|
||||
hero = graphene.Field(Character,
|
||||
episode = graphene.Argument(Episode)
|
||||
)
|
||||
human = graphene.Field(Human,
|
||||
id = graphene.Argument(graphene.String)
|
||||
)
|
||||
droid = graphene.Field(Droid,
|
||||
id = graphene.Argument(graphene.String)
|
||||
)
|
||||
|
||||
@resolve_only_args
|
||||
def resolve_hero(self, episode):
|
||||
return wrap_character(getHero(episode))
|
||||
|
||||
@resolve_only_args
|
||||
def resolve_human(self, id):
|
||||
return wrap_character(getHuman(id))
|
||||
if human:
|
||||
return Human(human)
|
||||
|
||||
@resolve_only_args
|
||||
def resolve_droid(self, id):
|
||||
return wrap_character(getDroid(id))
|
||||
|
||||
|
||||
Schema = graphene.Schema(query=Query)
|
Loading…
Reference in New Issue
Block a user