# build.spec # Build with: pyinstaller build.spec # # Produces dist/InsightUX/ containing both: # "InsightUX Calibrate.exe" — run once per person before first use # "InsightUX Browser.exe" — the actual research browser # # MERGE() shares mediapipe/onnxruntime/opencv/torch across both builds # instead of duplicating ~500MB+ of dependencies twice. from PyInstaller.utils.hooks import collect_all block_cipher = None datas = [] binaries = [] hiddenimports = [] # mediapipe and onnxruntime both ship binary model/asset files inside their # own package data that PyInstaller won't find automatically — collect_all # is required, not optional, or the packaged app fails at runtime with # "file not found" errors deep inside those libraries. for pkg in ("mediapipe", "onnxruntime", "cv2"): d, b, h = collect_all(pkg) datas += d binaries += b hiddenimports += h # Your trained model + preprocessing package, bundled as data since they're # loaded by relative path at runtime, not imported as Python modules. datas += [ ("models", "models"), ("preprocessing", "preprocessing"), ] # torch is optional (only used for calibration fine-tuning, already wrapped # in try/except ImportError in calibrate.py) — include it only if installed # in your build environment, PyInstaller will skip it silently otherwise. try: d, b, h = collect_all("torch") datas += d binaries += b hiddenimports += h except Exception: pass common_kwargs = dict( pathex=["."], binaries=binaries, datas=datas, hiddenimports=hiddenimports, hookspath=[], runtime_hooks=[], excludes=[], cipher=block_cipher, ) calibrate_a = Analysis(["calibrate.py"], **common_kwargs) browser_a = Analysis(["browser_session.py"], **common_kwargs) MERGE( (calibrate_a, "calibrate", "InsightUX Calibrate"), (browser_a, "browser_session", "InsightUX Browser"), ) calibrate_pyz = PYZ(calibrate_a.pure, calibrate_a.zipped_data, cipher=block_cipher) browser_pyz = PYZ(browser_a.pure, browser_a.zipped_data, cipher=block_cipher) calibrate_exe = EXE( calibrate_pyz, calibrate_a.scripts, [], exclude_binaries=True, name="InsightUX Calibrate", console=True, # keep console visible — calibration prints live diagnostics icon=None, ) browser_exe = EXE( browser_pyz, browser_a.scripts, [], exclude_binaries=True, name="InsightUX Browser", console=False, # no console window for the actual end-user app icon=None, ) coll = COLLECT( calibrate_exe, calibrate_a.binaries, calibrate_a.zipfiles, calibrate_a.datas, browser_exe, browser_a.binaries, browser_a.zipfiles, browser_a.datas, strip=False, upx=False, # UPX compression on ML binaries frequently triggers AV false-positives name="InsightUX", )