def test_resolver_decorator(): schema = build_schema(SDL) @schema.resolver("Query.foo") def _resolve_foo(*_): return "foo" assert ( "foo" == graphql_blocking(schema, "{ foo }").response()["data"]["foo"] )
def _override_test_schema(self) -> Schema: return build_schema(""" type Foo { a: Int b: Int! } type Query { foo: Foo! } """)
def test_resolver_decorator_multiple_applications(): schema = build_schema(SDL) @schema.resolver("Query.bar") @schema.resolver("Query.foo") def _resolve_foo(*_): return "foo" assert {"foo": "foo", "bar": "foo"} == graphql_blocking( schema, "{ foo, bar }" ).response()["data"]
def schema() -> Schema: return build_schema( """ directive @foo(arg_one: Int!, arg_two: InputObject) on FIELD input InputObject { field_one: Int! field_two: String } type Query { snake_case_field: Int, field_with_arguments(arg_one: Int!, arg_two: InputObject): String, } """ )
def test_hides_input_type_field(): schema = build_schema( """ input Foo { name: String id: ID! } input Bar { name: String id: ID! } type Query { field(foo: Foo, bar: Bar): String } """ ) class HideInputField(VisibilitySchemaTransform): def is_input_field_visible(self, typename, fieldname): return not (typename == "Foo" and fieldname == "name") assert ( dedent( """ input Bar { name: String id: ID! } input Foo { id: ID! } type Query { field(foo: Foo, bar: Bar): String } """ ) == _sdl(transform_schema(schema, HideInputField())) )
def schema(): return build_schema( """ directive @barDirective(arg: SomeEnum, other_arg: Int) on FIELD directive @fooDirective on FIELD type Bar implements IFace { name: String } type Foo implements IFace { name: String } interface IFace { name: String } type Query { a(arg: SomeEnum, other_arg: Int): String foo: Foo iface: IFace union: Thing uid: UUID } enum SomeEnum { FOO BAR } union Thing = Foo | Bar scalar UUID """ )
# -*- coding: utf-8 -*- from py_gql import build_schema, graphql_blocking schema = build_schema( """ type Query { hello(value: String = "world"): String! } """ ) @schema.resolver("Query.hello") def resolve_hello(*_, value): return "Hello {}!".format(value) result = graphql_blocking(schema, '{ hello(value: "World") }') assert result.response() == {"data": {"hello": "Hello World!"}}
def get_query_dict(sdl_path, depth_limit=100, include_deprecated_fields=True): """ :param sdl_path: Path to an SDL file :param depth_limit: the maximum depth of nesting to probe :param include_deprecated_fields: whether to include deprecated fields :return: dictionary whose key is a function and whose value is the query string to the function """ TAP_STRING = ' ' def generate_subquery(cur_name, cur_parent_type, cur_parent_name=None, arguments_dict=None, duplicate_args_counts=None, cross_reference_key_list=None, cur_depth=1): if arguments_dict is None: arguments_dict = {} if duplicate_args_counts is None: duplicate_args_counts = {} if cross_reference_key_list is None: cross_reference_key_list = [] field_args_dict = None field = gql_schema.get_type(cur_parent_type).field_map.get(cur_name) cur_type_name = field.type.type.name if hasattr( field.type, "type") else field.type.name cur_type = gql_schema.get_type(cur_type_name) query_str = "" child_query = '' if hasattr(cur_type, "fields") and cur_type.fields: cross_reference_key = "{}To{}Key".format(cur_parent_name, cur_name) if cross_reference_key in cross_reference_key_list or cur_depth > depth_limit: return '' cross_reference_key_list.append(cross_reference_key) if cur_type.fields != NotImplemented: child_keys = map(lambda x: x.name, cur_type.fields) child_keys = filter( lambda field_name: include_deprecated_fields or not cur_type.field_map.get(field_name).deprecated, child_keys) child_query_list = [] for child_key in child_keys: res = generate_subquery(child_key, cur_type.name, cur_name, arguments_dict, duplicate_args_counts, deepcopy(cross_reference_key_list), cur_depth + 1) if "query_str" in res: child_query_list.append(res.get("query_str")) child_query = "\n".join(child_query_list) if not ((hasattr(cur_type, "fields") and cur_type.fields != NotImplemented) and (not child_query)): query_str = TAP_STRING * cur_depth + field.name if field.arguments.__len__() > 0: field_args_dict = get_field_args_dict(field, duplicate_args_counts, arguments_dict) arguments_dict.update(field_args_dict) query_str += "({})".format( get_args_to_vars_str(field_args_dict)) if child_query: query_str += "{{\n{}\n{}}}".format(child_query, TAP_STRING * cur_depth) if hasattr(cur_type, "nodes") and cur_type.nodes and isinstance( cur_type.nodes[0], UnionTypeDefinition): types = cur_type.types if types: indent = TAP_STRING * cur_depth frag_indent = TAP_STRING * (cur_depth + 1) query_str += "{\n" for value_type_name in types: value_type = gql_schema.get_type(value_type_name.name) union_child_query_list = [] for cur in value_type.fields: res = generate_subquery( cur.name, value_type.name, cur_name, arguments_dict, duplicate_args_counts, deepcopy(cross_reference_key_list), cur_depth + 2) if "query_str" in res: union_child_query_list.append(res.get("query_str")) union_child_query = "\n".join(union_child_query_list) query_str += "{}... on {} {{\n{}\n{}}}\n".format( frag_indent, value_type_name.name, union_child_query, frag_indent) query_str += indent + "}" return { 'query_str': query_str, 'arguments_dict': arguments_dict, 'field_args_dict': field_args_dict } with open(sdl_path) as v: sdl = "".join(v.readlines()) gql_schema = build_schema(sdl) if not gql_schema.query_type: return query_dict = {} for type in gql_schema.query_type.fields: field = gql_schema.get_type("Query").field_map.get(type.name) if not include_deprecated_fields and field.deprecated: continue query_result = generate_subquery(field.name, "Query") vars_to_types_str = get_vars_to_types_str( query_result["arguments_dict"]) query = "{} {}{}{{\n{}\n}}".format('query', type.name, ('(' + vars_to_types_str + ')') if vars_to_types_str else '', query_result["query_str"]) query_dict["resolve_{}".format(type.name)] = { 'query': query, 'field_args_dict': query_result["field_args_dict"] } return query_dict
"residents": nested_list_resolver("residents", "people"), "films": nested_list_resolver("films", "films"), "population": string_numeric_resolver("population"), "surface_water": string_numeric_resolver("surface_water"), }, "Person": { "homeworld": nested_single_resource_resolver("homeworld", "planets"), "films": nested_list_resolver("films", "films"), "vehicles": nested_list_resolver("vehicles", "vehicles"), "starships": nested_list_resolver("starships", "starships"), "height": string_numeric_resolver("height"), "mass": string_numeric_resolver("mass"), "species": nested_list_resolver("species", "species"), }, "Starship": TRANSPORT_RESOLVERS, "Vehicle": TRANSPORT_RESOLVERS, "Species": { "homeworld": nested_single_resource_resolver("homeworld", "planets"), "people": nested_list_resolver("people", "people"), "films": nested_list_resolver("films", "films"), "average_lifespan": string_numeric_resolver("average_lifespan"), }, } with open(os.path.join(os.path.dirname(__file__), "schema.graphql")) as f: SCHEMA = build_schema(f.read()) for typename, field_resolvers in RESOLVERS.items(): for fieldname, resolver in field_resolvers.items(): SCHEMA.register_resolver(typename, fieldname, resolver)
def github_schema(fixture_file): return build_schema(fixture_file("github-schema.graphql"))
from typing import Any, Awaitable, cast import pytest from py_gql import build_schema from py_gql.exc import ResolverError from py_gql.execution.runtime import AsyncIORuntime from ._test_utils import assert_execution schema = build_schema(""" type Query { a: Int! nested: Int! sync_a: Int! b(sleep: Float): Int! c: [Int]! error: Int! sync_error: Int! } """) @schema.resolver("Query.a") async def resolve_a(*_: Any) -> int: return 42 @schema.resolver("Query.nested") async def resolve_nested(*_: Any) -> Awaitable[int]: return resolve_a()
"name": "Han Solo" }, { "type": "Human", "id": 1003, "name": "Leia Organa" }, { "type": "Human", "id": 1004, "name": "Wilhuff Tarkin" } ] """ schema = build_schema(SDL) database = {row["id"]: row for row in json.loads(DATA)} @schema.resolver("Query.hero") def resolve_hero(_root, ctx, _info): return ctx["db"][2000] # R2-D2 @schema.resolver("Query.characters") def resolve_characters(_root, ctx, _info): return ctx["db"].items() @schema.resolver("Query.character") def resolve_character(_root, ctx, _info, *, id):
def test_register_resolver(): schema = build_schema(SDL) schema.register_resolver("Query", "foo", lambda *_: "foo") assert ( "foo" == graphql_blocking(schema, "{ foo }").response()["data"]["foo"] )
def test_introspection_query(benchmark, fixture_file): github_schema = py_gql.build_schema(fixture_file("github-schema.graphql")) query = py_gql.utilities.introspection_query() benchmark(py_gql.graphql_blocking, github_schema, query)
LIST_OF_INTS = range(SIZE) LIST_OF_FLOATS = [random.random() for x in range(SIZE)] LIST_OF_STRINGS = [str(x) for x in range(SIZE)] LIST_OF_BOOLS = [bool(x % 2) for x in range(SIZE)] LIST_OF_OBJECTS = [FooType(x, x, x) for x in range(SIZE)] LIST_OF_DICTS = [{"x": x, "y": x, "z": x} for x in range(SIZE)] schema = py_gql.build_schema(""" type Foo { x: Int, y: Int, z: Int, } type Query { list_of_ints: [Int], list_of_floats: [Float], list_of_string_ids: [ID], list_of_int_ids: [ID], list_of_strings: [String], list_of_bools: [Boolean], list_of_objects: [Foo], list_of_dicts: [Foo], } """) @schema.resolver("Query.list_of_ints") @schema.resolver("Query.list_of_int_ids") def _resolve_list_of_ints(*_, **__): return LIST_OF_INTS
def test_validate_introspection_query(benchmark, fixture_file): schema = build_schema(fixture_file("github-schema.graphql")) doc = parse(introspection_query()) benchmark(validate_ast, schema, doc)
from copy import deepcopy from utils import * TAP_STRING = ' ' parser = argparse.ArgumentParser() parser.add_argument('--schemaFilePath', type=str) parser.add_argument('--destDirPath', type=str) parser.add_argument('--depthLimit', type=int) parser.add_argument('-C', '--includeDeprecatedFields', action='store_true') args = parser.parse_args() with open(args.schemaFilePath) as v: sdl = "".join(v.readlines()) gql_schema = build_schema(sdl) mkdir_if_not_exist(args.destDirPath) def generate_query(cur_name, cur_parent_type, cur_parent_name=None, arguments_dict=None, duplicate_args_counts=None, cross_reference_key_list=None, cur_depth=1): """ Generate the query for the specified field :param cur_name: the name of the current field :param cur_parent_type: the parent type of the current field
def test_resolver_decorator_invalid_path(): schema = build_schema(SDL) with pytest.raises(ValueError): schema.resolver("Query")(lambda *_: "foo")
message(id: UUID!): Message, room(id: UUID!): Room, rooms: [Room]!, } type Mutation { create_room(data: CreateRoomInput!): Room, create_message(room_id: UUID!, data: CreateMessageInput!): Message, } type Subscription { new_message(room_id: UUID!): Message } """ schema = build_schema(SDL, additional_types=[UUID]) @schema.resolver("Query.rooms") def resolve_rooms(_root: Any, board: MessageBoard, _info: Any) -> List[Room]: return list(board.rooms.values()) @schema.resolver("Room.messages") def resolve_room_messages( room: Room, board: MessageBoard, _info: Any, *, since: Optional[int] = None, limit: Optional[int] = None,
""" Simple mutations example: incrementing and decrementing a global counter. """ from py_gql import build_schema, graphql_blocking ROOT = {"counter": 0} schema = build_schema( """ type Query { counter: Int } type Mutation { increment(amount: Int = 1): Int decrement(amount: Int = 1): Int } """ ) @schema.resolver("Mutation.increment") def inc(root, *, amount): root["counter"] += amount return root["counter"] @schema.resolver("Mutation.decrement") def dec(root, *, amount):