Skip to content

DSL does not provide expected argument validation #355

Description

@brhubbar

Describe the bug

  • When creating a query with gql.gql(), the query string is checked for invalid arguments, and raises an exception if any are found. (expected behavior)
  • When creating a query with gql.dsl.dsl_gql(), the arguments are not checked, causing unexpected return values. (unexpected behavior)

I've been able to recreate this using the countries api used in the docs.

To Reproduce

Jump to step 5 to see the actual improper behavior.

  1. Set up the transport/client.

    import json
    
    import gql
    from gql.transport.requests import RequestsHTTPTransport as Transport
    from gql import dsl
    
    url = "https://countries.trevorblades.com/"
    
    transport = Transport(url=url)
    client = gql.Client(transport=transport, fetch_schema_from_transport=True)
    
    # Fetch the schema (lemme know if there's a recommended approach for this).
    client.connect_sync()
    client.close_sync()
    ds = dsl.DSLSchema(client.schema)
  2. Run a good query using strings.

    good_query_str = gql.gql(
        """
        query {
            continents (filter:{code:{eq:"AN"}}) {
                code
                name
            }
        }
        """
    )
    result = client.execute(good_query_str)
    print(json.dumps(result, indent=2))

    Result:

     {
     "continents": [
         {
         "code": "AN",
         "name": "Antarctica"
         }
     ]
     }
  3. Run a bad query using strings. The only change here is using 'AN' directly as an argument to code, instead of providing the eq directive.

    bad_query_str = gql.gql(
        """
        query {
            continents (filter:{code:"AN"}) {
                code
                name
            }
        }
        """
    )
    result = client.execute(bad_query_str)
    print(json.dumps(result, indent=2))

    Result:

    GraphQLError: Expected value of type 'StringQueryOperatorInput', found "AN".
    
     GraphQL request:3:34
     2 |     query {
     3 |         continents (filter:{code:"AN"}) {
     |                                  ^
     4 |             code
  4. Run a good query using DSL.

    good_query_dsl = dsl.dsl_gql(
        dsl.DSLQuery(
            ds.Query.continents(
                filter={
                    'code': {'eq': 'AN'}
                }
            ).select(
                ds.Continent.code,
                ds.Continent.name,
            )
        )
    )
    result = client.execute(good_query_dsl)
    print(json.dumps(result, indent=2))

    Result:

     {
     "continents": [
         {
         "code": "AN",
         "name": "Antarctica"
         }
     ]
     }
  5. Run a bad query using DSL. Same deal, just remove the 'eq' level of filter specification. Note that the result is an unfiltered response.

    bad_query_dsl = dsl.dsl_gql(
        dsl.DSLQuery(
            ds.Query.continents(
                filter={
                    'code': 'AN'
                }
            ).select(
                ds.Continent.code,
                ds.Continent.name,
            )
        )
    )
    result = client.execute(bad_query_dsl)
    print(json.dumps(result, indent=2))

    Result:

     {
     "continents": [
         {
         "code": "AF",
         "name": "Africa"
         },
         {
         "code": "AN",
         "name": "Antarctica"
         },
         {
         "code": "AS",
         "name": "Asia"
         },
         {
         "code": "EU",
         "name": "Europe"
         },
         {
         "code": "NA",
         "name": "North America"
         },
         {
         "code": "OC",
         "name": "Oceania"
         },
         {
         "code": "SA",
         "name": "South America"
         }
     ]
     }

Expected behavior

Step 5 should raise an equivalent exception to step 3.

System info (please complete the following information):

  • OS: Wins 10
  • Python version: 3.9.12
  • gql version: 3.4.0
  • graphql-core version: 3.2.1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions