From 25fd60d1ffed3e74f3494738aa3a3e693d4a0f4b Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Fri, 20 May 2016 00:16:34 -0700 Subject: [PATCH] Improved plugins --- graphene/contrib/django/debug/plugin.py | 30 ++++++++++------------ graphene/core/schema.py | 30 ++++++++++++++++++++++ graphene/core/types/argument.py | 10 -------- graphene/core/types/field.py | 9 +++---- graphene/core/types/tests/test_argument.py | 9 +------ graphene/plugins/camel_case.py | 5 +++- 6 files changed, 52 insertions(+), 41 deletions(-) diff --git a/graphene/contrib/django/debug/plugin.py b/graphene/contrib/django/debug/plugin.py index 2d930673..46030ef5 100644 --- a/graphene/contrib/django/debug/plugin.py +++ b/graphene/contrib/django/debug/plugin.py @@ -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() diff --git a/graphene/core/schema.py b/graphene/core/schema.py index 966e1fd2..b9e6f56d 100644 --- a/graphene/core/schema.py +++ b/graphene/core/schema.py @@ -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 diff --git a/graphene/core/types/argument.py b/graphene/core/types/argument.py index 80039ede..88a8c92f 100644 --- a/graphene/core/types/argument.py +++ b/graphene/core/types/argument.py @@ -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 diff --git a/graphene/core/types/field.py b/graphene/core/types/field.py index db17a465..837f505e 100644 --- a/graphene/core/types/field.py +++ b/graphene/core/types/field.py @@ -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,) diff --git a/graphene/core/types/tests/test_argument.py b/graphene/core/types/tests/test_argument.py index 4482c11c..bd9cda10 100644 --- a/graphene/core/types/tests/test_argument.py +++ b/graphene/core/types/tests/test_argument.py @@ -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 diff --git a/graphene/plugins/camel_case.py b/graphene/plugins/camel_case.py index d9a9084f..8b1c2bde 100644 --- a/graphene/plugins/camel_case.py +++ b/graphene/plugins/camel_case.py @@ -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)