Spaces:
Running
Running
Download code/run_queue.py from ArthurZ/transformers-triage: direct link, hf CLI and curl.
- Browser
- Download file 5.03 kB
-
https://huggingface.co/spaces/ArthurZ/transformers-triage/resolve/main/code/run_queue.py
- Command line
-
hf download hf://spaces/ArthurZ/transformers-triage/code/run_queue.py
-
curl -L -o run_queue.py https://huggingface.co/spaces/ArthurZ/transformers-triage/resolve/main/code/run_queue.py
5.03 kB
| import json, re, subprocess, sys, time, os | |
| Q = json.load(open(sys.argv[1])); LOG = sys.argv[2] if len(sys.argv) > 2 else 'final_run.log' | |
| done = set(re.findall(r'(issue|pr)#(\d+) (\w+)(?: \S+)? ok', open(LOG).read())) if os.path.exists(LOG) else set() | |
| Q = [q for q in Q if (q['kind'], str(q['n']), q['op']) not in done] | |
| N, t0, fails = len(Q), time.time(), [] | |
| log = open(LOG, 'a') | |
| def p(s): log.write(s + '\n'); log.flush() | |
| def already_posted(q): | |
| try: | |
| r = subprocess.run(['gh', q['kind'], 'view', str(q['n']), '-R', 'huggingface/transformers', '--json', 'comments,state', | |
| '--jq', '[.state, (.comments[-1].author.login // ""), (.comments[-1].body // "")]'], | |
| capture_output=True, text=True, timeout=60) | |
| st, who, body = json.loads(r.stdout) | |
| return who == 'ArthurZucker' and body.strip() == q['msg'].strip(), st | |
| except Exception: | |
| return False, None | |
| def edit_ours(q): | |
| qq = '{repository(owner:"huggingface",name:"transformers"){issueOrPullRequest(number:%d){... on Issue{comments(last:30){nodes{databaseId author{login} createdAt}}} ... on PullRequest{comments(last:30){nodes{databaseId author{login} createdAt}}}}}}' % q['n'] | |
| r = subprocess.run(['gh', 'api', 'graphql', '-f', 'query=' + qq], capture_output=True, text=True, timeout=60) | |
| nodes = json.loads(r.stdout)['data']['repository']['issueOrPullRequest']['comments']['nodes'] | |
| ours = [x for x in nodes if (x['author'] or {}).get('login') == 'ArthurZucker' and x['createdAt'] >= '2026-10-20'] | |
| if not ours: return subprocess.CompletedProcess([], 1, '', 'no close comment from 2026-10-20+ to edit') | |
| return subprocess.run(['gh', 'api', '-X', 'PATCH', f"repos/huggingface/transformers/issues/comments/{ours[-1]['databaseId']}", '-f', 'body=' + q['msg']], | |
| capture_output=True, text=True, timeout=60) | |
| for i, q in enumerate(Q, 1): | |
| if q['op'] == 'addrev': | |
| try: r = subprocess.run(['gh', 'pr', 'edit', str(q['n']), '-R', 'huggingface/transformers', '--add-reviewer', q['reviewer']], capture_output=True, text=True, timeout=60) | |
| except Exception as e: r = subprocess.CompletedProcess([], 1, '', str(e)) | |
| time.sleep(2); el = time.time() - t0 | |
| if r.returncode == 0: p(f'[{i}/{N}] {q["kind"]}#{q["n"]} addrev {q["reviewer"]} ok | elapsed {el:.0f}s') | |
| else: fails.append((q['kind'], q['n'], 'addrev: ' + (r.stderr or r.stdout)[:200])); p(f'[{i}/{N}] {q["kind"]}#{q["n"]} FAIL addrev {q["reviewer"]}: {(r.stderr or r.stdout)[:200]}') | |
| continue | |
| if q['op'] == 'edit': | |
| try: r = edit_ours(q) | |
| except Exception as e: r = subprocess.CompletedProcess([], 1, '', str(e)) | |
| time.sleep(4); el = time.time() - t0 | |
| if r.returncode == 0: p(f'[{i}/{N}] {q["kind"]}#{q["n"]} edit ok | elapsed {el:.0f}s') | |
| else: fails.append((q['kind'], q['n'], (r.stderr or r.stdout)[:200])); p(f'[{i}/{N}] {q["kind"]}#{q["n"]} FAIL: {(r.stderr or r.stdout)[:200]}') | |
| continue | |
| posted, st = already_posted(q) | |
| if posted and (q['op'] == 'comment' or st != 'OPEN'): | |
| p(f'[{i}/{N}] {q["kind"]}#{q["n"]} {q["op"]} ok (already posted) | elapsed {time.time()-t0:.0f}s'); continue | |
| cmd = ['gh', q['kind'], q['op'], str(q['n']), '-R', 'huggingface/transformers'] | |
| if q['op'] == 'close': cmd += (['-r', q['reason']] if q['kind'] == 'issue' else []) + ([] if posted else ['-c', q['msg']]) # comment already there → close only | |
| else: cmd += ['-b', q['msg']] | |
| for attempt in range(1000): | |
| try: | |
| r = subprocess.run(cmd, capture_output=True, text=True, timeout=120); out = r.stderr + r.stdout | |
| except subprocess.TimeoutExpired: | |
| p(f'[{i}/{N}] {q["kind"]}#{q["n"]} timeout, retrying in 30s'); time.sleep(30) | |
| posted, st = already_posted(q) # the timed-out call may have gone through | |
| if posted and (q['op'] == 'comment' or st != 'OPEN'): | |
| r = subprocess.CompletedProcess(cmd, 0, '', ''); break | |
| if posted and '-c' in cmd: cmd = cmd[:cmd.index('-c')] | |
| continue | |
| if r.returncode == 0: break | |
| if 'too quickly' in out or 'rate limit' in out.lower(): | |
| p(f'[{i}/{N}] {q["kind"]}#{q["n"]} rate-limited, sleeping 300s'); time.sleep(300); continue | |
| if ('Something went wrong' in out or 'timed out' in out or 'connection' in out.lower()) and attempt < 20: # transient network / GitHub 5xx | |
| time.sleep(30); continue | |
| break | |
| time.sleep(4) # ponytail: fixed spacing under GitHub's content-creation limit | |
| el = time.time() - t0 | |
| if r.returncode == 0: p(f'[{i}/{N}] {q["kind"]}#{q["n"]} {q["op"]} ok | elapsed {el:.0f}s | eta ~{el/i*(N-i):.0f}s') | |
| else: | |
| err = out.strip().replace('\n', ' ')[:200]; fails.append((q['kind'], q['n'], err)); p(f'[{i}/{N}] {q["kind"]}#{q["n"]} FAIL: {err}') | |
| p(f'done {sys.argv[1]} ok={N-len(fails)} fails={len(fails)}') | |
| json.dump(fails, open(sys.argv[1].replace('.json', '_fails.json'), 'w')) | |