-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathbuild_backend.py
More file actions
113 lines (95 loc) · 4.19 KB
/
build_backend.py
File metadata and controls
113 lines (95 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python3
"""
Script to build the Flask backend into a standalone executable using PyInstaller.
This script will be used both for local development and CI/CD.
"""
import os
import sys
import subprocess
import shutil
from pathlib import Path
def build_backend():
"""Build the Flask backend into a standalone executable."""
# Determine the project root directory (where this script and app.py are located)
script_dir = Path(__file__).parent.absolute()
project_root = script_dir
# Verify we found the correct root directory by checking for app.py
if not (project_root / 'app.py').exists():
print(f"Error: Could not find app.py in {project_root}")
return False
print(f"Project root directory: {project_root}")
# Clean up any previous build (using absolute paths)
build_dir = project_root / 'build'
dist_dir = project_root / 'dist'
if build_dir.exists():
shutil.rmtree(build_dir)
if dist_dir.exists():
shutil.rmtree(dist_dir)
# PyInstaller command (using absolute paths for data files)
init_yaml = project_root / 'init.yaml'
character_info = project_root / 'character_info.txt'
app_py = project_root / 'app.py'
cmd = [
'pyinstaller',
'--onefile',
'--name=app',
f'--add-data={init_yaml};.',
f'--add-data={character_info};.',
'--hidden-import=asyncio',
'--hidden-import=flask',
'--hidden-import=flask_cors',
str(app_py)
]
print("Building Flask backend with PyInstaller...")
print(f"Command: {' '.join(cmd)}")
print(f"Working directory: {project_root}")
try:
# Run PyInstaller from the project root directory
result = subprocess.run(cmd, check=True, capture_output=True, text=True, cwd=str(project_root))
print("PyInstaller build completed successfully!")
print(result.stdout)
# Create the backend directory for Electron (using absolute path)
backend_dir = project_root / 'ui/public/backend'
backend_dir.mkdir(parents=True, exist_ok=True)
# Copy the executable to the backend directory (using absolute path)
exe_path = dist_dir / 'app.exe'
if exe_path.exists():
shutil.copy2(exe_path, backend_dir / 'app.exe')
print(f"Copied executable to {backend_dir / 'app.exe'}")
else:
print("Warning: app.exe not found in dist/ directory")
# Copy necessary files to the backend directory (using absolute paths)
files_to_copy = [init_yaml, character_info]
for file_path in files_to_copy:
if file_path.exists():
shutil.copy2(file_path, backend_dir / file_path.name)
print(f"Copied {file_path.name} to backend directory")
else:
print(f"Warning: {file_path.name} not found")
# Create a simple test to verify the executable works
print("\nTesting the built executable...")
test_cmd = [str(backend_dir / 'app.exe'), '--help']
try:
result = subprocess.run(test_cmd, check=True, capture_output=True, text=True, timeout=30)
print("Executable test passed!")
print(f"Test output: {result.stdout}")
except subprocess.TimeoutExpired:
print("Executable test timed out after 30 seconds")
print("This may indicate an issue with the executable, but continuing with build...")
except subprocess.CalledProcessError as e:
print(f"Executable test failed with return code {e.returncode}")
print(f"stdout: {e.stdout}")
print(f"stderr: {e.stderr}")
print("Continuing with build despite test failure...")
except Exception as e:
print(f"Unexpected error during executable test: {e}")
print("Continuing with build...")
return True
except subprocess.CalledProcessError as e:
print(f"PyInstaller build failed: {e}")
print(f"stdout: {e.stdout}")
print(f"stderr: {e.stderr}")
return False
if __name__ == '__main__':
success = build_backend()
sys.exit(0 if success else 1)