Improved plugins

This commit is contained in:
Syrus Akbary 2016-05-20 00:16:34 -07:00
parent b431bfe477
commit 25fd60d1ff
6 changed files with 52 additions and 41 deletions

View File

@ -1,6 +1,7 @@
from contextlib import contextmanager
from django.db import connections
from graphene import with_context
from ....core.schema import GraphQLSchema
from ....core.types import Field
@ -10,11 +11,14 @@ from .sql.types import DjangoDebugSQL
from .types import DjangoDebug
class WrappedRoot(object):
class EmptyContext(object):
pass
def __init__(self, root):
class DjangoDebugContext(object):
def __init__(self):
self._recorded = []
self._root = root
def record(self, **log):
self._recorded.append(DjangoDebugSQL(**log))
@ -24,17 +28,9 @@ class WrappedRoot(object):
class WrapRoot(object):
@property
def _root(self):
return self._wrapped_root.root
@_root.setter
def _root(self, value):
self._wrapped_root = value
def resolve_debug(self, args, info):
return self._wrapped_root.debug()
@with_context
def resolve_debug(self, args, context, info):
return context.django_debug.debug()
def debug_objecttype(objecttype):
@ -72,8 +68,10 @@ class DjangoDebugPlugin(Plugin):
@contextmanager
def context_execution(self, executor):
executor['root_value'] = WrappedRoot(root=executor.get('root_value'))
context_value = executor.get('context_value') or EmptyContext()
context_value.django_debug = DjangoDebugContext()
executor['context_value'] = context_value
executor['schema'] = self.wrap_schema(executor['schema'])
self.enable_instrumentation(executor['root_value'])
self.enable_instrumentation(context_value.django_debug)
yield executor
self.disable_instrumentation()

View File

@ -12,6 +12,16 @@ from .classtypes.base import ClassType
from .types.base import InstanceType
class ACI(object):
def __init__(self, args, context, info):
self.args = args
self.context = context
self.info = info
def __repr__(self):
return "ACI(args={}, context={}, info={})".format(repr(self.args), repr(self.context), repr(self.info))
class GraphQLSchema(_GraphQLSchema):
def __init__(self, schema, *args, **kwargs):
@ -111,6 +121,26 @@ class Schema(object):
raise KeyError('Type %r not found in %r' % (type_name, self))
return self._types_names[type_name]
def resolve(self, resolver, root, args, context, info):
aci = ACI(args, context, info)
plugins_process_aci = self.plugins.get_plugin_functions('process_aci')
plugins_process_response = self.plugins.get_plugin_functions('process_response')
for process_aci in plugins_process_aci:
processed_aci = process_aci(aci)
if processed_aci is None:
continue
return processed_aci
response = resolver(root, aci.args, aci.context, aci.info)
for process_response in plugins_process_response:
processed_response = process_response(response, aci)
if processed_response is None:
continue
return processed_response
return response
@property
def types(self):
return self._types_names

View File

@ -1,9 +1,7 @@
from functools import wraps
from itertools import chain
from graphql.type import GraphQLArgument
from ...utils import ProxySnakeDict
from .base import ArgumentType, GroupNamedType, NamedType, OrderedType
@ -53,11 +51,3 @@ def to_arguments(*args, **kwargs):
arguments[name] = argument
return sorted(arguments.values())
def snake_case_args(resolver):
@wraps(resolver)
def wrapped_resolver(instance, args, context, info):
return resolver(instance, ProxySnakeDict(args), context, info)
return wrapped_resolver

View File

@ -1,5 +1,5 @@
from collections import OrderedDict
from functools import wraps
from functools import wraps, partial
import six
from graphql.type import GraphQLField, GraphQLInputObjectField
@ -10,7 +10,7 @@ from ..classtypes.base import FieldsClassType
from ..classtypes.inputobjecttype import InputObjectType
from ..classtypes.mutation import Mutation
from ..exceptions import SkipField
from .argument import Argument, ArgumentsGroup, snake_case_args
from .argument import Argument, ArgumentsGroup
from .base import (ArgumentType, GroupNamedType, LazyType, MountType,
NamedType, OrderedType)
from .definitions import NonNull
@ -89,9 +89,6 @@ class Field(NamedType, OrderedType):
return NonNull(self.type)
return self.type
def decorate_resolver(self, resolver):
return snake_case_args(resolver)
def internal_type(self, schema):
if not self.object_type:
raise Exception('The field is not mounted in any ClassType')
@ -119,7 +116,7 @@ class Field(NamedType, OrderedType):
assert type, 'Internal type for field %s is None' % str(self)
return GraphQLField(type, args=schema.T(arguments),
resolver=self.decorate_resolver(resolver),
resolver=partial(schema.resolve, resolver),
deprecation_reason=self.deprecation_reason,
description=description,)

View File

@ -4,7 +4,7 @@ from pytest import raises
from graphene.core.schema import Schema
from graphene.core.types import ObjectType
from ..argument import Argument, snake_case_args, to_arguments
from ..argument import Argument, to_arguments
from ..scalars import String
@ -45,10 +45,3 @@ def test_to_arguments_wrong_type():
p=3
)
assert 'Unknown argument p=3' == str(excinfo.value)
def test_snake_case_args():
def resolver(instance, args, context, info):
return args['my_arg']['inner_arg']
r = snake_case_args(resolver)
assert r(None, {'myArg': {'innerArg': 3}}, None, None) == 3

View File

@ -1,7 +1,10 @@
from ..utils import to_camel_case
from ..utils import to_camel_case, ProxySnakeDict
class CamelCase(object):
def get_default_namedtype_name(self, value):
return to_camel_case(value)
def process_aci(self, aci):
aci.args = ProxySnakeDict(aci.args)