Created
December 7, 2018 04:49
-
-
Save abulka/04e9ec68f3a782b044c7f6f9af3bd0c4 to your computer and use it in GitHub Desktop.
bootstrapping code for launching python from electron when packaged inside pyinstaller directory structure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { app, BrowserWindow, Menu, MenuItem, globalShortcut } from 'electron'; | |
const {ipcMain} = require('electron'); // do not use ipcRenderer in main process, use ipcMain | |
const path = require('path') | |
const url = require('url') | |
const log = require('electron-log'); // https://www.npmjs.com/package/electron-log | |
const sh = require("shelljs"); // https://github.com/shelljs/shelljs | |
log.transports.file.level = 'debug'; // transports: console and file, levels: error, warn, info, verbose, debug, silly | |
log.transports.console.level = 'warn'; | |
log.debug('--------------------- APP START -------------------------------') | |
log.debug('index.js main process') | |
log.debug('cwd is', sh.pwd().stdout); | |
// DEPLOYMENT SUPPORT | |
const PY_DIST_FOLDER = '../dist' // now lives above | |
const PY_FOLDER = '..' | |
const PY_MODULE = 'api_pythermal' // without .py suffix | |
const guessPackaged = () => { | |
const fullPath = path.join(__dirname, PY_DIST_FOLDER) | |
// console.log('looking for dist directory here', fullPath) | |
// log.info('looking for dist directory here', fullPath) | |
return require('fs').existsSync(fullPath) | |
} | |
const createPyProc = () => { | |
let script = getScriptPath() | |
let port = '' + selectPort() | |
// console.log('script', script, 'port', port, 'guessPackaged', guessPackaged()) | |
log.debug('script', script, 'port', port, 'guessPackaged', guessPackaged()) | |
// enhancement to provide Python with critical env vars | |
let extra_env = { | |
NODE_ENV: 'production', | |
LANG: 'en_AU.UTF-8', | |
PYTHONUNBUFFERED: '1', | |
PYTHONDONTWRITEBYTECODE: '1', | |
EXAMPLE_VAR: 'hey there' | |
} | |
// makes a copy of existing env, such that it is, and adds to it | |
let options = { | |
env : Object.assign({}, process.env, extra_env), | |
cwd: sh.pwd().stdout | |
} | |
if (guessPackaged()) { | |
pyProc = require('child_process').execFile(script, [port], options) | |
} | |
else { | |
delete options.NODE_ENV; // don't want in production | |
let python_path = sh.which('python').stdout // this will return null if no python found | |
log.debug('which virtual python', python_path) | |
pyProc = require('child_process').spawn(python_path, [script, port], options) | |
} | |
if (pyProc != null) { | |
// console.log('child process success on port ' + port) | |
log.debug('child process success on port ' + port) | |
} | |
pyProc.stdout.on('data', function (data) { | |
// console.log('stdout: ' + data.toString()); | |
log.debug('stdout: ' + data.toString().trim()); | |
}); | |
pyProc.stderr.on('data', function (data) { | |
// console.log('stderr: ' + data.toString()); | |
log.debug('stderr: ' + data.toString().trim()); | |
}); | |
pyProc.on('exit', function (code) { | |
if (code == null) | |
log.debug('python exited with null code - WTF?') | |
else { | |
// console.log('child process exited with code ' + code.toString()); | |
log.debug('child process exited with code ' + code.toString()); | |
} | |
python_is_dead = true // just in case need to send before main render windows set up | |
if (mainWindow == null) | |
log.debug('Cannot send a message to renderer window that python has exited') | |
else | |
mainWindow.webContents.send('python_exited_notice') // for all other cases | |
}); | |
} | |
const exitPyProc = () => { | |
pyProc.kill() | |
pyProc = null | |
pyPort = null | |
} | |
app.on('ready', createPyProc) | |
app.on('will-quit', exitPyProc) | |
const getScriptPath = () => { | |
if (!guessPackaged()) { | |
return path.join(__dirname, PY_FOLDER, PY_MODULE + '.py') | |
} | |
if (process.platform === 'win32') { | |
return path.join(__dirname, PY_DIST_FOLDER, PY_MODULE, PY_MODULE + '.exe') | |
} | |
return path.join(__dirname, PY_DIST_FOLDER, PY_MODULE, PY_MODULE) | |
} | |
// .... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment