verify-industry-install.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """Read-only native-runtime preflight; never installs modules or changes a library pointer."""
  2. import argparse
  3. import hashlib
  4. import json
  5. from pathlib import Path
  6. import platform
  7. import sys
  8. ROOT = Path(__file__).resolve().parents[1]
  9. sys.path.insert(0, str(ROOT / 'server/voc-library'))
  10. def main():
  11. parser = argparse.ArgumentParser(description=__doc__)
  12. sources = parser.add_mutually_exclusive_group(required=True)
  13. sources.add_argument('--snapshot')
  14. sources.add_argument('--registry')
  15. sources.add_argument('--db')
  16. parser.add_argument('--voc-runtime')
  17. parser.add_argument('--monitoring-store', dest='monitoringStore')
  18. parser.add_argument('--expected-generation', required=True)
  19. args = parser.parse_args()
  20. if not args.snapshot:
  21. if not args.voc_runtime or not (Path(args.voc_runtime) / 'board_library.py').is_file():
  22. raise ValueError('EXISTING_VOC_RUNTIME_REQUIRED')
  23. sys.path.insert(0, str(Path(args.voc_runtime).resolve()))
  24. from industry_monitor import load, Monitor, run
  25. config = {k: getattr(args, k) for k in ('snapshot', 'registry', 'db', 'monitoringStore') if getattr(args, k)}
  26. data = load(config)
  27. if data['generation'] != args.expected_generation:
  28. raise ValueError('LIBRARY_VERSION_CHANGED')
  29. monitor = Monitor(data)
  30. baseline = monitor.review_coverage({'platform': 'jd', 'shopId': '1000084104'})
  31. corpus = monitor.review_research({}, {'mode': 'analysis'})
  32. probes = {}
  33. for op in ('contract', 'listings', 'reviews', 'policies', 'rankings', 'plan', 'insights'):
  34. result = run(config, {'op': op, 'generation': data['generation']})
  35. probes[op] = result.get('ok') is True and result.get('databaseWrites') == 0
  36. # Reload the binding after all reads to reject a concurrent publication.
  37. if load(config)['generation'] != args.expected_generation:
  38. raise ValueError('LIBRARY_VERSION_CHANGED')
  39. fingerprints = {}
  40. if args.voc_runtime:
  41. for filename in ('board_library.py', 'voc_db.py', 'retrieval.py', 'schema.sql'):
  42. path = Path(args.voc_runtime) / filename
  43. if path.is_file():
  44. fingerprints[filename] = hashlib.sha256(path.read_bytes().replace(b'\r\n', b'\n')).hexdigest()
  45. print(json.dumps({'ok': all(probes.values()), 'readOnly': True, 'databaseWrites': 0, 'paidCalls': 0,
  46. 'runtime': platform.python_version(), 'nativePython39Verified': sys.version_info[:2] == (3, 9),
  47. 'generation': data['generation'], 'counts': data['summary']['counts'],
  48. 'primaryStore': {k: baseline[k] for k in ('products', 'reviewRows', 'uniqueReadableTexts')},
  49. 'analysisRowsRecomputed': corpus['total'], 'probes': probes,
  50. 'existingRuntimeFingerprints': fingerprints}, ensure_ascii=False, indent=2))
  51. if __name__ == '__main__':
  52. try:
  53. main()
  54. except Exception as error:
  55. print(json.dumps({'ok': False, 'error': str(error) if isinstance(error, ValueError) else type(error).__name__,
  56. 'databaseWrites': 0, 'paidCalls': 0}))
  57. sys.exit(1)