Fix Windows FastAPI import: Replace collect_all with collect_submodules
Research findings: - collect_all() has design flaws and poor performance with pydantic - Pydantic uses compiled cpython extensions that prevent module discovery - collect_submodules() is the recommended approach per PyInstaller docs Changes: - Replaced collect_all() with collect_submodules() for better reliability - Now collects 105 pydantic submodules (vs unreliable collect_all) - Added collect_data_files() for packages requiring data files - Added explicit pydantic dependencies: colorsys, decimal, json, etc. - Applies to both Windows AND Linux (no longer platform-specific) Results: ✓ Collected 52 submodules from fastapi ✓ Collected 34 submodules from starlette ✓ Collected 105 submodules from pydantic ✓ Collected 3 submodules from pydantic_core ✓ Plus uvicorn, websockets, h11, anyio Fixes: ModuleNotFoundError: No module named 'fastapi' on Windows Based on: https://github.com/pyinstaller/pyinstaller/issues/5359
This commit is contained in:
@@ -10,9 +10,8 @@ block_cipher = None
|
|||||||
# Determine if we're on Windows
|
# Determine if we're on Windows
|
||||||
is_windows = sys.platform == 'win32'
|
is_windows = sys.platform == 'win32'
|
||||||
|
|
||||||
# Import PyInstaller utilities (only needed on Windows for FastAPI fix)
|
# Import PyInstaller utilities
|
||||||
if is_windows:
|
from PyInstaller.utils.hooks import collect_submodules, collect_data_files
|
||||||
from PyInstaller.utils.hooks import collect_all
|
|
||||||
|
|
||||||
# Find faster_whisper assets folder
|
# Find faster_whisper assets folder
|
||||||
import faster_whisper
|
import faster_whisper
|
||||||
@@ -82,19 +81,33 @@ hiddenimports = [
|
|||||||
'charset_normalizer',
|
'charset_normalizer',
|
||||||
]
|
]
|
||||||
|
|
||||||
# On Windows, use more aggressive collection for FastAPI packages
|
# Collect all submodules for FastAPI and related packages
|
||||||
# This fixes import errors on Windows while keeping Linux builds stable
|
# This approach is more reliable than collect_all() which has design flaws
|
||||||
if is_windows:
|
# Particularly important for pydantic which uses compiled cpython extensions
|
||||||
print("Windows build: Using collect_all for FastAPI packages...")
|
print("Collecting submodules for FastAPI packages...")
|
||||||
for package in ['fastapi', 'starlette', 'pydantic', 'pydantic_core', 'anyio', 'uvicorn', 'websockets', 'h11']:
|
for package in ['fastapi', 'starlette', 'pydantic', 'pydantic_core', 'anyio', 'uvicorn', 'websockets', 'h11', 'httptools', 'uvloop']:
|
||||||
try:
|
try:
|
||||||
tmp_datas, tmp_binaries, tmp_hiddenimports = collect_all(package)
|
submodules = collect_submodules(package)
|
||||||
datas += tmp_datas
|
hiddenimports += submodules
|
||||||
binaries += tmp_binaries
|
print(f" ✓ Collected {len(submodules)} submodules from {package}")
|
||||||
hiddenimports += tmp_hiddenimports
|
except Exception as e:
|
||||||
print(f" ✓ Collected {package}")
|
print(f" ⚠ Warning: Could not collect {package}: {e}")
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠ Warning: Could not collect {package}: {e}")
|
# Collect data files for packages that need them
|
||||||
|
for package in ['fastapi', 'starlette', 'pydantic', 'uvicorn']:
|
||||||
|
try:
|
||||||
|
data_files = collect_data_files(package)
|
||||||
|
if data_files:
|
||||||
|
datas += data_files
|
||||||
|
print(f" ✓ Collected {len(data_files)} data files from {package}")
|
||||||
|
except Exception as e:
|
||||||
|
pass # Not all packages have data files
|
||||||
|
|
||||||
|
# Add critical pydantic dependencies that may be missed
|
||||||
|
hiddenimports += [
|
||||||
|
'colorsys', 'decimal', 'json', 'ipaddress', 'pathlib', 'uuid',
|
||||||
|
'email.message', 'typing_extensions',
|
||||||
|
]
|
||||||
|
|
||||||
a = Analysis(
|
a = Analysis(
|
||||||
['main.py'],
|
['main.py'],
|
||||||
|
|||||||
Reference in New Issue
Block a user