コード例 #1
0
ファイル: query.py プロジェクト: pm5/django-graphql
class QueryEngine:
    """
    GraphQL query engine.

    Usage:

        graphql = QueryEngine()
        graphql.addModel('user', user)
        result = graphql.query('''
            {
                user(id: 4) {
                    name
                }
            }
        ''')
        # result = {'user': {'name': 'Mark Zuckerberg'}}
    """
    def __init__(self, **kwargs):
        self._models = {}
        self._parser = GraphQLParser()

    def addModel(self, name, model):
        self._models[name] = model

    def _getAST(self, query):
        return self._parser.parse(query)

    def query(self, query):
        ast = self._getAST(query)
コード例 #2
0
ファイル: schema.py プロジェクト: willingc/django-graph-api
    def execute(self, document):
        """
        Queries the schema in python.

        :param document: A GraphQL query string
        :return: JSON of returned data or errors

        e.g.
        ::

            query = '''
            {
                users {
                    name
                }
            }
            '''
            schema.execute(query)

        Might return
        ::

            {
                "data": {
                    "users": [
                        {"name": "Buffy Summers"},
                        {"name": "Willow Rosenberg"},
                        {"name": "Xander Harris"}
                    ]
                }
            }
        """
        parser = GraphQLParser()
        ast = parser.parse(document)

        queries = [
            definition for definition in ast.definitions
            if isinstance(definition, Query)
        ]
        assert len(queries) == 1, "Exactly one query must be defined"

        fragments = {
            definition.name: definition
            for definition in ast.definitions
            if isinstance(definition, FragmentDefinition)
        }

        return {
            'data':
            self.query_root(
                ast=queries[0],
                data=None,
                fragments=fragments,
            ).serialize(),
        }
コード例 #3
0
    def execute(self, document):
        """
        Queries the schema in python.

        :param document: A GraphQL query string
        :return: JSON of returned data or errors

        e.g.
        ::

            query = '''
            {
                users {
                    name
                }
            }
            '''
            schema.execute(query)

        Might return
        ::

            {
                "data": {
                    "users": [
                        {"name": "Buffy Summers"},
                        {"name": "Willow Rosenberg"},
                        {"name": "Xander Harris"}
                    ]
                }
            }
        """
        parser = GraphQLParser()
        ast = parser.parse(document)

        query_ast = ast.definitions[0]

        if any(selection.name == '__schema'
               for selection in query_ast.selections):
            raise NotImplementedError(
                'This version of django-graph-api does not support introspection'
            )

        return {
            'data': self.query_root(query_ast, None).serialize(),
        }
コード例 #4
0
def get_completions(gql, idx, schema):
    """Creates AST from `gql` query string, finds out exactly where cursor is in
    string, and uses `schema` to get appropriate completions. Doesn't protect
    against exceptions. They should be handled by calling code.
    """
    try:  # at module import time this package is not available
        from graphql.parser import GraphQLParser
        from graphql.lexer import GraphQLLexer
    except ImportError:
        raise Exception('Install graphql-py with pip for GraphQL autocomplete')

    try:  # monkey-patch this class, the `t_NULL` method breaks parsing
        delattr(GraphQLLexer, 't_NULL')
    except AttributeError:
        pass

    start, end = slurp_word(gql, idx)
    gql_parser = GraphQLParser()
    ast = gql_parser.parse(gql[:start] + placeholder + gql[end:],
                           lexer=GraphQLLexer())

    for query in ast.definitions:  # get path if it exists
        path = placeholder_path(query, placeholder)
        if path is not None:
            break

    query_type, types = schema
    t = resolve_type(path, types, query_type)
    fields = types[t]['fields']

    completions = []
    for f in fields.values():
        name = f['name']
        args = [a['name'] + ':' for a in f['args']]
        args_string = '({})'.format(', '.join(args)) if args else ''
        type_name = resolve_field_type(f)
        completions.append([
            '{}{}\t{}'.format(name, args_string, type_name),
            '{}{}'.format(name, args_string),
        ])

    return (completions, sublime.INHIBIT_WORD_COMPLETIONS
            | sublime.INHIBIT_EXPLICIT_COMPLETIONS)
コード例 #5
0
    def __init__(self, document, schema, variables=None, operation_name=None):
        """
        Creates a Request object that can be validated and executed.

        :param document: The query string to execute.

            e.g. ``"query episodeNames { episodes { name } }"``

        :param schema: A Schema object to run the query against
        :param variables: A ``dict`` of variables to pass to the query (optional)
        :param operation_name: If the document contains multiple named queries,
            the name of the query to execute (optional)
        """
        self.document = document
        self.variables = variables or {}
        self.operation_name = operation_name
        self.schema = schema
        self._validated = False
        self._errors = []
        self.query_root = None
        parser = GraphQLParser()

        if not self.document:
            self._errors.append(GraphQLError('Must provide query string.'))
        else:
            try:
                self.ast = parser.parse(self.document)
            except (graphql_exceptions.LexerError,
                    graphql_exceptions.SyntaxError) as e:
                self.ast = None
                self._errors.append(
                    GraphQLError(
                        'Parse error: {}'.format(e),
                        line=e.line,
                        column=e.column,
                    ))

        # Additional errors are meaningless if we couldn't parse the document
        if self._errors:
            self._validated = True
コード例 #6
0
def main():

    moreDetails = False

    if len(sys.argv) > 1 and sys.argv[1] == 'True':
        moreDetails = True
        print(
            "You have chosen to get some more details of your schema coverage. This will be provided in a file in root "
            "called 'individualSchemaCoverage.csv'. The overview of the covered schema will be printed to a file "
            "called 'schemaCoverageDictionary.csv'.")
        with open('individualSchemaCoverage.csv', 'w') as csvfile:
            csvwriter = csv.writer(csvfile)
            csvwriter.writerow(['testID', 'individualCoverage'])

    templateLoader = jinja2.FileSystemLoader(searchpath="")
    templateEnv = jinja2.Environment(loader=templateLoader)
    template = templateEnv.get_template(cfg.test_template)

    parser = GraphQLParser()
    encoder = json.JSONEncoder()

    types = requests.post(cfg.graphql_url,
                          data=encoder.encode(cfg.schema_query),
                          headers={'content-type': 'application/json'})

    schema = json.loads(types.content)['data']['__schema']

    #jsonschema = json.dumps(schema)
    #jsonFile = open('schema.json', 'w+')
    #jsonFile.write(jsonschema)

    createDict = CreateDictionaries(schema)
    possValuesDict = createDict.possibleValuesDictionary()
    schemaCoverageDict = createDict.schemaCoverageDictionary()

    searcher = SchemaSearcher(schema, schemaCoverageDict)
    walker = AstWalker(searcher)
    createAssertions = CreateAssertions(possValuesDict)

    for f in os.listdir('queries/'):
        id = f.split('.json')[0]
        if id == '.DS_Store':
            continue
        testName = 'Q' + ''.join(id.split('-')) + 'Test'
        payload = open('queries/' + f).read()
        jsonPayload = "<<<'JSON'\n" + payload + "\nJSON"

        try:
            dict = json.loads(payload)
        except:
            print("Couldn't load " + id)
            continue

        try:
            astree = parser.parse(dict['query'])
        except:
            print('Something is wrong with test ' + id)
            continue

        mutation = False
        query = None

        # Checking there are no mutations in query
        for tree in astree.definitions:
            if type(tree) == graphql.ast.Mutation:
                print(id + ' contains mutations and will not be used')
                mutation = True
                break

        # Skipping current query if contains mutations
        if mutation:
            continue

        searcher.setId(id)

        # Checking other types in query
        for tree in astree.definitions:
            if type(tree) == graphql.ast.FragmentDefinition:
                success = createDict.createFragmentDictionary(tree, walker)
                if success:
                    walker.fragmentDictionary = createDict.fragmentDictionary
                else:
                    astree.definitions.append(tree)
                    continue
            elif type(tree) == graphql.ast.Query or type(tree) == None:
                query = tree

        rootNode = walker.walk(query, None)

        if moreDetails:
            createSchemaDict = CreateDictionaries(schema)
            individualSchemaCoverageDict = createSchemaDict.schemaCoverageDictionary(
            )
            schemaSearcher = SchemaSearcher(schema,
                                            individualSchemaCoverageDict)
            schemaWalker = AstWalker(schemaSearcher)
            schemaWalker.fragmentDictionary = createDict.fragmentDictionary
            schemaWalker.walk(query, None)
            with open('individualSchemaCoverage.csv', 'a') as csvfile:
                csvwriter = csv.writer(csvfile)
                csvwriter.writerow(
                    [id, (schemaSearcher.calculateSchemaCoverage() * 100)])

        variables = ['$a', '$b', '$c', '$d', '$e', '$f', '$g']

        try:
            assertions = []
            for node in rootNode:
                nodeAssertions = createAssertions.createAssertions(
                    node, variables)
                for line in nodeAssertions:
                    assertions.append(line)
            output = template.render(className=testName,
                                     query=jsonPayload,
                                     allAssertions=assertions,
                                     graphQLURL=cfg.graphql_url,
                                     authToken=cfg.authorization_token)
            testfile = open('testCases/' + testName + '.php', 'w')
            testfile.write(output)
            testfile.close()
        except:
            continue

    if moreDetails:
        with open('schemaCoverageDictionary.csv', 'w') as csvfile:
            csvwriter = csv.writer(csvfile)
            csvwriter.writerow(
                ['schemaTuple', 'visited', 'timesVisited', 'id'])
            for line in schemaCoverageDict:
                csvwriter.writerow([
                    line, schemaCoverageDict[line][1],
                    schemaCoverageDict[line][0], schemaCoverageDict[line][2]
                ])

    print("The schema coverage for the generated test suite is: " +
          str(searcher.calculateSchemaCoverage() * 100) + ' %' +
          " where mutations are: " + str(searcher.calculateMutations() * 100) +
          ' % of the schema and input objects are: ' +
          str(searcher.calculateInputTypes() * 100) + ' % of the schema.')
コード例 #7
0
ファイル: graphql.py プロジェクト: WeshGuillaume/vim-graphiql
def get_graphql_tree(content):
    parser = GraphQLParser()
    ast = parser.parse(query)
    return ast.definitions[0].selections[0]