# PyInstaller spec for the bundled Windows node daemon. # # Output: dist/meshbay-node/meshbay-node.exe (--onedir, relocatable) # Consumed by: packaging/win/build-node-runtime.ps1, which moves the tree to # packages/meshbay-client/node-runtime/ for electron-builder to carry as an # extraResource. # # The dependency set (aiortc, av, aioquic, pydantic-core, uvicorn, watchdog, # guessit, blake3, ...) has C/Rust extensions and does dynamic imports, so # each awkward package is pulled in whole with collect_all rather than left to # PyInstaller's static analysis. Add to COLLECT_ALL / HIDDEN / COPY_META when a # frozen run raises ModuleNotFoundError — that is the expected way this list grows. from PyInstaller.utils.hooks import collect_all, copy_metadata # Packages taken in full: data files + shared libs + every submodule. COLLECT_ALL = [ "meshbay_node", "meshbay_common", "aiortc", "aioice", "aioquic", "av", "cryptography", "pylibsrtp", "pyee", "google_crc32c", "pydantic", "pydantic_core", "fastapi", "starlette", "uvicorn", "anyio", "sniffio", "h11", "websockets", "httpx", "httpcore", "watchdog", "guessit", "rebulk", "babelfish", "mutagen", "PIL", "blake3", "msgpack", "zstandard", "aiosqlite", "jwt", "dns", "tzdata", ] # importlib.metadata lookups that survive freezing only if the dist-info is copied. COPY_META = [ "meshbay-node", "meshbay-common", "guessit", "rebulk", "babelfish", "uvicorn", "fastapi", ] # Imports PyInstaller's static pass misses even with collect_all. HIDDEN = [ "uvicorn.logging", "uvicorn.loops.auto", "uvicorn.loops.asyncio", "uvicorn.protocols.http.auto", "uvicorn.protocols.http.h11_impl", "uvicorn.protocols.websockets.auto", "uvicorn.protocols.websockets.websockets_impl", "uvicorn.lifespan.on", ] datas, binaries, hiddenimports = [], [], list(HIDDEN) for pkg in COLLECT_ALL: d, b, h = collect_all(pkg) datas += d binaries += b hiddenimports += h for dist in COPY_META: datas += copy_metadata(dist) a = Analysis( ["node-entry.py"], pathex=[], binaries=binaries, datas=datas, hiddenimports=hiddenimports, hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=["tkinter", "pytest", "ruff", "piexif", "IPython"], noarchive=False, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name="meshbay-node", debug=False, bootloader_ignore_signals=False, strip=False, upx=False, console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon="../../packages/meshbay-client/build/icon.ico", ) coll = COLLECT( exe, a.binaries, a.datas, strip=False, upx=False, upx_exclude=[], name="meshbay-node", )