mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-09 08:00:39 +03:00
Improved plugins
This commit is contained in:
parent
b431bfe477
commit
25fd60d1ff
|
@ -1,6 +1,7 @@
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from django.db import connections
|
from django.db import connections
|
||||||
|
from graphene import with_context
|
||||||
|
|
||||||
from ....core.schema import GraphQLSchema
|
from ....core.schema import GraphQLSchema
|
||||||
from ....core.types import Field
|
from ....core.types import Field
|
||||||
|
@ -10,11 +11,14 @@ from .sql.types import DjangoDebugSQL
|
||||||
from .types import DjangoDebug
|
from .types import DjangoDebug
|
||||||
|
|
||||||
|
|
||||||
class WrappedRoot(object):
|
class EmptyContext(object):
|
||||||
|
pass
|
||||||
|
|
||||||
def __init__(self, root):
|
|
||||||
|
class DjangoDebugContext(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
self._recorded = []
|
self._recorded = []
|
||||||
self._root = root
|
|
||||||
|
|
||||||
def record(self, **log):
|
def record(self, **log):
|
||||||
self._recorded.append(DjangoDebugSQL(**log))
|
self._recorded.append(DjangoDebugSQL(**log))
|
||||||
|
@ -24,17 +28,9 @@ class WrappedRoot(object):
|
||||||
|
|
||||||
|
|
||||||
class WrapRoot(object):
|
class WrapRoot(object):
|
||||||
|
@with_context
|
||||||
@property
|
def resolve_debug(self, args, context, info):
|
||||||
def _root(self):
|
return context.django_debug.debug()
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
def debug_objecttype(objecttype):
|
def debug_objecttype(objecttype):
|
||||||
|
@ -72,8 +68,10 @@ class DjangoDebugPlugin(Plugin):
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def context_execution(self, executor):
|
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'])
|
executor['schema'] = self.wrap_schema(executor['schema'])
|
||||||
self.enable_instrumentation(executor['root_value'])
|
self.enable_instrumentation(context_value.django_debug)
|
||||||
yield executor
|
yield executor
|
||||||
self.disable_instrumentation()
|
self.disable_instrumentation()
|
||||||
|
|
|
@ -12,6 +12,16 @@ from .classtypes.base import ClassType
|
||||||
from .types.base import InstanceType
|
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):
|
class GraphQLSchema(_GraphQLSchema):
|
||||||
|
|
||||||
def __init__(self, schema, *args, **kwargs):
|
def __init__(self, schema, *args, **kwargs):
|
||||||
|
@ -111,6 +121,26 @@ class Schema(object):
|
||||||
raise KeyError('Type %r not found in %r' % (type_name, self))
|
raise KeyError('Type %r not found in %r' % (type_name, self))
|
||||||
return self._types_names[type_name]
|
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
|
@property
|
||||||
def types(self):
|
def types(self):
|
||||||
return self._types_names
|
return self._types_names
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
from functools import wraps
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from graphql.type import GraphQLArgument
|
from graphql.type import GraphQLArgument
|
||||||
|
|
||||||
from ...utils import ProxySnakeDict
|
|
||||||
from .base import ArgumentType, GroupNamedType, NamedType, OrderedType
|
from .base import ArgumentType, GroupNamedType, NamedType, OrderedType
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,11 +51,3 @@ def to_arguments(*args, **kwargs):
|
||||||
arguments[name] = argument
|
arguments[name] = argument
|
||||||
|
|
||||||
return sorted(arguments.values())
|
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
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from functools import wraps
|
from functools import wraps, partial
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from graphql.type import GraphQLField, GraphQLInputObjectField
|
from graphql.type import GraphQLField, GraphQLInputObjectField
|
||||||
|
@ -10,7 +10,7 @@ from ..classtypes.base import FieldsClassType
|
||||||
from ..classtypes.inputobjecttype import InputObjectType
|
from ..classtypes.inputobjecttype import InputObjectType
|
||||||
from ..classtypes.mutation import Mutation
|
from ..classtypes.mutation import Mutation
|
||||||
from ..exceptions import SkipField
|
from ..exceptions import SkipField
|
||||||
from .argument import Argument, ArgumentsGroup, snake_case_args
|
from .argument import Argument, ArgumentsGroup
|
||||||
from .base import (ArgumentType, GroupNamedType, LazyType, MountType,
|
from .base import (ArgumentType, GroupNamedType, LazyType, MountType,
|
||||||
NamedType, OrderedType)
|
NamedType, OrderedType)
|
||||||
from .definitions import NonNull
|
from .definitions import NonNull
|
||||||
|
@ -89,9 +89,6 @@ class Field(NamedType, OrderedType):
|
||||||
return NonNull(self.type)
|
return NonNull(self.type)
|
||||||
return self.type
|
return self.type
|
||||||
|
|
||||||
def decorate_resolver(self, resolver):
|
|
||||||
return snake_case_args(resolver)
|
|
||||||
|
|
||||||
def internal_type(self, schema):
|
def internal_type(self, schema):
|
||||||
if not self.object_type:
|
if not self.object_type:
|
||||||
raise Exception('The field is not mounted in any ClassType')
|
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)
|
assert type, 'Internal type for field %s is None' % str(self)
|
||||||
return GraphQLField(type, args=schema.T(arguments),
|
return GraphQLField(type, args=schema.T(arguments),
|
||||||
resolver=self.decorate_resolver(resolver),
|
resolver=partial(schema.resolve, resolver),
|
||||||
deprecation_reason=self.deprecation_reason,
|
deprecation_reason=self.deprecation_reason,
|
||||||
description=description,)
|
description=description,)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from pytest import raises
|
||||||
from graphene.core.schema import Schema
|
from graphene.core.schema import Schema
|
||||||
from graphene.core.types import ObjectType
|
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
|
from ..scalars import String
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,10 +45,3 @@ def test_to_arguments_wrong_type():
|
||||||
p=3
|
p=3
|
||||||
)
|
)
|
||||||
assert 'Unknown argument p=3' == str(excinfo.value)
|
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
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
from ..utils import to_camel_case
|
from ..utils import to_camel_case, ProxySnakeDict
|
||||||
|
|
||||||
|
|
||||||
class CamelCase(object):
|
class CamelCase(object):
|
||||||
|
|
||||||
def get_default_namedtype_name(self, value):
|
def get_default_namedtype_name(self, value):
|
||||||
return to_camel_case(value)
|
return to_camel_case(value)
|
||||||
|
|
||||||
|
def process_aci(self, aci):
|
||||||
|
aci.args = ProxySnakeDict(aci.args)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user