Ejemplo n.º 1
0
    async def call(
        self,
        document: GraphQLSchema,
        request: typing.Any = None,
        variables: typing.Dict[str, typing.Any] = None
    ) -> ExecutionResult:
        """Preform a query against the schema.

        This is meant to be called in an asyncio.loop, if you are using a
        web framework that is synchronous use the `call_sync` method.
        """
        validation_errors = validate(self.schema, document)
        if validation_errors:
            return ExecutionResult(data=None, errors=validation_errors)

        context = self.get_context(request)
        result = execute(
            schema=self.schema,
            document=document,
            context_value=context,
            variable_values=variables,
            middleware=self.middleware,
        )
        if inspect.isawaitable(result):
            return await result
        return result
Ejemplo n.º 2
0
 def execute(self,
             root=None,
             context=None,
             middleware=None,
             operation_name=None,
             variables=None,
             allowed_operations=None):
     if self.errors:
         return ExecutionResult(errors=self.errors, invalid=True)
     try:
         if allowed_operations is not None:
             operation_type = get_operation_from_operation_name(
                 self.document_ast, operation_name)
             if operation_type and operation_type not in allowed_operations:
                 raise GraphQLError("{} operations are not allowed.".format(
                     operation_type))
         return execute(self.schema,
                        self.document_ast,
                        root_value=root,
                        middleware=middleware,
                        context_value=context,
                        variable_values=variables or {},
                        operation_name=operation_name,
                        **self.execute_params)
     except Exception as e:
         return ExecutionResult(errors=[e])
Ejemplo n.º 3
0
def from_file(
    file: Union[IO[str], str],
    *,
    app: Any = None,
    base_url: Optional[str] = None,
    data_generation_methods: DataGenerationMethodInput = DEFAULT_DATA_GENERATION_METHODS,
    code_sample_style: str = CodeSampleStyle.default().name,
    location: Optional[str] = None,
) -> GraphQLSchema:
    """Load GraphQL schema from a file descriptor or a string.

    :param file: Could be a file descriptor, string or bytes.
    """
    if isinstance(file, str):
        data = file
    else:
        data = file.read()
    document = graphql.build_schema(data)
    result = graphql.execute(document, INTROSPECTION_QUERY_AST)
    # TYPES: We don't pass `is_awaitable` above, therefore `result` is of the `ExecutionResult` type
    result = cast(ExecutionResult, result)
    # TYPES:
    #  - `document` is a valid schema, because otherwise `build_schema` will rise an error;
    #  - `INTROSPECTION_QUERY` is a valid query - it is known upfront;
    # Therefore the execution result is always valid at this point and `result.data` is not `None`
    raw_schema = cast(Dict[str, Any], result.data)
    return from_dict(
        raw_schema,
        app=app,
        base_url=base_url,
        data_generation_methods=data_generation_methods,
        code_sample_style=code_sample_style,
        location=location,
    )
Ejemplo n.º 4
0
    def query(self, q):
        try:
            source = Source(q, name='GraphQL request')
            ast = parse(source)
            validation_errors = validate(self.schema, ast)
            if validation_errors:
                return ExecutionResult(
                    errors=validation_errors,
                    invalid=True,
                )
        except Exception as e:
            return ExecutionResult(errors=[e], invalid=True)

        try:
            return execute(self.__schema,
                           ast,
                           root_value=None,
                           variable_values={},
                           operation_name=None,
                           context_value={
                               'query': q,
                               'introspection': 'introspection' in q.lower()
                           },
                           middleware=self.__middleware,
                           executor=self.__executor)
        except Exception as e:
            return ExecutionResult(errors=[e], invalid=True)
Ejemplo n.º 5
0
 def context_do_execute_handler(result):
     context, do_execute = result
     if not do_execute:
         return
     else:
         return execute(self.schema, parsed_query, root_value,
                        context, variables, operation_name)
Ejemplo n.º 6
0
 def _graphql(
     self,
     schema: GraphQLSchema,
     document: DocumentNode,
     root_value: Any = None,
     context_value: Any = None,
     variable_values: Dict[str, Any] = None,  # type: ignore
     operation_name: str = None,  # type: ignore
     field_resolver: GraphQLFieldResolver = None,  # type: ignore
     type_resolver: GraphQLTypeResolver = None,  # type: ignore
     middleware: Middleware = None,
     execution_context_class: Type[ExecutionContext] = ExecutionContext,
 ) -> AwaitableOrValue[ExecutionResult]:
     # Execute
     return execute(
         schema,
         document,
         root_value,
         context_value,
         variable_values,
         operation_name,
         field_resolver,
         type_resolver,
         middleware,
         execution_context_class,
     )
 async def test_uuid_scalar_input_as_query_string_validates(self):
     query = """
         query {
             uuid_input(uuid: "hello")
         }
         """
     result = graphql.execute(schema, graphql.parse(query))
     assert "invalid value" in str(result.errors)
 async def test_datetime_scalar_input_as_query_string(self):
     query = """
         query {
             datetime_input(dt: "2018-01-01T01:00:00-05:00")
         }
         """
     result = graphql.execute(schema, graphql.parse(query))
     assert result.data["datetime_input"] == 2018
Ejemplo n.º 9
0
def test_batches_correctly(executor):

    Business = GraphQLObjectType(
        'Business', lambda: {
            'id':
            GraphQLField(GraphQLID, resolver=lambda root, info, **args: root),
        })

    Query = GraphQLObjectType(
        'Query', lambda: {
            'getBusiness':
            GraphQLField(Business,
                         args={
                             'id': GraphQLArgument(GraphQLNonNull(GraphQLID)),
                         },
                         resolver=lambda root, info, **args: info.context.
                         business_data_loader.load(args.get('id'))),
        })

    schema = GraphQLSchema(query=Query)

    doc = '''
{
    business1: getBusiness(id: "1") {
        id
    }
    business2: getBusiness(id: "2") {
        id
    }
}
    '''
    doc_ast = parse(doc)

    load_calls = []

    class BusinessDataLoader(DataLoader):
        def batch_load_fn(self, keys):
            load_calls.append(keys)
            return Promise.resolve(keys)

    class Context(object):
        business_data_loader = BusinessDataLoader()

    result = execute(schema,
                     doc_ast,
                     None,
                     context_value=Context(),
                     executor=executor)
    assert not result.errors
    assert result.data == {
        'business1': {
            'id': '1'
        },
        'business2': {
            'id': '2'
        },
    }
    assert load_calls == [['1', '2']]
Ejemplo n.º 10
0
def test_batches_correctly(executor):
    # type: (SyncExecutor) -> None

    Business = GraphQLObjectType(
        "Business",
        lambda: {
            "id": GraphQLField(GraphQLID,
                               resolver=lambda root, info, **args: root)
        },
    )

    Query = GraphQLObjectType(
        "Query",
        lambda: {
            "getBusiness":
            GraphQLField(
                Business,
                args={"id": GraphQLArgument(GraphQLNonNull(GraphQLID))},
                resolver=lambda root, info, **args: info.context.
                business_data_loader.load(args.get("id")),
            )
        },
    )

    schema = GraphQLSchema(query=Query)

    doc = """
{
    business1: getBusiness(id: "1") {
        id
    }
    business2: getBusiness(id: "2") {
        id
    }
}
    """
    doc_ast = parse(doc)

    load_calls = []

    class BusinessDataLoader(DataLoader):
        def batch_load_fn(self, keys):
            # type: (List[str]) -> Promise
            load_calls.append(keys)
            return Promise.resolve(keys)

    class Context(object):
        business_data_loader = BusinessDataLoader()

    result = execute(schema,
                     doc_ast,
                     None,
                     context_value=Context(),
                     executor=executor)
    assert not result.errors
    assert result.data == {"business1": {"id": "1"}, "business2": {"id": "2"}}
    assert load_calls == [["1", "2"]]
 async def test_uuid_scalar_input_as_query_string(self):
     query = """
         query {
             uuid_input(uuid: "8c9c95c5-30b8-467b-8acb-384c86dc3ab8")
         }
         """
     result = graphql.execute(schema, graphql.parse(query))
     assert result.data[
         "uuid_input"] == "8c9c95c5-30b8-467b-8acb-384c86dc3ab8"
Ejemplo n.º 12
0
 async def execute(self, *args, **kwargs):
     result = execute(self.schema,
                      return_promise=self._enable_async,
                      *args,
                      **kwargs)
     if isinstance(result, Promise):
         return await result
     else:
         return result
 async def test_json_scalar_input_as_variable(self):
     query = r"""
         query($j: JSON) {
             json_input(json: $j)
         }
         """
     result = graphql.execute(schema,
                              graphql.parse(query),
                              variable_values=dict(j={"x": 1}))
     assert result.data["json_input"] == 1
def test_unicode_error_message():
    ast = parse("query Example { unicode }")

    def resolver(context, *_):
        raise Exception(u"UNIÇODÉ!")

    Type = GraphQLObjectType("Type", {"unicode": GraphQLField(GraphQLString, resolver=resolver)})

    result = execute(GraphQLSchema(Type), ast)
    assert isinstance(result.errors[0], GraphQLLocatedError)
 async def test_uuid_scalar_input_as_variable_validates(self):
     query = """
         query($uuid: UUID) {
             uuid_input(uuid: $uuid)
         }
         """
     result = graphql.execute(schema,
                              graphql.parse(query),
                              variable_values=dict(uuid="hello"))
     assert "invalid value" in str(result.errors)
Ejemplo n.º 16
0
def test_page(session, schema, page, expected_count, result_length):
    document = parse(query_pagination)

    car2 = Car(name="Car 2")
    car3 = Car(name="Car 3")
    session.add(car2)
    session.add(car3)
    session.commit()

    result = execute(schema, document, context_value=session, variable_values=page)
    assert len(result.data["cars"]["result"]) == result_length
    assert result.data["cars"]["count"] == expected_count
Ejemplo n.º 17
0
def test_batches_correctly(executor):

    Business = GraphQLObjectType('Business', lambda: {
        'id': GraphQLField(GraphQLID, resolver=lambda root, info, **args: root),
    })

    Query = GraphQLObjectType('Query', lambda: {
        'getBusiness': GraphQLField(Business,
            args={
                'id': GraphQLArgument(GraphQLNonNull(GraphQLID)),
            },
            resolver=lambda root, info, **args: info.context.business_data_loader.load(args.get('id'))
        ),
    })

    schema = GraphQLSchema(query=Query)


    doc = '''
{
    business1: getBusiness(id: "1") {
        id
    }
    business2: getBusiness(id: "2") {
        id
    }
}
    '''
    doc_ast = parse(doc)


    load_calls = []
    
    class BusinessDataLoader(DataLoader):
        def batch_load_fn(self, keys):
            load_calls.append(keys)
            return Promise.resolve(keys)

    class Context(object):
        business_data_loader = BusinessDataLoader()


    result = execute(schema, doc_ast, None, context_value=Context(), executor=executor)
    assert not result.errors
    assert result.data == {
        'business1': {
            'id': '1'
        },
        'business2': {
            'id': '2'
        },
    }
    assert load_calls == [['1','2']]
 async def test_json_scalar_input_as_query_string(self):
     """
     Won't work unless the literal JSON string is parsed as JSON and passed to the resolver,
     so it can be indexed
     """
     query = r"""
         query {
             json_input(json: "{\"x\": 1}")
         }
         """
     result = graphql.execute(schema, graphql.parse(query))
     assert result.data["json_input"] == 1
 async def test_uuid_scalar_input_as_variable(self):
     query = """
         query($uuid: UUID) {
             uuid_input(uuid: $uuid)
         }
         """
     result = graphql.execute(
         schema,
         graphql.parse(query),
         variable_values=dict(uuid="8c9c95c5-30b8-467b-8acb-384c86dc3ab8"),
     )
     assert result.data[
         "uuid_input"] == "8c9c95c5-30b8-467b-8acb-384c86dc3ab8"
Ejemplo n.º 20
0
def test_unicode_error_message():
    # type: () -> None
    ast = parse("query Example { unicode }")

    def resolver(context, *_):
        # type: (Optional[Any], *ResolveInfo) -> NoReturn
        raise Exception(u"UNIÇODÉ!")

    Type = GraphQLObjectType(
        "Type", {"unicode": GraphQLField(GraphQLString, resolver=resolver)})

    result = execute(GraphQLSchema(Type), ast)
    assert isinstance(result.errors[0], GraphQLLocatedError)
Ejemplo n.º 21
0
    def execute(self, *args, **kwargs):
        operation_ast = get_operation_ast(args[0])

        if operation_ast and operation_ast.operation == "subscription":
            result = subscribe(self.schema, *args, **kwargs)
            if isinstance(result, Observable):
                a = []
                result.subscribe(lambda x: a.append(x))
                if len(a) > 0:
                    result = a[-1]
            return result

        return execute(self.schema, *args, **kwargs)
Ejemplo n.º 22
0
def test_unicode_error_message():
    ast = parse('query Example { unicode }')

    def resolver(context, *_):
        raise Exception(u'UNIÇODÉ!')

    Type = GraphQLObjectType(
        'Type', {
            'unicode': GraphQLField(GraphQLString, resolver=resolver),
        })

    result = execute(GraphQLSchema(Type), ast)
    assert isinstance(result.errors[0], GraphQLLocatedError)
 async def test_datetime_scalar_input_as_variable(self):
     query = r"""
         query($dt: DateTime) {
             datetime_input(dt: $dt)
         }
         """
     result = graphql.execute(
         schema,
         graphql.parse(query),
         variable_values=dict(
             dt=pendulum.datetime(2018, 1, 1, 1, tz="EST").isoformat()),
     )
     assert result.data["datetime_input"] == 2018
Ejemplo n.º 24
0
    def test_multiple_one_shot_middleware():
        runs = []

        class OneShotMiddleware:
            @run_only_once
            def resolve(self, next_, *args, **kwargs):
                runs.append("OneShotMiddleware")
                return next_(*args, **kwargs)

        class AnotherOneShotMiddleware:
            @run_only_once
            def resolve(self, next_, *args, **kwargs):
                runs.append("AnotherOneShotMiddleware")
                return next_(*args, **kwargs)

        middleware = (OneShotMiddleware(), AnotherOneShotMiddleware())
        execute(schema=schema,
                document=parse(query),
                middleware=middleware,
                context_value={})
        assert len(runs) == 2, "both middleware should have run"
        assert "OneShotMiddleware" in runs
        assert "AnotherOneShotMiddleware" in runs
Ejemplo n.º 25
0
    async def _handle_query_over_ws(
        self,
        websocket,
        operation_id,
        subscriptions,
        document,
        context_value,
        variable_values,
        operation_name,
    ) -> List[GraphQLError]:
        result = execute(
            self.schema.graphql_schema,
            document,
            root_value=self.root_value,
            context_value=context_value,
            variable_values=variable_values,
            operation_name=operation_name,
            middleware=self.middleware,
            execution_context_class=self.execution_context_class,
        )

        if isinstance(result, ExecutionResult) and result.errors:
            return result.errors

        if isawaitable(result):
            result = await cast(Awaitable[ExecutionResult], result)

        result = cast(ExecutionResult, result)

        payload: Dict[str, Any] = {}
        payload["data"] = result.data
        if result.errors:
            for error in result.errors:
                if error.original_error:
                    self.logger.error(
                        "An exception occurred in resolvers",
                        exc_info=error.original_error,
                    )
            payload["errors"] = [
                self.error_formatter(error) for error in result.errors
            ]

        await websocket.send_json({
            "type": GQL_DATA,
            "id": operation_id,
            "payload": payload
        })
        return []
Ejemplo n.º 26
0
def generate_schema_hash(schema: GraphQLSchema) -> str:
    """
    Generates a stable hash of the current schema using an introspection query.
    """
    ast = parse(introspection_query)
    result = cast(ExecutionResult, execute(schema, ast))

    if result and not result.data:
        raise GraphQLError("Unable to generate server introspection document")

    schema = result.data["__schema"]
    # It's important that we perform a deterministic stringification here
    # since, depending on changes in the underlying `graphql-core` execution
    # layer, varying orders of the properties in the introspection
    stringified_schema = stringify(schema).encode("utf-8")
    return hashlib.sha512(stringified_schema).hexdigest()
Ejemplo n.º 27
0
    def test_run_only_once():
        class OneShotMiddleware:
            @run_only_once
            def resolve(self, next_, *args, **kwargs):
                runs.append("OneShotMiddleware")
                return next_(*args, **kwargs)

        runs = []
        middleware = (OneShotMiddleware(), )

        result = execute(schema=schema,
                         document=parse(query),
                         middleware=middleware,
                         context_value={})
        assert_no_errors(result)
        assert len(runs) == 1, "middleware should run only once"
async def test_custom_scalar_inline():
    # https://github.com/PrefectHQ/cloud/issues/2414
    query = r"""
        mutation($j: JSON!) {
            hello_mutation(input: {u: "51608cdf-c46c-4d02-a4e7-66ddd678243c", j: $j})
        }
        """
    result = graphql.execute(schema,
                             graphql.parse(query),
                             variable_values=dict(j={"x": 1}))
    assert result.data["hello_mutation"] == {
        "u": "51608cdf-c46c-4d02-a4e7-66ddd678243c",
        "j": {
            "x": 1
        },
    }
Ejemplo n.º 29
0
    def test_middleware_with_wsgi_request_context_values():
        runs = []

        class OneShotMiddleware:
            @run_only_once
            def resolve(self, next_, *args, **kwargs):
                runs.append("OneShotMiddleware")
                return next_(*args, **kwargs)

        middleware = (OneShotMiddleware(), )
        [
            execute(schema=schema,
                    document=parse(query),
                    middleware=middleware,
                    context_value=_get_fake_wsgi_request_obj()) for _ in (0, 1)
        ]
        assert len(runs) == 2, "middleware should run twice for 2 requests"
Ejemplo n.º 30
0
def execute_graphql(source, variables, operation_name=None):
    schema = build_schema(request.env)
    try:
        document_ast = parse(source)
        validation_errors = validate(schema, document_ast)
        if validation_errors:
            return ExecutionResult(
                errors=validation_errors,
                invalid=True,
            )
    except Exception as e:
        return ExecutionResult(errors=[e], invalid=True)
    
    return execute(
        document_ast,
        variable_values=variables,
        operation_name=operation_name,
        context_value=request
    )
Ejemplo n.º 31
0
def execute_graphql_request(
    schema: GraphQLSchema,
    params: GraphQLParams,
    allow_only_query: bool = False,
    **kwargs,
):
    if not params.query:
        raise HttpQueryError(400, "Must provide query string.")

    try:
        document = parse(params.query)
    except GraphQLError as e:
        return ExecutionResult(data=None, errors=[e])
    except Exception as e:
        e = GraphQLError(str(e), original_error=e)
        return ExecutionResult(data=None, errors=[e])

    if allow_only_query:
        operation_ast = get_operation_ast(document, params.operation_name)
        if operation_ast:
            operation = operation_ast.operation.value
            if operation != "query":
                raise HttpQueryError(
                    405,
                    f"Can only perform a {operation} operation from a POST request.",
                    headers={"Allow": "POST"},
                )

    # Note: the schema is not validated here for performance reasons.
    # This should be done only once when starting the server.

    validation_errors = validate(schema, document)
    if validation_errors:
        return ExecutionResult(data=None, errors=validation_errors)

    return execute(
        schema,
        document,
        variable_values=params.variables,
        operation_name=params.operation_name,
        **kwargs,
    )
    async def _handle_query_via_ws(
        self,
        websocket,
        operation_id,
        subscriptions,
        document,
        context_value,
        variable_values,
        operation_name,
    ) -> List[GraphQLError]:
        result2 = execute(
            self.schema.graphql_schema,
            document,
            root_value=self.root_value,
            context_value=context_value,
            variable_values=variable_values,
            operation_name=operation_name,
            middleware=self.middleware,
        )

        if isinstance(result2, ExecutionResult) and result2.errors:
            return result2.errors

        if isawaitable(result2):
            result2 = await cast(Awaitable[ExecutionResult], result2)

        result2 = cast(ExecutionResult, result2)

        payload: Dict[str, Any] = {}
        payload["data"] = result2.data
        if result2.errors:
            payload["errors"] = [
                format_error(error) for error in result2.errors
            ]

        await websocket.send_json({
            "type": GQL_DATA,
            "id": operation_id,
            "payload": payload
        })
        return []
Ejemplo n.º 33
0
    async def execute(
        self,
        document: DocumentNode,
        *args,
        **kwargs,
    ) -> ExecutionResult:
        """Execute the provided document AST for on a local GraphQL Schema."""

        result_or_awaitable = execute(self.schema, document, *args, **kwargs)

        execution_result: ExecutionResult

        if isawaitable(result_or_awaitable):
            result_or_awaitable = cast(Awaitable[ExecutionResult],
                                       result_or_awaitable)
            execution_result = await result_or_awaitable
        else:
            result_or_awaitable = cast(ExecutionResult, result_or_awaitable)
            execution_result = result_or_awaitable

        return execution_result
Ejemplo n.º 34
0
 def b():
     return execute(schema, ast)
Ejemplo n.º 35
0
 def execute(self, *args, **kwargs):
     return execute(self.schema, *args, **kwargs)