Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for yield from graphql_async(schema, query) #254

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions graphql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from graphql import parse
from graphql.language.base import parse
"""
import sys

from .pyutils.version import get_version

# The primary entry point into fulfilling a GraphQL request.
Expand Down Expand Up @@ -168,13 +170,22 @@
set_default_backend,
)

if sys.version_info > (3, 3):
from .graphql_async import graphql_async
else:

def graphql_async(*args, **kwargs):
raise ImportError("graphql_async needs python>=3.4")


VERSION = (2, 2, 1, "final", 0)
__version__ = get_version(VERSION)


__all__ = (
"__version__",
"graphql",
"graphql_async",
"GraphQLBoolean",
"GraphQLEnumType",
"GraphQLEnumValue",
Expand Down
27 changes: 27 additions & 0 deletions graphql/backend/async_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import asyncio

from .utils import validate_document_ast
from ..execution import execute_async

# Necessary for static type checking
if False: # flake8: noqa
from typing import Any, Union
from ..execution import ExecutionResult
from ..language.ast import Document
from ..type.schema import GraphQLSchema
from rx import Observable


@asyncio.coroutine
def execute_and_validate_async(
schema, # type: GraphQLSchema
document_ast, # type: Document
*args, # type: Any
**kwargs # type: Any
):
# type: (...) -> Union[ExecutionResult, Observable]
execution_result = validate_document_ast(schema, document_ast, **kwargs)
if execution_result:
return execution_result
result = yield from execute_async(schema, document_ast, *args, **kwargs)
return result
6 changes: 6 additions & 0 deletions graphql/backend/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ def document_from_string(self, schema, request_string):
"document_from_string method not implemented in {}.".format(self.__class__)
)

@abstractmethod
def document_from_string_async(self, schema, request_string):
raise NotImplementedError(
"document_from_string method not implemented in {}.".format(self.__class__)
)


class GraphQLDocument(object):
def __init__(self, schema, document_string, document_ast, execute):
Expand Down
5 changes: 5 additions & 0 deletions graphql/backend/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,8 @@ def document_from_string(self, schema, request_string):
)

return self.cache_map[key]

def document_from_string_async(self, schema, request_string):
raise NotImplementedError(
"document_from_string method not implemented in {}.".format(self.__class__)
)
44 changes: 35 additions & 9 deletions graphql/backend/core.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import sys
from functools import partial
from six import string_types

from .utils import validate_document_ast
from ..execution import execute, ExecutionResult
from ..language.base import parse, print_ast
from ..language import ast
from ..validation import validate


from .base import GraphQLBackend, GraphQLDocument

if sys.version_info > (3, 3):
from .async_util import execute_and_validate_async
else:

def execute_and_validate_async(*args, **kwargs):
raise ImportError("execute_and_validate_async needs python>=3.4")


# Necessary for static type checking
if False: # flake8: noqa
from typing import Any, Optional, Union
from typing import Any, Optional, Union, Tuple
from ..language.ast import Document
from ..type.schema import GraphQLSchema
from rx import Observable
Expand All @@ -23,11 +33,9 @@ def execute_and_validate(
**kwargs # type: Any
):
# type: (...) -> Union[ExecutionResult, Observable]
do_validation = kwargs.get("validate", True)
if do_validation:
validation_errors = validate(schema, document_ast)
if validation_errors:
return ExecutionResult(errors=validation_errors, invalid=True)
execution_result = validate_document_ast(schema, document_ast, **kwargs)
if execution_result:
return execution_result

return execute(schema, document_ast, *args, **kwargs)

Expand All @@ -40,8 +48,9 @@ def __init__(self, executor=None):
# type: (Optional[Any]) -> None
self.execute_params = {"executor": executor}

def document_from_string(self, schema, document_string):
# type: (GraphQLSchema, Union[Document, str]) -> GraphQLDocument
@staticmethod
def _get_doc_str_and_ast(document_string):
# type: (Union[ast.Document, str]) -> Tuple[str, ast.Document]
if isinstance(document_string, ast.Document):
document_ast = document_string
document_string = print_ast(document_ast)
Expand All @@ -50,6 +59,11 @@ def document_from_string(self, schema, document_string):
document_string, string_types
), "The query must be a string"
document_ast = parse(document_string)
return document_string, document_ast

def document_from_string(self, schema, document_string):
# type: (GraphQLSchema, Union[ast.Document, str]) -> GraphQLDocument
document_string, document_ast = self._get_doc_str_and_ast(document_string)
return GraphQLDocument(
schema=schema,
document_string=document_string,
Expand All @@ -58,3 +72,15 @@ def document_from_string(self, schema, document_string):
execute_and_validate, schema, document_ast, **self.execute_params
),
)

def document_from_string_async(self, schema, document_string):
# type: (GraphQLSchema, Union[ast.Document, str]) -> GraphQLDocument
document_string, document_ast = self._get_doc_str_and_ast(document_string)
return GraphQLDocument(
schema=schema,
document_string=document_string,
document_ast=document_ast,
execute=partial(
execute_and_validate_async, schema, document_ast, **self.execute_params
),
)
5 changes: 5 additions & 0 deletions graphql/backend/decider.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,8 @@ def document_from_string(self, schema, request_string):
self.get_worker().queue(self.queue_backend, key, schema, request_string)

return self.cache_map[key]

def document_from_string_async(self, schema, request_string):
raise NotImplementedError(
"document_from_string method not implemented in {}.".format(self.__class__)
)
5 changes: 5 additions & 0 deletions graphql/backend/quiver_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,8 @@ def uptodate():
schema, code, uptodate, self.extra_namespace
)
return document

def document_from_string_async(self, schema, request_string):
raise NotImplementedError(
"document_from_string method not implemented in {}.".format(self.__class__)
)
5 changes: 5 additions & 0 deletions graphql/backend/tests/test_decider.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ def document_from_string(self, *args, **kwargs):
raise Exception("Backend failed")
return self.name

def document_from_string_async(self, schema, request_string):
raise NotImplementedError(
"document_from_string method not implemented in {}.".format(self.__class__)
)

def wait(self):
return self.event.wait()

Expand Down
23 changes: 23 additions & 0 deletions graphql/backend/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from ..execution import ExecutionResult
from ..validation import validate


# Necessary for static type checking
if False: # flake8: noqa
from typing import Any, Union
from ..language.ast import Document
from ..type.schema import GraphQLSchema


def validate_document_ast(
schema, # type: GraphQLSchema
document_ast, # type: Document
**kwargs # type: Any
):
# type: (...) -> Union[ExecutionResult, None]
do_validation = kwargs.get("validate", True)
if do_validation:
validation_errors = validate(schema, document_ast)
if validation_errors:
return ExecutionResult(errors=validation_errors, invalid=True)
return None
10 changes: 10 additions & 0 deletions graphql/execution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,23 @@
2) fragment "spreads" e.g. "...c"
3) inline fragment "spreads" e.g. "...on Type { a }"
"""
import sys

from .executor import execute, subscribe
from .base import ExecutionResult, ResolveInfo
from .middleware import middlewares, MiddlewareManager

if sys.version_info > (3, 3):
from .executor_async import execute_async
else:

def execute_async(*args, **kwargs):
raise ImportError("execute_async needs python>=3.4")


__all__ = [
"execute",
"execute_async",
"subscribe",
"ExecutionResult",
"ResolveInfo",
Expand Down
Loading