V2 API Python helper class

Here’s a basic Python class to get you up and running against the GraphQL API in V2:

from gql import Client
from gql.transport.requests import RequestsHTTPTransport

class Sonar:
    """This is a simple class for accessing the GraphQL API in Sonar V2.
    
    Args:
        sonar_url: The full URL to the GraphQL endpoint.
            Ex: https://instance.sonar.software/api/graphql
        token: The Personal Access Token of the user that will access the API.
    """
    
    def __init__(self, sonar_url, token):
        self.client = Client(
            transport=RequestsHTTPTransport(
                url=sonar_url,
                headers={
                    'Authorization': 'Bearer ' + token
                }
            )
        )

    def execute(self, query, variable_values=None):
        return self.client.execute(query, variable_values=variable_values)

Example usage:

from gql import gql
sonar = Sonar('https://example.sonar.software/api/graphql', 'secret.token')

sonar.execute(gql("""{
    accounts {
        entities {
            id
        }
    }
}"""))
# {
#   'accounts': {
#     'entities': [
#       { 'id': '1' },
#       { 'id': '2' },
#       ...
#     ]
#   }
# }

# Note: Int64Bit scalars are returned from the API as string

Maybe someone will find it useful.

2 Likes

Thank you - this will save me some work in the next few months.

This is very helpful. However I’m running into issues with dynamic queries using the DSL module.

this is what I have as my helper

 try:
            self.transport = RequestsHTTPTransport(
                url='https://%s/api/graphql' % self.hostname,
                use_json=True,
                headers={
                    'Content-type': 'application/json',
                    'Authorization': 'Bearer ' + str(self.api_key),
                },
                verify=False,
                retries=3,
            )

            self.client = Client(
                transport=self.transport,
                fetch_schema_from_transport=True,
            )

Then I use this

ds = DSLSchema(self.client)


        query_dsl = ds.Query.accounts.select(
                ds.Account.id,
                ds.Account.name,
            )

this creates the following query

{ accounts {
    id
   name
   }
}

however it’s missing the “query” and “entities” so I can’t execute this.

I need this generated instead

query { 
      accounts {
            entities {
                id
                name
                }
     }
}

Have you had any luck building the queries dynamically using the DSL module ?

Not sure about DSL, but you don’t need the query bit, however you definitely need the entities part here.

i.e., this is valid:

{
  accounts {
    entities {
      id
      name
    }
  }
}

I got it working. This is the correct way to build a dynamic query that uses the “entities”

 dsl_query = ds.Query.accounts.select(
                      ds.AccountConnection.entities.select(
                          ds.Account.id,
                          ds.Account.name
                          )
                     )

This will produce the following

accounts {
  entities {
    id
    name
  }
}

This will work fine in postman but will not execute in python using gql so you then need to wrap it with curly braces

wrapped_query = "{\n " + str(dsl_query) + " \n}"

And then finally convert it to a gql object

query = gql(wrapped_query)

Now you can execute it

client.execute(query)

1 Like