119 lines
3.7 KiB
Python
119 lines
3.7 KiB
Python
# -*- 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',
|
||
)
|