# -*- mode: python ; coding: utf-8 -*- """PyInstaller spec file for Local Transcription app.""" import sys from pathlib import Path import os block_cipher = None # Determine if we're on Windows is_windows = sys.platform == 'win32' # Import PyInstaller utilities (only needed on Windows for FastAPI fix) if is_windows: from PyInstaller.utils.hooks import collect_all # Find faster_whisper assets folder import faster_whisper faster_whisper_path = os.path.dirname(faster_whisper.__file__) vad_assets_path = os.path.join(faster_whisper_path, 'assets') # Base configuration binaries = [] datas = [ ('config/default_config.yaml', 'config'), (vad_assets_path, 'faster_whisper/assets'), # Include VAD model ] hiddenimports = [ 'PySide6.QtCore', 'PySide6.QtWidgets', 'PySide6.QtGui', 'faster_whisper', 'faster_whisper.transcribe', 'faster_whisper.vad', 'ctranslate2', 'sounddevice', 'noisereduce', 'webrtcvad', 'scipy', 'scipy.signal', 'numpy', # FastAPI and dependencies 'fastapi', 'fastapi.routing', 'fastapi.responses', 'starlette', 'starlette.applications', 'starlette.routing', 'starlette.responses', 'starlette.websockets', 'starlette.middleware', 'starlette.middleware.cors', 'pydantic', 'pydantic.fields', 'pydantic.main', 'anyio', 'anyio._backends', 'anyio._backends._asyncio', 'sniffio', # Uvicorn and dependencies 'uvicorn', 'uvicorn.logging', 'uvicorn.loops', 'uvicorn.loops.auto', 'uvicorn.protocols', 'uvicorn.protocols.http', 'uvicorn.protocols.http.auto', 'uvicorn.protocols.http.h11_impl', 'uvicorn.protocols.websockets', 'uvicorn.protocols.websockets.auto', 'uvicorn.protocols.websockets.wsproto_impl', 'uvicorn.lifespan', 'uvicorn.lifespan.on', 'h11', 'websockets', 'websockets.legacy', 'websockets.legacy.server', # Requests (for server sync) 'requests', 'urllib3', 'certifi', 'charset_normalizer', ] # On Windows, use more aggressive collection for FastAPI packages # This fixes import errors on Windows while keeping Linux builds stable if is_windows: print("Windows build: Using collect_all for FastAPI packages...") for package in ['fastapi', 'starlette', 'pydantic', 'pydantic_core', 'anyio', 'uvicorn', 'websockets', 'h11']: try: tmp_datas, tmp_binaries, tmp_hiddenimports = collect_all(package) datas += tmp_datas binaries += tmp_binaries hiddenimports += tmp_hiddenimports print(f" ✓ Collected {package}") except Exception as e: print(f" ⚠ Warning: Could not collect {package}: {e}") a = Analysis( ['main.py'], pathex=[], binaries=binaries, datas=datas, hiddenimports=hiddenimports, hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='LocalTranscription', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True, # Set to False to hide console window disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon=None, # Add icon file path here if you have one ) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='LocalTranscription', )