Files
voicebox/backend/server.py
James Pine a69c216794 fix: address review feedback on CUDA backend swap
- Use YAML block scalar for inline run with colons (build-cuda.yml)
- Explicitly set VOICEBOX_BACKEND_VARIANT=cpu instead of setdefault (server.py)
- Use Path.replace() for atomic move on all platforms (cuda_download.py)
- Log actual exception in checksum fetch warning (cuda_download.py)
2026-03-13 00:20:05 -07:00

112 lines
3.6 KiB
Python

"""
Entry point for PyInstaller-bundled voicebox server.
This module provides an entry point that works with PyInstaller by using
absolute imports instead of relative imports.
"""
import sys
import logging
# Set up logging FIRST, before any imports that might fail
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
stream=sys.stderr, # Log to stderr so it's captured by Tauri
)
logger = logging.getLogger(__name__)
# Log startup immediately to confirm binary execution
logger.info("=" * 60)
logger.info("voicebox-server starting up...")
logger.info(f"Python version: {sys.version}")
logger.info(f"Executable: {sys.executable}")
logger.info(f"Arguments: {sys.argv}")
logger.info("=" * 60)
try:
logger.info("Importing argparse...")
import argparse
logger.info("Importing uvicorn...")
import uvicorn
logger.info("Standard library imports successful")
# Import the FastAPI app from the backend package
logger.info("Importing backend.config...")
from backend import config
logger.info("Importing backend.database...")
from backend import database
logger.info("Importing backend.main (this may take a while due to torch/transformers)...")
from backend.main import app
logger.info("Backend imports successful")
except Exception as e:
logger.error(f"Failed to import required modules: {e}", exc_info=True)
sys.exit(1)
if __name__ == "__main__":
try:
parser = argparse.ArgumentParser(description="voicebox backend server")
parser.add_argument(
"--host",
type=str,
default="127.0.0.1",
help="Host to bind to (use 0.0.0.0 for remote access)",
)
parser.add_argument(
"--port",
type=int,
default=8000,
help="Port to bind to",
)
parser.add_argument(
"--data-dir",
type=str,
default=None,
help="Data directory for database, profiles, and generated audio",
)
parser.add_argument(
"--version",
action="store_true",
help="Print version and exit",
)
args = parser.parse_args()
if args.version:
from backend import __version__
print(f"voicebox-server {__version__}")
sys.exit(0)
# Detect backend variant from binary name
# voicebox-server-cuda → sets VOICEBOX_BACKEND_VARIANT=cuda
import os
binary_name = os.path.basename(sys.executable).lower()
if "cuda" in binary_name:
os.environ["VOICEBOX_BACKEND_VARIANT"] = "cuda"
logger.info("Backend variant: CUDA")
else:
os.environ["VOICEBOX_BACKEND_VARIANT"] = "cpu"
logger.info("Backend variant: CPU")
logger.info(f"Parsed arguments: host={args.host}, port={args.port}, data_dir={args.data_dir}")
# Set data directory if provided
if args.data_dir:
logger.info(f"Setting data directory to: {args.data_dir}")
config.set_data_dir(args.data_dir)
# Initialize database after data directory is set
logger.info("Initializing database...")
database.init_db()
logger.info("Database initialized successfully")
logger.info(f"Starting uvicorn server on {args.host}:{args.port}...")
uvicorn.run(
app,
host=args.host,
port=args.port,
log_level="info",
)
except Exception as e:
logger.error(f"Server startup failed: {e}", exc_info=True)
sys.exit(1)