# -*- mode: python ; coding: utf-8 -*- """ PyInstaller spec for 标伙伴 · AI标书助手 Build: pyinstaller bid_partner.spec 知识库改用 SQLite + 纯 Python 向量存储,已不依赖 ChromaDB,打包更小。 """ import os from PyInstaller.utils.hooks import collect_all, collect_data_files block_cipher = None # ── Collect complex packages ───────────────────────────────────────────────── openai_datas, openai_bins, openai_hidden = collect_all('openai') pydantic_datas, pydantic_bins, pydantic_hidden = collect_all('pydantic') # tiktoken data (BPE vocab files) tiktoken_datas = collect_data_files('tiktoken') a = Analysis( ['launcher.py'], pathex=['.'], binaries=openai_bins + pydantic_bins, datas=[ # ── App assets (read-only, go into _MEIPASS) ── ('templates', 'templates'), ('static', 'static'), # ── Package data ── *openai_datas, *pydantic_datas, *tiktoken_datas, ], hiddenimports=[ # Flask / Werkzeug 'flask', 'flask_cors', 'werkzeug', 'werkzeug.serving', 'werkzeug.routing', 'werkzeug.middleware.proxy_fix', 'jinja2', 'jinja2.ext', # SQLite (stdlib, always present) 'sqlite3', # OpenAI *openai_hidden, # Pydantic *pydantic_hidden, # Document processing 'PyPDF2', 'pypdf', 'pypdf.errors', 'pdfminer', 'pdfminer.high_level', 'pdfminer.layout', 'pdfminer.pdfpage', 'pdfminer.pdfinterp', 'pdfminer.converter', 'docx', 'docx.oxml', 'docx.oxml.ns', 'docx.shared', 'docx.enum', 'docx.enum.text', 'docx.enum.style', 'python_docx', # tiktoken 'tiktoken', 'tiktoken.core', 'tiktoken.model', 'tiktoken_ext', 'tiktoken_ext.openai_public', # Network / encoding 'requests', 'chardet', 'httpx', 'httpcore', 'anyio', 'anyio.streams', 'anyio.streams.memory', 'sniffio', 'certifi', # Stdlib extras 'importlib.metadata', 'importlib.resources', 'pkg_resources', 'json', 'math', 'threading', # Local project modules (explicitly include all) 'config', 'app', 'utils', 'utils.ai_client', 'utils.file_utils', 'utils.prompts', 'utils.settings', 'utils.boq_parser', 'utils.bill_analysis', 'modules', 'modules.parser', 'modules.generator', 'modules.checker', 'modules.exporter', 'modules.knowledge', ], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[ # Heavy packages not used in this app 'matplotlib', 'pandas', 'scipy', 'numpy', 'IPython', 'jupyter', 'notebook', 'PIL', 'Pillow', 'cv2', 'torch', 'tensorflow', 'pytest', 'unittest', # ChromaDB 及其依赖(已移除,改用 SQLite 内置存储) 'chromadb', 'hnswlib', 'posthog', 'pypika', 'mmh3', 'overrides', 'monotonic', 'sentence_transformers', 'onnxruntime', ], 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='bid_partner', debug=False, bootloader_ignore_signals=False, strip=False, upx=False, console=False, # no black console window — GUI launcher takes over disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=False, upx_exclude=[], name='BidPartner', )