workshop-self-run-evidence.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. """Bounded read-only research requests for one local workshop rehearsal."""
  2. import argparse
  3. import datetime
  4. import hashlib
  5. import json
  6. from pathlib import Path
  7. import urllib.error
  8. import urllib.request
  9. ROOT = Path(__file__).resolve().parents[1]
  10. WORK = ROOT / 'work/workshop-self-run-20261110'
  11. EVIDENCE = WORK / 'evidence'
  12. GENERATION = '82b104fc024b49a75d2f5376bf9778ced6f63a9433b5fc5a6daa3c458d05d5ea'
  13. def read(name, endpoint, body):
  14. assert endpoint in ('library', 'industry')
  15. assert body['op'] in {'summary', 'version', 'browse', 'detail', 'contract', 'overview', 'policies', 'rankings', 'workshop'}
  16. EVIDENCE.mkdir(parents=True, exist_ok=True)
  17. target = EVIDENCE / (name + '.json')
  18. assert not target.exists(), 'Evidence is immutable; use another request name'
  19. request = {**body}
  20. if body['op'] not in ('summary', 'version', 'contract'):
  21. request['generation'] = GENERATION
  22. url = 'https://kangshifu.fmode.cn/api/' + endpoint
  23. req = urllib.request.Request(url, data=json.dumps(request, ensure_ascii=False).encode(),
  24. headers={'Content-Type': 'application/json'}, method='POST')
  25. try:
  26. response = urllib.request.urlopen(req, timeout=40)
  27. except urllib.error.HTTPError as error:
  28. response = error
  29. raw = response.read()
  30. target.write_bytes(raw)
  31. data = json.loads(raw)
  32. receipt = {'name': name, 'requestedAt': datetime.datetime.now(datetime.timezone.utc).isoformat(),
  33. 'url': url, 'request': request, 'httpStatus': response.code,
  34. 'responseSha256': hashlib.sha256(raw).hexdigest(), 'bytes': len(raw),
  35. 'ok': data.get('ok'), 'generation': data.get('generation'),
  36. 'readOnly': data.get('readOnly'), 'databaseWrites': data.get('databaseWrites'),
  37. 'error': data.get('error')}
  38. (EVIDENCE / (name + '.request.json')).write_text(json.dumps(receipt, ensure_ascii=False, indent=2), encoding='utf-8')
  39. assert not data.get('ok') or data.get('readOnly') is True and data.get('databaseWrites') == 0
  40. print(json.dumps(receipt, ensure_ascii=False))
  41. return data
  42. if __name__ == '__main__':
  43. p = argparse.ArgumentParser(description=__doc__)
  44. p.add_argument('name')
  45. p.add_argument('endpoint', choices=['library', 'industry'])
  46. p.add_argument('request_json')
  47. args = p.parse_args()
  48. read(args.name, args.endpoint, json.loads(args.request_json))