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}" + "{ }" 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('', f"{_name}{args}" + "{ }") self.path += [_name] return self def iter(self, _name): self.path += [_name] to_replace = f"{_name} ()" + "{ totalCount pageInfo { endCursor hasNextPage} }" self.schema = self.schema.replace('', to_replace) self.to_iter.append([*self.path]) return self def save_result(self, _name): self.schema = self.schema.replace('', f"{_name} ") self.to_save.append([*self.path, _name]) return self @property def nodes(self): self.path.append('nodes') self.schema = self.schema.replace('', 'nodes { }') 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'', 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('', '') self.recursive_iterable(schema, self.to_iter) # print(self.schema.replace('', '')) # 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('', '')}) # # 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())