Add Windows and portable installation support for Python path resolution

- Add resolvePythonPath() function that handles:
  - PYTHON_PATH env var override (highest priority)
  - Portable installations (python_embeded/python.exe)
  - Standard venv with correct paths per OS:
    - Windows: .venv/Scripts/python.exe
    - Unix: .venv/bin/python
- Remove hardcoded Unix paths from acestep.ts and generate.ts
- Remove hardcoded /home/ambsd default path

Fixes "ENOENT" errors on Windows when spawning Python processes.
This commit is contained in:
fspecii
2026-02-04 04:51:58 +02:00
parent 3ff4e3e0a9
commit 645c88ca0a
2 changed files with 29 additions and 5 deletions
+3 -2
View File
@@ -14,6 +14,7 @@ import {
cleanupJob,
getJobRawResponse,
downloadAudioToBuffer,
resolvePythonPath,
} from '../services/acestep.js';
import { getStorageProvider } from '../services/storage/factory.js';
@@ -557,12 +558,12 @@ router.post('/format', authMiddleware, async (req: AuthenticatedRequest, res: Re
const { spawn } = await import('child_process');
const ACESTEP_DIR = process.env.ACESTEP_PATH || '/home/ambsd/Desktop/aceui/ACE-Step-1.5';
const ACESTEP_DIR = process.env.ACESTEP_PATH || path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../ACE-Step-1.5');
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const SCRIPTS_DIR = path.join(__dirname, '../../scripts');
const FORMAT_SCRIPT = path.join(SCRIPTS_DIR, 'format_sample.py');
const pythonPath = path.join(ACESTEP_DIR, '.venv', 'bin', 'python');
const pythonPath = resolvePythonPath(ACESTEP_DIR);
const args = [
FORMAT_SCRIPT,
+26 -3
View File
@@ -1,5 +1,6 @@
import { writeFile, mkdir, copyFile, rm, stat } from 'fs/promises';
import { writeFile, mkdir, copyFile, rm, stat, access } from 'fs/promises';
import { spawn, execSync } from 'child_process';
import { existsSync } from 'fs';
import path from 'path';
// Get audio duration using ffprobe
@@ -35,6 +36,29 @@ function resolveAceStepPath(): string {
return path.resolve(__dirname, '../../../../ACE-Step-1.5');
}
// Resolve Python path cross-platform (supports venv and portable installations)
export function resolvePythonPath(baseDir: string): string {
// Allow explicit override via env var
if (process.env.PYTHON_PATH) {
return process.env.PYTHON_PATH;
}
const isWindows = process.platform === 'win32';
const pythonExe = isWindows ? 'python.exe' : 'python';
// Check for portable installation first (python_embeded)
const portablePath = path.join(baseDir, 'python_embeded', pythonExe);
if (existsSync(portablePath)) {
return portablePath;
}
// Standard venv path (different structure on Windows vs Unix)
if (isWindows) {
return path.join(baseDir, '.venv', 'Scripts', pythonExe);
}
return path.join(baseDir, '.venv', 'bin', 'python');
}
const ACESTEP_DIR = resolveAceStepPath();
const SCRIPTS_DIR = path.join(__dirname, '../../scripts');
const PYTHON_SCRIPT = path.join(SCRIPTS_DIR, 'simple_generate.py');
@@ -431,8 +455,7 @@ interface PythonResult {
function runPythonGeneration(scriptArgs: string[]): Promise<PythonResult> {
return new Promise((resolve) => {
// Use the ACE-Step venv's Python directly
const pythonPath = path.join(ACESTEP_DIR, '.venv', 'bin', 'python');
const pythonPath = resolvePythonPath(ACESTEP_DIR);
const args = [PYTHON_SCRIPT, ...scriptArgs];
const proc = spawn(pythonPath, args, {