diff --git a/graphene/contrib/django/debug/tests/test_query.py b/graphene/contrib/django/debug/tests/test_query.py index b6fdb8ec..50976ad5 100644 --- a/graphene/contrib/django/debug/tests/test_query.py +++ b/graphene/contrib/django/debug/tests/test_query.py @@ -8,6 +8,7 @@ from ...tests.models import Reporter from ..middleware import DjangoDebugMiddleware from ..types import DjangoDebug + class context(object): pass @@ -56,7 +57,7 @@ def test_should_query_field(): }] } } - schema = graphene.Schema(query=Query, plugins=[DjangoDebugMiddleware()]) + schema = graphene.Schema(query=Query, middlewares=[DjangoDebugMiddleware()]) result = schema.execute(query, context_value=context()) assert not result.errors assert result.data == expected @@ -104,7 +105,7 @@ def test_should_query_list(): }] } } - schema = graphene.Schema(query=Query, plugins=[DjangoDebugMiddleware()]) + schema = graphene.Schema(query=Query, middlewares=[DjangoDebugMiddleware()]) result = schema.execute(query, context_value=context()) assert not result.errors assert result.data == expected @@ -153,7 +154,7 @@ def test_should_query_connection(): }] }, } - schema = graphene.Schema(query=Query, plugins=[DjangoDebugMiddleware()]) + schema = graphene.Schema(query=Query, middlewares=[DjangoDebugMiddleware()]) result = schema.execute(query, context_value=context()) assert not result.errors assert result.data['allReporters'] == expected['allReporters'] @@ -209,7 +210,7 @@ def test_should_query_connectionfilter(): }] }, } - schema = graphene.Schema(query=Query, plugins=[DjangoDebugMiddleware()]) + schema = graphene.Schema(query=Query, middlewares=[DjangoDebugMiddleware()]) result = schema.execute(query, context_value=context()) assert not result.errors assert result.data['allReporters'] == expected['allReporters'] diff --git a/graphene/core/schema.py b/graphene/core/schema.py index 86b623ba..71fdd742 100644 --- a/graphene/core/schema.py +++ b/graphene/core/schema.py @@ -7,8 +7,7 @@ from graphql.utils.schema_printer import print_schema from graphene import signals -from ..plugins import CamelCase, PluginManager -from ..utils import promise_middleware +from ..middlewares import MiddlewareManager, CamelCaseArgsMiddleware from .classtypes.base import ClassType from .types.base import InstanceType @@ -24,7 +23,7 @@ class Schema(object): _executor = None def __init__(self, query=None, mutation=None, subscription=None, - name='Schema', executor=None, plugins=None, auto_camelcase=True, **options): + name='Schema', executor=None, middlewares=None, auto_camelcase=True, **options): self._types_names = {} self._types = {} self.mutation = mutation @@ -32,11 +31,13 @@ class Schema(object): self.subscription = subscription self.name = name self.executor = executor - plugins = plugins or [] + if 'plugins' in options: + raise Exception('Plugins are deprecated, please use middlewares.') + middlewares = middlewares or [] if auto_camelcase: - plugins.append(CamelCase()) + middlewares.append(CamelCaseArgsMiddleware()) self.auto_camelcase = auto_camelcase - self.plugins = PluginManager(self, plugins) + self.middleware_manager = MiddlewareManager(self, middlewares) self.options = options signals.init_schema.send(self) @@ -109,8 +110,7 @@ class Schema(object): return self._types_names[type_name] def resolver_with_middleware(self, resolver): - plugins_resolve = self.plugins.get_plugin_functions('resolve') - return promise_middleware(resolver, plugins_resolve) + return self.middleware_manager.wrap(resolver) @property def types(self): diff --git a/graphene/core/tests/test_schema.py b/graphene/core/tests/test_schema.py index a7e4c2e1..8a182515 100644 --- a/graphene/core/tests/test_schema.py +++ b/graphene/core/tests/test_schema.py @@ -154,6 +154,12 @@ def test_lazytype(): assert schema.T(t) == schema.T(MyType) +def test_deprecated_plugins_throws_exception(): + with raises(Exception) as excinfo: + Schema(plugins=[]) + assert 'Plugins are deprecated, please use middlewares' in str(excinfo.value) + + def test_schema_str(): expected = """ schema { diff --git a/graphene/middlewares/__init__.py b/graphene/middlewares/__init__.py new file mode 100644 index 00000000..4cee0bcc --- /dev/null +++ b/graphene/middlewares/__init__.py @@ -0,0 +1,6 @@ +from .base import MiddlewareManager +from .camel_case import CamelCaseArgsMiddleware + +__all__ = [ + 'MiddlewareManager', 'CamelCaseArgsMiddleware' +] diff --git a/graphene/middlewares/base.py b/graphene/middlewares/base.py new file mode 100644 index 00000000..33a26ac5 --- /dev/null +++ b/graphene/middlewares/base.py @@ -0,0 +1,23 @@ +from ..utils import promise_middleware + +MIDDLEWARE_RESOLVER_FUNCTION = 'resolve' + + +class MiddlewareManager(object): + + def __init__(self, schema, middlewares=None): + self.schema = schema + self.middlewares = middlewares or [] + + def add_middleware(self, middleware): + self.middlewares.append(middleware) + + def get_middleware_resolvers(self): + for middleware in self.middlewares: + if not hasattr(middleware, MIDDLEWARE_RESOLVER_FUNCTION): + continue + yield getattr(middleware, MIDDLEWARE_RESOLVER_FUNCTION) + + def wrap(self, resolver): + middleware_resolvers = self.get_middleware_resolvers() + return promise_middleware(resolver, middleware_resolvers) diff --git a/graphene/middlewares/camel_case.py b/graphene/middlewares/camel_case.py new file mode 100644 index 00000000..b5266f02 --- /dev/null +++ b/graphene/middlewares/camel_case.py @@ -0,0 +1,8 @@ +from ..utils import ProxySnakeDict + + +class CamelCaseArgsMiddleware(object): + + def resolve(self, next, root, args, context, info): + args = ProxySnakeDict(args) + return next(root, args, context, info) diff --git a/graphene/plugins/__init__.py b/graphene/plugins/__init__.py deleted file mode 100644 index 160bffba..00000000 --- a/graphene/plugins/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from .base import Plugin, PluginManager -from .camel_case import CamelCase - -__all__ = [ - 'Plugin', 'PluginManager', 'CamelCase' -] diff --git a/graphene/plugins/base.py b/graphene/plugins/base.py deleted file mode 100644 index 2347beba..00000000 --- a/graphene/plugins/base.py +++ /dev/null @@ -1,53 +0,0 @@ -from contextlib import contextmanager -from functools import partial, reduce - - -class Plugin(object): - - def contribute_to_schema(self, schema): - self.schema = schema - - -def apply_function(a, b): - return b(a) - - -class PluginManager(object): - - PLUGIN_FUNCTIONS = ('get_default_namedtype_name', ) - - def __init__(self, schema, plugins=[]): - self.schema = schema - self.plugins = [] - for plugin in plugins: - self.add_plugin(plugin) - - def add_plugin(self, plugin): - if hasattr(plugin, 'contribute_to_schema'): - plugin.contribute_to_schema(self.schema) - self.plugins.append(plugin) - - def get_plugin_functions(self, function): - for plugin in self.plugins: - if not hasattr(plugin, function): - continue - yield getattr(plugin, function) - - def __getattr__(self, name): - functions = self.get_plugin_functions(name) - return partial(reduce, apply_function, functions) - - def __contains__(self, name): - return name in self.PLUGIN_FUNCTIONS - - @contextmanager - def context_execution(self, **executor): - contexts = [] - functions = self.get_plugin_functions('context_execution') - for f in functions: - context = f(executor) - executor = context.__enter__() - contexts.append((context, executor)) - yield executor - for context, value in contexts[::-1]: - context.__exit__(None, None, None) diff --git a/graphene/plugins/camel_case.py b/graphene/plugins/camel_case.py deleted file mode 100644 index 1f1c6690..00000000 --- a/graphene/plugins/camel_case.py +++ /dev/null @@ -1,11 +0,0 @@ -from ..utils import to_camel_case, ProxySnakeDict - - -class CamelCase(object): - - def get_default_namedtype_name(self, value): - return to_camel_case(value) - - def resolve(self, next, root, args, context, info): - args = ProxySnakeDict(args) - return next(root, args, context, info)