Add bundled open-webui
Use pyinstaller to compile to a single bundle
This commit is contained in:
parent
3392496493
commit
3218c10063
9
.gitignore
vendored
9
.gitignore
vendored
@ -8,3 +8,12 @@ node_modules
|
|||||||
!.env.example
|
!.env.example
|
||||||
vite.config.js.timestamp-*
|
vite.config.js.timestamp-*
|
||||||
vite.config.ts.timestamp-*
|
vite.config.ts.timestamp-*
|
||||||
|
backend/.webui_secret_key
|
||||||
|
.venv
|
||||||
|
backend/build
|
||||||
|
backend/dist
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
*.pkl
|
||||||
|
1
backend/.python-version
Normal file
1
backend/.python-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.12
|
174
backend/BUILD.md
Normal file
174
backend/BUILD.md
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
# Building GlowPath Backend with PyInstaller
|
||||||
|
|
||||||
|
This directory contains everything needed to bundle the GlowPath backend into a standalone executable using PyInstaller.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The easiest way to build the application is using the provided build script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install build dependencies and create the executable
|
||||||
|
python build.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Or using make:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Requirements
|
||||||
|
|
||||||
|
- Python 3.12+
|
||||||
|
- PyInstaller 6.0+
|
||||||
|
- All dependencies from `pyproject.toml`
|
||||||
|
|
||||||
|
## Build Methods
|
||||||
|
|
||||||
|
### Method 1: Using the Build Script (Recommended)
|
||||||
|
|
||||||
|
The `build.py` script handles everything automatically:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Standard build
|
||||||
|
python build.py
|
||||||
|
|
||||||
|
# Debug build (includes debug symbols and verbose output)
|
||||||
|
python build.py --debug
|
||||||
|
|
||||||
|
# Skip dependency installation
|
||||||
|
python build.py --no-deps
|
||||||
|
|
||||||
|
# Skip cleaning previous builds
|
||||||
|
python build.py --no-clean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: Using Make
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Standard build
|
||||||
|
make build
|
||||||
|
|
||||||
|
# Debug build
|
||||||
|
make build-debug
|
||||||
|
|
||||||
|
# Quick build (no cleaning)
|
||||||
|
make quick-build
|
||||||
|
|
||||||
|
# Just clean
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 3: Manual PyInstaller
|
||||||
|
|
||||||
|
If you prefer to run PyInstaller directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies first
|
||||||
|
pip install pyinstaller pyinstaller-hooks-contrib
|
||||||
|
|
||||||
|
# Run PyInstaller
|
||||||
|
pyinstaller --clean --noconfirm glowpath-backend.spec
|
||||||
|
```
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
After a successful build, you'll find:
|
||||||
|
|
||||||
|
- `dist/glowpath-backend` - The standalone executable
|
||||||
|
- `dist/glowpath-backend-bundle/` - A complete distribution package with:
|
||||||
|
- The executable
|
||||||
|
- Startup scripts (`start.sh` or `start.bat`)
|
||||||
|
- README.txt with usage instructions
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### PyInstaller Spec File
|
||||||
|
|
||||||
|
The `glowpath-backend.spec` file contains the PyInstaller configuration. It's configured to:
|
||||||
|
|
||||||
|
- Include all open-webui dependencies and data files
|
||||||
|
- Handle complex packages like bcrypt, cryptography, etc.
|
||||||
|
- Include SSL certificates
|
||||||
|
- Exclude unnecessary packages (tkinter, matplotlib, etc.)
|
||||||
|
- Create a single-file executable
|
||||||
|
|
||||||
|
### Custom Hooks
|
||||||
|
|
||||||
|
The `hooks/` directory contains PyInstaller hooks for better package detection:
|
||||||
|
|
||||||
|
- `hook-open_webui.py` - Ensures all open-webui files are included
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Missing modules**: If you get import errors, add the missing module to `hiddenimports` in the spec file.
|
||||||
|
|
||||||
|
2. **Missing data files**: If templates or static files are missing, they may need to be added to the `datas` list.
|
||||||
|
|
||||||
|
3. **SSL certificate errors**: The spec file includes SSL certificates, but you may need to adjust the path based on your system.
|
||||||
|
|
||||||
|
4. **Large executable size**: The executable includes all dependencies. You can reduce size by:
|
||||||
|
- Adding more packages to the `excludes` list
|
||||||
|
- Using `--onedir` instead of `--onefile` (modify the spec file)
|
||||||
|
|
||||||
|
### Debug Mode
|
||||||
|
|
||||||
|
Build in debug mode to get more information about what's being included:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python build.py --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Enable PyInstaller debug output
|
||||||
|
- Include debug symbols
|
||||||
|
- Show detailed import information
|
||||||
|
|
||||||
|
### Testing the Build
|
||||||
|
|
||||||
|
After building, test the executable:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run the executable directly
|
||||||
|
./dist/glowpath-backend
|
||||||
|
|
||||||
|
# Or use the bundle
|
||||||
|
cd dist/glowpath-backend-bundle
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
### Adding Dependencies
|
||||||
|
|
||||||
|
To include additional Python packages:
|
||||||
|
|
||||||
|
1. Add them to the `additional_packages` list in `glowpath-backend.spec`
|
||||||
|
2. If they have hidden imports, add them to the `hiddenimports` list
|
||||||
|
|
||||||
|
### Changing the Executable Name
|
||||||
|
|
||||||
|
Modify the `name` parameter in the `EXE` section of the spec file.
|
||||||
|
|
||||||
|
### Creating a GUI Application
|
||||||
|
|
||||||
|
Change `console=True` to `console=False` in the `EXE` section for a GUI app (no console window).
|
||||||
|
|
||||||
|
## Performance Notes
|
||||||
|
|
||||||
|
- First build will be slower as PyInstaller analyzes all dependencies
|
||||||
|
- Subsequent builds with `--no-clean` will be faster
|
||||||
|
- The executable may take a moment to start as it unpacks dependencies
|
||||||
|
|
||||||
|
## Distribution
|
||||||
|
|
||||||
|
The bundled application is self-contained and can be distributed to machines without Python installed. The bundle includes:
|
||||||
|
|
||||||
|
- All Python dependencies
|
||||||
|
- SSL certificates
|
||||||
|
- Static files and templates
|
||||||
|
- Configuration files
|
||||||
|
|
||||||
|
Simply copy the entire `dist/glowpath-backend-bundle/` directory to the target machine.
|
60
backend/Makefile
Normal file
60
backend/Makefile
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Makefile for GlowPath Backend
|
||||||
|
|
||||||
|
.PHONY: clean build build-debug install-deps install-project-deps install-all-deps dist help
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: build
|
||||||
|
|
||||||
|
# Install project dependencies
|
||||||
|
install-project-deps:
|
||||||
|
@echo "Installing project dependencies..."
|
||||||
|
@uv sync
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
install-deps:
|
||||||
|
@echo "Installing build dependencies..."
|
||||||
|
@uv sync --group dev
|
||||||
|
|
||||||
|
# Install all dependencies (project + build)
|
||||||
|
install-all-deps:
|
||||||
|
@echo "Installing all dependencies..."
|
||||||
|
@uv sync --all-groups
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
@echo "Cleaning build artifacts..."
|
||||||
|
@rm -rf build dist __pycache__ *.pyc
|
||||||
|
@find . -name "*.pyc" -delete
|
||||||
|
@find . -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
build: install-all-deps clean
|
||||||
|
@echo "Building GlowPath backend..."
|
||||||
|
@uv run python build.py
|
||||||
|
|
||||||
|
# Build in debug mode
|
||||||
|
build-debug: install-all-deps clean
|
||||||
|
@echo "Building GlowPath backend in debug mode..."
|
||||||
|
@uv run python build.py --debug
|
||||||
|
|
||||||
|
# Quick build without cleaning
|
||||||
|
quick-build:
|
||||||
|
@echo "Quick building GlowPath backend..."
|
||||||
|
@uv run python build.py --no-clean
|
||||||
|
|
||||||
|
# Create distribution package
|
||||||
|
dist: build
|
||||||
|
@echo "Distribution package created in dist/ directory"
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
help:
|
||||||
|
@echo "Available targets:"
|
||||||
|
@echo " build - Install all deps, clean and build the application"
|
||||||
|
@echo " build-debug - Build in debug mode"
|
||||||
|
@echo " quick-build - Build without cleaning"
|
||||||
|
@echo " clean - Clean build artifacts"
|
||||||
|
@echo " install-deps - Install build dependencies (PyInstaller)"
|
||||||
|
@echo " install-project-deps - Install project dependencies"
|
||||||
|
@echo " install-all-deps - Install all dependencies (project + build)"
|
||||||
|
@echo " dist - Create distribution package"
|
||||||
|
@echo " help - Show this help message"
|
0
backend/README.md
Normal file
0
backend/README.md
Normal file
180
backend/build.py
Executable file
180
backend/build.py
Executable file
@ -0,0 +1,180 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Build script for bundling GlowPath backend with PyInstaller.
|
||||||
|
This script handles the entire build process including dependency installation and cleanup.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(cmd, cwd=None, check=True):
|
||||||
|
"""Run a command and return the result."""
|
||||||
|
print(f"Running: {' '.join(cmd)}")
|
||||||
|
result = subprocess.run(cmd, cwd=cwd, check=check, capture_output=True, text=True)
|
||||||
|
if result.stdout:
|
||||||
|
print(result.stdout)
|
||||||
|
if result.stderr:
|
||||||
|
print(result.stderr, file=sys.stderr)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def clean_build():
|
||||||
|
"""Clean previous build artifacts."""
|
||||||
|
print("Cleaning previous build artifacts...")
|
||||||
|
dirs_to_clean = ["build", "dist", "__pycache__"]
|
||||||
|
files_to_clean = ["*.pyc"]
|
||||||
|
|
||||||
|
for dir_name in dirs_to_clean:
|
||||||
|
if os.path.exists(dir_name):
|
||||||
|
print(f"Removing {dir_name}")
|
||||||
|
shutil.rmtree(dir_name)
|
||||||
|
|
||||||
|
# Clean .pyc files
|
||||||
|
for root, dirs, files in os.walk("."):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".pyc"):
|
||||||
|
os.remove(os.path.join(root, file))
|
||||||
|
|
||||||
|
|
||||||
|
def install_dependencies():
|
||||||
|
"""Install build dependencies."""
|
||||||
|
print("Installing build dependencies...")
|
||||||
|
try:
|
||||||
|
# Try uv first (faster) - sync dev dependencies
|
||||||
|
run_command(["uv", "sync", "--group", "dev"])
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
# Fallback to pip
|
||||||
|
run_command(
|
||||||
|
[
|
||||||
|
sys.executable,
|
||||||
|
"-m",
|
||||||
|
"pip",
|
||||||
|
"install",
|
||||||
|
"pyinstaller",
|
||||||
|
"pyinstaller-hooks-contrib",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build_executable(debug=False):
|
||||||
|
"""Build the executable using PyInstaller."""
|
||||||
|
print("Building executable with PyInstaller...")
|
||||||
|
|
||||||
|
cmd = ["pyinstaller"]
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
cmd.extend(["--debug", "all"])
|
||||||
|
|
||||||
|
cmd.extend(["--clean", "--noconfirm", "glowpath-backend.spec"])
|
||||||
|
|
||||||
|
run_command(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def create_distribution():
|
||||||
|
"""Create a distribution package."""
|
||||||
|
print("Creating distribution package...")
|
||||||
|
|
||||||
|
dist_dir = Path("dist")
|
||||||
|
if not dist_dir.exists():
|
||||||
|
print("No dist directory found. Build may have failed.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Create a distribution folder with all necessary files
|
||||||
|
app_name = "glowpath-backend"
|
||||||
|
bundle_dir = dist_dir / f"{app_name}-bundle"
|
||||||
|
|
||||||
|
if bundle_dir.exists():
|
||||||
|
shutil.rmtree(bundle_dir)
|
||||||
|
|
||||||
|
bundle_dir.mkdir()
|
||||||
|
|
||||||
|
# Copy the executable
|
||||||
|
exe_path = dist_dir / app_name
|
||||||
|
if exe_path.exists():
|
||||||
|
if sys.platform == "win32":
|
||||||
|
exe_path = exe_path.with_suffix(".exe")
|
||||||
|
shutil.copy2(exe_path, bundle_dir)
|
||||||
|
|
||||||
|
# Create a simple startup script
|
||||||
|
if sys.platform != "win32":
|
||||||
|
startup_script = bundle_dir / "start.sh"
|
||||||
|
startup_script.write_text(
|
||||||
|
f"""#!/bin/bash
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
./{app_name} "$@"
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
startup_script.chmod(0o755)
|
||||||
|
else:
|
||||||
|
startup_script = bundle_dir / "start.bat"
|
||||||
|
startup_script.write_text(
|
||||||
|
f"""@echo off
|
||||||
|
cd /d "%~dp0"
|
||||||
|
{app_name}.exe %*
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create README
|
||||||
|
readme = bundle_dir / "README.txt"
|
||||||
|
readme.write_text(
|
||||||
|
f"""GlowPath Backend
|
||||||
|
===============
|
||||||
|
|
||||||
|
This is a bundled version of the GlowPath backend application.
|
||||||
|
|
||||||
|
To run the application:
|
||||||
|
- On Unix/Linux/macOS: ./start.sh
|
||||||
|
- On Windows: start.bat
|
||||||
|
- Or run the executable directly: ./{app_name}{"" if sys.platform != "win32" else ".exe"}
|
||||||
|
|
||||||
|
The application will start a web server. Check the console output for the URL to access the interface.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Distribution package created in: {bundle_dir}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Build GlowPath backend executable")
|
||||||
|
parser.add_argument("--debug", action="store_true", help="Build in debug mode")
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-clean", action="store_true", help="Skip cleaning build artifacts"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-deps", action="store_true", help="Skip installing dependencies"
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not args.no_clean:
|
||||||
|
clean_build()
|
||||||
|
|
||||||
|
if not args.no_deps:
|
||||||
|
install_dependencies()
|
||||||
|
|
||||||
|
build_executable(debug=args.debug)
|
||||||
|
|
||||||
|
if create_distribution():
|
||||||
|
print("\n✅ Build completed successfully!")
|
||||||
|
print(f"Executable and bundle available in the 'dist' directory")
|
||||||
|
else:
|
||||||
|
print("\n❌ Build failed!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"\n❌ Build failed with error: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n⚠️ Build interrupted by user")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
125
backend/glowpath-backend.spec
Normal file
125
backend/glowpath-backend.spec
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
from PyInstaller.utils.hooks import collect_all, collect_data_files, collect_submodules
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Collect all open-webui files and dependencies
|
||||||
|
datas = []
|
||||||
|
binaries = []
|
||||||
|
hiddenimports = []
|
||||||
|
|
||||||
|
# Collect open-webui and its dependencies
|
||||||
|
tmp_ret = collect_all('open_webui')
|
||||||
|
datas += tmp_ret[0]
|
||||||
|
binaries += tmp_ret[1]
|
||||||
|
hiddenimports += tmp_ret[2]
|
||||||
|
|
||||||
|
# Collect additional packages that might have data files or hidden imports
|
||||||
|
additional_packages = [
|
||||||
|
'bcrypt',
|
||||||
|
'cryptography',
|
||||||
|
'passlib',
|
||||||
|
'fastapi',
|
||||||
|
'uvicorn',
|
||||||
|
'pydantic',
|
||||||
|
'sqlalchemy',
|
||||||
|
'alembic',
|
||||||
|
'jinja2',
|
||||||
|
'aiofiles',
|
||||||
|
'python_multipart',
|
||||||
|
'httpx',
|
||||||
|
'requests',
|
||||||
|
'websockets',
|
||||||
|
'sse_starlette',
|
||||||
|
'chromadb',
|
||||||
|
]
|
||||||
|
|
||||||
|
for package in additional_packages:
|
||||||
|
try:
|
||||||
|
tmp_ret = collect_all(package)
|
||||||
|
datas += tmp_ret[0]
|
||||||
|
binaries += tmp_ret[1]
|
||||||
|
hiddenimports += tmp_ret[2]
|
||||||
|
except ImportError:
|
||||||
|
print(f"Warning: Package {package} not found, skipping...")
|
||||||
|
|
||||||
|
# Additional hidden imports that might be needed
|
||||||
|
hiddenimports += [
|
||||||
|
'uvicorn.main',
|
||||||
|
'uvicorn.protocols.http.auto',
|
||||||
|
'uvicorn.protocols.websockets.auto',
|
||||||
|
'uvicorn.lifespan.on',
|
||||||
|
'uvicorn.loops.auto',
|
||||||
|
'uvicorn.logging',
|
||||||
|
'fastapi.middleware.cors',
|
||||||
|
'fastapi.responses',
|
||||||
|
'passlib.handlers.bcrypt',
|
||||||
|
'passlib.handlers.pbkdf2',
|
||||||
|
'cryptography.hazmat.backends.openssl',
|
||||||
|
'sqlalchemy.dialects.sqlite',
|
||||||
|
'sqlalchemy.pool',
|
||||||
|
'alembic.runtime.migration',
|
||||||
|
'email_validator',
|
||||||
|
'chromadb.utils.embedding_functions.onnx_mini_lm_l6_v2',
|
||||||
|
'chromadb.utils.embedding_functions',
|
||||||
|
'chromadb.config',
|
||||||
|
'chromadb.db',
|
||||||
|
'chromadb.db.impl',
|
||||||
|
'onnxruntime',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Include SSL certificates
|
||||||
|
import ssl
|
||||||
|
ssl_paths = ssl.get_default_verify_paths()
|
||||||
|
if ssl_paths.cafile:
|
||||||
|
datas.append((ssl_paths.cafile, 'certifi'))
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['main.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=binaries,
|
||||||
|
datas=datas,
|
||||||
|
hiddenimports=hiddenimports,
|
||||||
|
hookspath=['hooks'],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[
|
||||||
|
'tkinter',
|
||||||
|
'matplotlib',
|
||||||
|
'IPython',
|
||||||
|
'jupyter',
|
||||||
|
'notebook',
|
||||||
|
'test',
|
||||||
|
'tests',
|
||||||
|
],
|
||||||
|
noarchive=False,
|
||||||
|
optimize=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove duplicate entries
|
||||||
|
a.datas = list(set(a.datas))
|
||||||
|
a.binaries = list(set(a.binaries))
|
||||||
|
|
||||||
|
pyz = PYZ(a.pure)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.datas,
|
||||||
|
[],
|
||||||
|
name='glowpath-backend',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=True,
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
icon=None,
|
||||||
|
)
|
33
backend/hooks/hook-open_webui.py
Normal file
33
backend/hooks/hook-open_webui.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
"""
|
||||||
|
PyInstaller hook for open-webui package.
|
||||||
|
This hook ensures all necessary files and modules are included in the bundle.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from PyInstaller.utils.hooks import (
|
||||||
|
collect_data_files,
|
||||||
|
collect_submodules,
|
||||||
|
collect_dynamic_libs,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Collect all submodules
|
||||||
|
hiddenimports = collect_submodules("open_webui")
|
||||||
|
|
||||||
|
# Collect data files (templates, static files, etc.)
|
||||||
|
datas = collect_data_files("open_webui")
|
||||||
|
|
||||||
|
# Collect any dynamic libraries
|
||||||
|
binaries = collect_dynamic_libs("open_webui")
|
||||||
|
|
||||||
|
# Add specific hidden imports that might be missed
|
||||||
|
hiddenimports += [
|
||||||
|
"open_webui.main",
|
||||||
|
"open_webui.apps",
|
||||||
|
"open_webui.config",
|
||||||
|
"open_webui.constants",
|
||||||
|
"open_webui.utils",
|
||||||
|
"open_webui.models",
|
||||||
|
"uvicorn.protocols.http.auto",
|
||||||
|
"uvicorn.protocols.websockets.auto",
|
||||||
|
"uvicorn.lifespan.on",
|
||||||
|
"uvicorn.loops.auto",
|
||||||
|
]
|
5
backend/main.py
Normal file
5
backend/main.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from open_webui import app
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app()
|
15
backend/pyproject.toml
Normal file
15
backend/pyproject.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[project]
|
||||||
|
name = "glowpath-backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = [
|
||||||
|
"open-webui>=0.6.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
|
"pyinstaller>=6.14.1",
|
||||||
|
"pyinstaller-hooks-contrib>=2025.5",
|
||||||
|
]
|
6191
backend/uv.lock
generated
Normal file
6191
backend/uv.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user