def test_invalid_meta_field_selection(ds): DSLQuery(DSLMetaField("__typename")) DSLQuery(DSLMetaField("__schema")) DSLQuery(DSLMetaField("__type")) metafield = DSLMetaField("__typename") assert metafield.name == "__typename" # alias does not work metafield.alias("test") assert metafield.name == "__typename" with pytest.raises(GraphQLError): DSLMetaField("__invalid_meta_field") DSLMutation(DSLMetaField("__typename")) with pytest.raises(GraphQLError): DSLMutation(DSLMetaField("__schema")) with pytest.raises(GraphQLError): DSLMutation(DSLMetaField("__type")) with pytest.raises(GraphQLError): DSLSubscription(DSLMetaField("__typename")) with pytest.raises(GraphQLError): DSLSubscription(DSLMetaField("__schema")) with pytest.raises(GraphQLError): DSLSubscription(DSLMetaField("__type")) fragment = DSLFragment("blah") with pytest.raises(AttributeError): fragment.select(DSLMetaField("__typename")) fragment.on(ds.Character) fragment.select(DSLMetaField("__typename")) with pytest.raises(GraphQLError): fragment.select(DSLMetaField("__schema")) with pytest.raises(GraphQLError): fragment.select(DSLMetaField("__type")) ds.Query.hero.select(DSLMetaField("__typename")) with pytest.raises(GraphQLError): ds.Query.hero.select(DSLMetaField("__schema")) with pytest.raises(GraphQLError): ds.Query.hero.select(DSLMetaField("__type"))
def test_inline_fragment_in_dsl_gql(ds): inline_fragment = DSLInlineFragment() query = DSLQuery() with pytest.raises( GraphQLError, match=r"Invalid field for <DSLQuery>: <DSLInlineFragment>", ): query.select(inline_fragment)
def test_multiple_operations(ds): query = dsl_gql( GetHeroName=DSLQuery(ds.Query.hero.select(ds.Character.name)), CreateReviewMutation=DSLMutation( ds.Mutation.createReview.args(episode=6, review={ "stars": 5, "commentary": "This is a great movie!" }).select(ds.Review.stars, ds.Review.commentary)), ) assert (print_ast(query) == """query GetHeroName { hero { name } } mutation CreateReviewMutation { createReview(episode: JEDI, review: {stars: 5, \ commentary: "This is a great movie!"}) { stars commentary } } """)
def test_dsl_root_type_not_default(): from graphql import parse, build_ast_schema schema_str = """ schema { query: QueryNotDefault } type QueryNotDefault { version: String } """ type_def_ast = parse(schema_str) schema = build_ast_schema(type_def_ast) ds = DSLSchema(schema) query = dsl_gql(DSLQuery(ds.QueryNotDefault.version)) expected_query = """ { version } """ assert print_ast(query) == expected_query.strip() with pytest.raises(GraphQLError) as excinfo: DSLSubscription(ds.QueryNotDefault.version) assert ( "Invalid field for <DSLSubscription>: <DSLField QueryNotDefault::version>" ) in str(excinfo.value)
def test_dsl_query_all_fields_should_correspond_to_the_root_type(ds): with pytest.raises(GraphQLError) as excinfo: DSLQuery(ds.Character.name) assert ("Invalid field for <DSLQuery>: <DSLField Character::name>") in str( excinfo.value )
def test_fragments(ds): query = """fragment NameAndAppearances on Character { name appearsIn } { hero { ...NameAndAppearances } }""" name_and_appearances = ( DSLFragment("NameAndAppearances") .on(ds.Character) .select(ds.Character.name, ds.Character.appearsIn) ) query_dsl = DSLQuery(ds.Query.hero.select(name_and_appearances)) document = dsl_gql(name_and_appearances, query_dsl) print(print_ast(document)) assert query == print_ast(document)
async def main(): transport = AIOHTTPTransport( url="https://countries.trevorblades.com/graphql") client = Client(transport=transport, fetch_schema_from_transport=True) # Using `async with` on the client will start a connection on the transport # and provide a `session` variable to execute queries on this connection. # Because we requested to fetch the schema from the transport, # GQL will fetch the schema just after the establishment of the first session async with client as session: # Instanciate the root of the DSL Schema as ds ds = DSLSchema(client.schema) # Create the query using dynamically generated attributes from ds query = dsl_gql( DSLQuery( ds.Query.continents(filter={ "code": { "eq": "EU" } }).select(ds.Continent.code, ds.Continent.name))) result = await session.execute(query) print(result) # This can also be written as: # I want to query the continents query_continents = ds.Query.continents # I want to get only the continents with code equal to "EU" query_continents(filter={"code": {"eq": "EU"}}) # I want this query to return the code and name fields query_continents.select(ds.Continent.code) query_continents.select(ds.Continent.name) # I generate a document from my query to be able to execute it query = dsl_gql(DSLQuery(query_continents)) # Execute the query result = await session.execute(query) print(result)
def test_nested_input_2(ds, client): query = dsl_gql( DSLQuery(ds.Query.echo.args(nested={ "foo": 1, "child": { "foo": 2 } }))) assert client.execute(query) == {"echo": '{"foo": 1, "child": {"foo": 2}}'}
def test_operation_name(ds): query = dsl_gql( GetHeroName=DSLQuery(ds.Query.hero.select(ds.Character.name), )) assert (print_ast(query) == """query GetHeroName { hero { name } } """)
def test_root_fields_aliased(ds, client): query = dsl_gql( DSLQuery( ds.Query.hero.select(ds.Character.name), hero_of_episode_5=ds.Query.hero(episode=5).select(ds.Character.name), ) ) result = client.execute(query) expected = { "hero": {"name": "R2-D2"}, "hero_of_episode_5": {"name": "Luke Skywalker"}, } assert result == expected
async def _query_today(self, thumbs=False): """ Queries the API wrapper with the 'today' query """ async with self._gql_client as session: schema = self._get_schema() query = dsl_gql( DSLQuery( schema.Query.today( apiKey=self._config['api_key'], thumbs=thumbs).select( schema.Apod.copyright, schema.Apod.explanation, schema.Apod.hdurl, schema.Apod.mediaType, schema.Apod.title, schema.Apod.url))) result = await session.execute(query) return result
def test_arg_serializer_list(ds, client): query = dsl_gql( DSLQuery( ds.Query.characters.args(ids=[1000, 1001, 1003]).select( ds.Character.name, ) ) ) result = client.execute(query) expected = { "characters": [ {"name": "Luke Skywalker"}, {"name": "Darth Vader"}, {"name": "Leia Organa"}, ] } assert result == expected
def test_type_hero_query(ds): query = """{ __type(name: "Hero") { kind name ofType { kind name } } }""" type_hero = DSLMetaField("__type")(name="Hero") type_hero.select( ds.__Type.kind, ds.__Type.name, ds.__Type.ofType.select(ds.__Type.kind, ds.__Type.name), ) query_dsl = DSLQuery(type_hero) assert query == str(print_ast(dsl_gql(query_dsl))).strip()
def get_introspection_query_ast( descriptions: bool = True, specified_by_url: bool = False, directive_is_repeatable: bool = False, schema_description: bool = False, type_recursion_level: int = 7, ) -> DocumentNode: """Get a query for introspection as a document using the DSL module. Equivalent to the get_introspection_query function from graphql-core but using the DSL module and allowing to select the recursion level. Optionally, you can exclude descriptions, include specification URLs, include repeatability of directives, and specify whether to include the schema description as well. """ ds = DSLSchema(GraphQLSchema()) fragment_FullType = DSLFragment("FullType").on(ds.__Type) fragment_InputValue = DSLFragment("InputValue").on(ds.__InputValue) fragment_TypeRef = DSLFragment("TypeRef").on(ds.__Type) schema = DSLMetaField("__schema") if descriptions and schema_description: schema.select(ds.__Schema.description) schema.select( ds.__Schema.queryType.select(ds.__Type.name), ds.__Schema.mutationType.select(ds.__Type.name), ds.__Schema.subscriptionType.select(ds.__Type.name), ) schema.select(ds.__Schema.types.select(fragment_FullType)) directives = ds.__Schema.directives.select(ds.__Directive.name) if descriptions: directives.select(ds.__Directive.description) if directive_is_repeatable: directives.select(ds.__Directive.isRepeatable) directives.select( ds.__Directive.locations, ds.__Directive.args.select(fragment_InputValue), ) schema.select(directives) fragment_FullType.select( ds.__Type.kind, ds.__Type.name, ) if descriptions: fragment_FullType.select(ds.__Type.description) if specified_by_url: fragment_FullType.select(ds.__Type.specifiedByURL) fields = ds.__Type.fields(includeDeprecated=True).select(ds.__Field.name) if descriptions: fields.select(ds.__Field.description) fields.select( ds.__Field.args.select(fragment_InputValue), ds.__Field.type.select(fragment_TypeRef), ds.__Field.isDeprecated, ds.__Field.deprecationReason, ) enum_values = ds.__Type.enumValues(includeDeprecated=True).select( ds.__EnumValue.name ) if descriptions: enum_values.select(ds.__EnumValue.description) enum_values.select( ds.__EnumValue.isDeprecated, ds.__EnumValue.deprecationReason, ) fragment_FullType.select( fields, ds.__Type.inputFields.select(fragment_InputValue), ds.__Type.interfaces.select(fragment_TypeRef), enum_values, ds.__Type.possibleTypes.select(fragment_TypeRef), ) fragment_InputValue.select(ds.__InputValue.name) if descriptions: fragment_InputValue.select(ds.__InputValue.description) fragment_InputValue.select( ds.__InputValue.type.select(fragment_TypeRef), ds.__InputValue.defaultValue, ) fragment_TypeRef.select( ds.__Type.kind, ds.__Type.name, ) if type_recursion_level >= 1: current_field = ds.__Type.ofType.select(ds.__Type.kind, ds.__Type.name) fragment_TypeRef.select(current_field) for _ in repeat(None, type_recursion_level - 1): new_oftype = ds.__Type.ofType.select(ds.__Type.kind, ds.__Type.name) current_field.select(new_oftype) current_field = new_oftype query = DSLQuery(schema) query.name = "IntrospectionQuery" dsl_query = dsl_gql(query, fragment_FullType, fragment_InputValue, fragment_TypeRef) return dsl_query
def test_dsl_nested_query_with_fragment(ds): query = """fragment NameAndAppearances on Character { name appearsIn } query NestedQueryWithFragment { hero { ...NameAndAppearances friends { ...NameAndAppearances friends { ...NameAndAppearances } } } }""" name_and_appearances = ( DSLFragment("NameAndAppearances") .on(ds.Character) .select(ds.Character.name, ds.Character.appearsIn) ) query_dsl = DSLQuery( ds.Query.hero.select( name_and_appearances, ds.Character.friends.select( name_and_appearances, ds.Character.friends.select(name_and_appearances) ), ) ) document = dsl_gql(name_and_appearances, NestedQueryWithFragment=query_dsl) print(print_ast(document)) assert query == print_ast(document) # Same thing, but incrementaly name_and_appearances = DSLFragment("NameAndAppearances") name_and_appearances.on(ds.Character) name_and_appearances.select(ds.Character.name) name_and_appearances.select(ds.Character.appearsIn) level_2 = ds.Character.friends level_2.select(name_and_appearances) level_1 = ds.Character.friends level_1.select(name_and_appearances) level_1.select(level_2) hero = ds.Query.hero hero.select(name_and_appearances) hero.select(level_1) query_dsl = DSLQuery(hero) document = dsl_gql(name_and_appearances, NestedQueryWithFragment=query_dsl) print(print_ast(document)) assert query == print_ast(document)
def test_dsl_query_all_fields_should_be_instances_of_DSLField(): with pytest.raises( TypeError, match="Fields should be instances of DSLSelectable. Received: <class 'str'>", ): DSLQuery("I am a string")
from gql.dsl import DSLQuery, DSLSchema, dsl_gql from gql.transport.requests import RequestsHTTPTransport transport = RequestsHTTPTransport( url="https://countries.trevorblades.com/", verify=True, retries=3, ) client = Client(transport=transport, fetch_schema_from_transport=True) # Using `with` on the sync client will start a connection on the transport # and provide a `session` variable to execute queries on this connection. # Because we requested to fetch the schema from the transport, # GQL will fetch the schema just after the establishment of the first session with client as session: # We should have received the schema now that the session is established assert client.schema is not None # Instantiate the root of the DSL Schema as ds ds = DSLSchema(client.schema) # Create the query using dynamically generated attributes from ds query = dsl_gql( DSLQuery( ds.Query.continents.select(ds.Continent.code, ds.Continent.name))) result = session.execute(query) print(result)
def test_dsl_query_all_fields_should_correspond_to_the_root_type(ds): with pytest.raises(AssertionError) as excinfo: DSLQuery(ds.Character.name) assert ("Invalid root field for operation QUERY.\n" "Received: Character") in str(excinfo.value)
def test_dsl_query_all_fields_should_be_instances_of_DSLField(): with pytest.raises( TypeError, match="fields must be instances of DSLField. Received type:"): DSLQuery("I am a string")
def test_arg_serializer_enum(ds, client): query = dsl_gql( DSLQuery(ds.Query.hero.args(episode=5).select(ds.Character.name))) result = client.execute(query) expected = {"hero": {"name": "Luke Skywalker"}} assert result == expected
def test_hero_name_query_result(ds, client): query = dsl_gql(DSLQuery(ds.Query.hero.select(ds.Character.name))) result = client.execute(query) expected = {"hero": {"name": "R2-D2"}} assert result == expected