File size: 4,912 Bytes
38e70c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import json

import requests

counter = 0

class Query:
    name: str
    mutations: ()
    schema = ""
    url = "https://api.github.com/graphql"
    headers = {
        "Accept": "application/json",
        "Authorization": "Bearer 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",
        "Accept-Encoding": "gzip, deflate, br",
        "Content-Type": "application/json",
        "Connection": "keep-alive",
        "DNT": '1',
        "Origin": "file://"
    }

    def __init__(self, name):
        self.name = name
        self.schema = f"query {name}" + "{ <NEXT_VAL> }"
        self.path = []
        self.to_save = []
        self.to_iter = []

    def mutation(self, _name, **kwargs):
        args = []
        for k, v in kwargs.items():
            if isinstance(v, str):
                args.append(f'{k}: \"{v}\"')
            else:
                args.append(f'{k}: {v}')

        args = ', '.join(args)

        if len(args):
            args = f'({args})'

        self.schema = self.schema.replace('<NEXT_VAL>', f"{_name}{args}" + "{ <NEXT_VAL> }")
        self.path += [_name]
        return self

    def iter(self, _name):
        self.path += [_name]
        to_replace = f"{_name} (<ITER {self.path}>)" + "{ totalCount pageInfo { endCursor hasNextPage} <NEXT_VAL> }"
        self.schema = self.schema.replace('<NEXT_VAL>', to_replace)
        self.to_iter.append([*self.path])
        return self

    def save_result(self, _name):
        self.schema = self.schema.replace('<NEXT_VAL>', f"{_name} <NEXT_VAL>")
        self.to_save.append([*self.path, _name])
        return self

    @property
    def nodes(self):
        self.path.append('nodes')
        self.schema = self.schema.replace('<NEXT_VAL>', 'nodes { <NEXT_VAL> }')
        return self

    def end_of_page(self, previous, iterable):
        if previous is None:
            return False

        for selector in iterable:
            previous = previous[selector]

        return previous['pageInfo']['hasNextPage']

    def recursive_iterable(self, schema, iterables):
        if len(iterables) > 0:
            iterable = iterables[0]
            iterables = iterables[1:]
        else:
            return

        output = None
        while not self.end_of_page(output, iterable):
            if output is None:
                index = f'first: 20'
            else:
                index = f'after: {output}'

            new_schema = schema.replace(f'<ITER {str(iterable)}>', index)

            if 'ITER' not in new_schema:
                print('new schema', new_schema)
                res = requests.post(self.url, headers=self.headers, json={'query': new_schema})
                output = res.json()['data']

            out = self.recursive_iterable(new_schema, iterables)
            print('output', out)

            return output

    def call(self):
        schema = self.schema.replace('<NEXT_VAL>', '')
        self.recursive_iterable(schema, self.to_iter)

        # print(self.schema.replace('<NEXT_VAL>', ''))
        # print('will save', self.to_save)
        # print('will iterate over', self.to_iter)
        # # res = requests.post(self.url, headers=self.headers, json={'query': self.schema.replace('<NEXT_VAL>', '')})
        # # output = res.json()['data']
        # output = json.loads('{"repository": {"nameWithOwner": "huggingface/transformers", "issues": {"totalCount": 9843, "pageInfo": {"endCursor": "Y3Vyc29yOnYyOpHOFwK_Mw==", "hasNextPage": true}, "nodes": [{"number": 3}, {"number": 5}, {"number": 6}, {"number": 9}, {"number": 10}, {"number": 11}, {"number": 12}, {"number": 13}, {"number": 15}, {"number": 19}, {"number": 20}, {"number": 23}, {"number": 24}, {"number": 25}, {"number": 26}, {"number": 27}, {"number": 28}, {"number": 30}, {"number": 31}, {"number": 33}, {"number": 34}, {"number": 35}, {"number": 36}, {"number": 37}, {"number": 38}, {"number": 39}, {"number": 41}, {"number": 43}, {"number": 44}, {"number": 45}, {"number": 46}, {"number": 47}, {"number": 48}, {"number": 49}, {"number": 50}, {"number": 51}, {"number": 52}, {"number": 53}, {"number": 54}, {"number": 55}, {"number": 56}, {"number": 57}, {"number": 59}, {"number": 61}, {"number": 62}, {"number": 63}, {"number": 64}, {"number": 65}, {"number": 67}, {"number": 68}]}}}')
        #
        # for iterable in self.to_iter[::-1]:
        #     for selector in iterable:
        #         output = output[selector]
        #
        #     page_info = output['pageInfo']
        #
        #     print('pageInfo', page_info)
        #     # if page_info['hasNextPage']:
        #
        # return output


query = Query('GetRepository')
query.mutation('repository', owner='huggingface', name='transformers')
query.save_result('nameWithOwner')

query.iter('issues').nodes.save_result('number')
query.mutation('comments', first=100).nodes.mutation('reactions')
query.save_result('totalCount')

print(query.call())