Code Monkey home page Code Monkey logo

electron-python-example's Introduction

Electron as GUI of Python Applications (Updated)

tl;dr

This post shows how to use Electron as the GUI component of Python applications. (Updated version of one of my previous posts.) The frontend and backend communicate with each other using zerorpc. The complete code is on GitHub repo.

important notice

Disclaimer on Dec 2019: This article was originally written in 2017, and I haven't updated or maintained this repo for a long time. Right now (Dec 2019), the code in this article may be outdated, and may or may not be working!!!

The following are copied from my original post. They should be the same. If there are inconsistencies, the README.md on the GitHub repo is more accurate.

original post and debates

attention

The current post is a updated version of the previous post a few years before. Readers do NOT need to read the previous post if haven't.

debates

I didn't expect that the previous post attracted so many visitors. Some other people even posted it on Hacker News and Reddit. The previous post also attracted some criticisms. Here I would like to share my replies to some debates.

Do you know Tkinter, GTK, QT (PySide and PyQT), wxPython, Kivy, thrust, ...?

Yes, I know at least their existences and try a few of them. I still think QT is the best among them. BTW, pyotherside is one of the actively maintaining bindings for Python. I am just offering another "web technology oriented" way here.

... And cefpython.

It's more or less be in "lower level" than where Electron is. For example, PySide is based on it.

I can directly write things in JavaScript!

Correct. Unless some libraries such as numpy are not available in JS. Moreover, the original intention is using Electron / JavaScript / web technologies to enhance Python Applications.

I can use QT WebEngine.

Go ahead and give it a try. But since you are using "web engine", why not also give Electron a try?

You have two runtimes!

Yes. One for JavaScript and one for Python. Unfortunately, Python and JavaScript are dynamic languages, which usually need run-time support.

the architectures and the choice

In the previous post, I showed an example architecture: Python to build up a localhost server, then Electron is just a local web browser.

start
 |
 V
+------------+
|            | start
|            +-------------> +-------------------+
|  electron  | sub process   |                   |
|            |               | python web server |
| (basically |     http      |                   |
|  browser)  | <-----------> | (business logic)  |
|            | communication |                   |
|            |               | (all html/css/js) |
|            |               |                   |
+------------+               +-------------------+

That is just one not-so-efficient solution.

Let's reconsider the core needs here: we have a Python application, and a Node.js application (Electron). How to combine them and communicate with each other?

We actually need an interprocess communication (IPC) mechanism. It is unavoidable unless Python and JavaScript have direct FFI for each other.

HTTP is merely one of the popular ways to implement IPC, and it was merely the first thing came up to my mind when I was writing the previous post.

We have more choices.

We can (and should) use socket. Then, based on that, we want an abstract messaging layer that could be implemented with ZeroMq that is one of the best messaging libraries. Moreover, based on that, we need to define some schema upon raw data that could be implemented with zerorpc.

(Luckily, zerorpc fits our needs here because it supports Python and Node.js. For more general languages support, check out gRPC.)

Thus, in this post, I will show another example using zerorpc for communication as follows, which should be more efficient than what I showed in my previous post.

start
 |
 V
+--------------------+
|                    | start
|  electron          +-------------> +------------------+
|                    | sub process   |                  |
| (browser)          |               | python server    |
|                    |               |                  |
| (all html/css/js)  |               | (business logic) |
|                    |   zerorpc     |                  |
| (node.js runtime,  | <-----------> | (zeromq server)  |
|  zeromq client)    | communication |                  |
|                    |               |                  |
+--------------------+               +------------------+

preparation

Attention: the example could be successfully run on my Windows 10 machine with Python 3.6, Electron 1.7, Node.js v6.

We need the python application, python, pip, node, npm, available in command line. For using zerorpc, we also need the C/C++ compilers (cc and c++ in the command line, and/or MSVC on Windows).

The structure of this project is

.
|-- index.html
|-- main.js
|-- package.json
|-- renderer.js
|
|-- pycalc
|   |-- api.py
|   |-- calc.py
|   `-- requirements.txt
|
|-- LICENSE
`-- README.md

As shown above, the Python application is wrapped in a subfolder. In this example, Python application pycalc/calc.py provides a function: calc(text) that could take a text like 1 + 1 / 2 and return the result like 1.5 (assuming it be like eval()). The pycalc/api.py is what we are going to figure out.

And the index.html, main.js, package.json and renderer.js are modified from electron-quick-start.

Python part

First of all, since we already have the Python application running, the Python environment should be fine. I strongly recommend developing Python applications in virtualenv.

Try install zerorpc, and pyinstaller (for packaging). On Linux / Ubuntu we may need to run sudo apt-get install libzmq3-dev before pip install.

pip install zerorpc
pip install pyinstaller

# for windows only
pip install pypiwin32 # for pyinstaller

If properly configured, the above commands should have no problem. Otherwise, please check out the guides online.

Node.js / Electron part

Secondly, try to configure the Node.js and Electron environment. I assume that node and npm can be invoked in the command line and are of latest versions.

We need to configure the package.json, especially the main entry:

{
  "name": "pretty-calculator",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "dependencies": {
    "zerorpc": "git+https://github.com/0rpc/zerorpc-node.git"
  },
  "devDependencies": {
    "electron": "^1.7.6",
    "electron-packager": "^9.0.1"
  }
}

Clean the caches:

# On Linux / OS X
# clean caches, very important!!!!!
rm -rf ~/.node-gyp
rm -rf ~/.electron-gyp
rm -rf ./node_modules
# On Window PowerShell (not cmd.exe!!!)
# clean caches, very important!!!!!
Remove-Item "$($env:USERPROFILE)\.node-gyp" -Force -Recurse -ErrorAction Ignore
Remove-Item "$($env:USERPROFILE)\.electron-gyp" -Force -Recurse -ErrorAction Ignore
Remove-Item .\node_modules -Force -Recurse -ErrorAction Ignore

Then run npm:

# 1.7.6 is the version of electron
# It's very important to set the electron version correctly!!!
# check out the version value in your package.json
npm install --runtime=electron --target=1.7.6

# verify the electron binary and its version by opening it
./node_modules/.bin/electron

The npm install will install zerorpc-node from my fork to skip building from sources. Updated: the pull request of zerorpc-node was merged so everyone is encouraged to use the official repo instead.

(Consider adding ./.npmrc in the project folder if necessary.)

All libraries should be fine now.

optional: building from sources

If the above installation causes any errors even while setting the electron version correctly, we may have to build the packages from sources.

Ironically, to compile Node.js C/C++ native codes, we need to have python2 configured, no matter what Python version we are using for our Python application. Check out the official guide.

Especially, if working on Windows, open PowerShell as Administrator, and run npm install --global --production windows-build-tools to install a separated Python 2.7 in %USERPROFILE%\.windows-build-tools\python27 and other required VS libraries. We only need to do it at once.

Then, clean ~/.node-gyp and ./node_modules caches as described above at first.

Set the npm for Electron, and install the required libraries.

Set the environment variables for Linux (Ubuntu) / OS X / Windows:

# On Linux / OS X:

# env
export npm_config_target=1.7.6 # electron version
export npm_config_runtime=electron
export npm_config_disturl=https://atom.io/download/electron
export npm_config_build_from_source=true

# may not be necessary
#export npm_config_arch=x64
#export npm_config_target_arch=x64

npm config ls
# On Window PowerShell (not cmd.exe!!!)

$env:npm_config_target="1.7.6" # electron version
$env:npm_config_runtime="electron"
$env:npm_config_disturl="https://atom.io/download/electron"
$env:npm_config_build_from_source="true"

# may not be necessary
#$env:npm_config_arch="x64"
#$env:npm_config_target_arch="x64"

npm config ls

Then install things:

# in the same shell as above!!!
# because you want to make good use of the above environment variables

# install everything based on the package.json
npm install

# verify the electron binary and its version by opening it
./node_modules/.bin/electron

(Consider adding ./.npmrc in the project folder if necessary.)

core functions

Python part

We want to build up a ZeroMQ server in Python end.

Put calc.py into folder pycalc/. Then create another file pycalc/api.py. Check zerorpc-python for reference.

from __future__ import print_function
from calc import calc as real_calc
import sys
import zerorpc

class CalcApi(object):
    def calc(self, text):
        """based on the input text, return the int result"""
        try:
            return real_calc(text)
        except Exception as e:
            return 0.0
    def echo(self, text):
        """echo any text"""
        return text

def parse_port():
    return 4242

def main():
    addr = 'tcp://127.0.0.1:' + parse_port()
    s = zerorpc.Server(CalcApi())
    s.bind(addr)
    print('start running on {}'.format(addr))
    s.run()

if __name__ == '__main__':
    main()

To test the correctness, run python pycalc/api.py in one terminal. Then open another terminal, run this command and see the result:

zerorpc tcp://localhost:4242 calc "1 + 1"
## connecting to "tcp://localhost:4242"
## 2.0

After debugging, remember to terminate the Python function.

Actually, this is yet another server, communicated over zeromq over TCP, rather than traditional web server over HTTP.

Node.js / Electron part

Basic idea: In the main process, spawn the Python child process and create the window. In the render process, use Node.js runtime and zerorpc library to communicate with Python child process. All the HTML / JavaScript / CSS are managed by Electron, instead of by Python web server (The example in the previous post used Python web server to dynamically generate HTML codes).

In main.js, these are default codes to start from, with nothing special:

// main.js

const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const path = require('path')

let mainWindow = null
const createWindow = () => {
  mainWindow = new BrowserWindow({width: 800, height: 600})
  mainWindow.loadURL(require('url').format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))
  mainWindow.webContents.openDevTools()
  mainWindow.on('closed', () => {
    mainWindow = null
  })
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

We want to add some code to spawn Python child process:

// add these to the end or middle of main.js

let pyProc = null
let pyPort = null

const selectPort = () => {
  pyPort = 4242
  return pyPort
}

const createPyProc = () => {
  let port = '' + selectPort()
  let script = path.join(__dirname, 'pycalc', 'api.py')
  pyProc = require('child_process').spawn('python', [script, port])
  if (pyProc != null) {
    console.log('child process success')
  }
}

const exitPyProc = () => {
  pyProc.kill()
  pyProc = null
  pyPort = null
}

app.on('ready', createPyProc)
app.on('will-quit', exitPyProc)

In index.html, we have an <input> for input, and <div> for output:

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello Calculator!</title>
  </head>
  <body>
    <h1>Hello Calculator!</h1>
    <p>Input something like <code>1 + 1</code>.</p>
    <p>This calculator supports <code>+-*/^()</code>,
    whitespaces, and integers and floating numbers.</p>
    <input id="formula" value="1 + 2.0 * 3.1 / (4 ^ 5.6)"></input>
    <div id="result"></div>
  </body>
  <script>
    require('./renderer.js')
  </script>
</html>

In renderer.js, we have codes for initialization of zerorpc client, and the code for watching the changes in the input. Once the user types some formula into the text area, the JS send the text to Python backend and retrieve the computed result.

// renderer.js

const zerorpc = require("zerorpc")
let client = new zerorpc.Client()
client.connect("tcp://127.0.0.1:4242")

let formula = document.querySelector('#formula')
let result = document.querySelector('#result')
formula.addEventListener('input', () => {
  client.invoke("calc", formula.value, (error, res) => {
    if(error) {
      console.error(error)
    } else {
      result.textContent = res
    }
  })
})
formula.dispatchEvent(new Event('input'))

running

Run this to see the magic:

./node_modules/.bin/electron .

Awesome!

If something like dynamic linking errors shows up, try to clean the caches and install the libraries again.

rm -rf node_modules
rm -rf ~/.node-gyp ~/.electron-gyp

npm install

packaging

Some people are asking for the packaging. This is easy: apply the knowledge of how to package Python applications and Electron applications.

Python part

User PyInstaller.

Run the following in the terminal:

pyinstaller pycalc/api.py --distpath pycalcdist

rm -rf build/
rm -rf api.spec

If everything goes well, the pycalcdist/api/ folder should show up, as well as the executable inside that folder. This is the complete independent Python executable that could be moved to somewhere else.

Attention: the independent Python executable has to be generated! Because the target machine we want to distribute to may not have correct Python shell and/or required Python libraries. It's almost impossible to just copy the Python source codes.

Node.js / Electron part

This is tricky because of the Python executable.

In the above example code, I write

  // part of main.js
  let script = path.join(__dirname, 'pycalc', 'api.py')
  pyProc = require('child_process').spawn('python', [script, port])

However, once we package the Python code, we should no longer spawn Python script. Instead, we should execFile the generated excutable.

Electron doesn't provide functions to check whether the app is under distributed or not (at least I don't find it). So I use a workaround here: check whether the Python executable has been generated or not.

In main.js, add the following functions:

// main.js

const PY_DIST_FOLDER = 'pycalcdist'
const PY_FOLDER = 'pycalc'
const PY_MODULE = 'api' // without .py suffix

const guessPackaged = () => {
  const fullPath = path.join(__dirname, PY_DIST_FOLDER)
  return require('fs').existsSync(fullPath)
}

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)
}

And change the function createPyProc to this:

// main.js
// the improved version
const createPyProc = () => {
  let script = getScriptPath()
  let port = '' + selectPort()

  if (guessPackaged()) {
    pyProc = require('child_process').execFile(script, [port])
  } else {
    pyProc = require('child_process').spawn('python', [script, port])
  }

  if (pyProc != null) {
    //console.log(pyProc)
    console.log('child process success on port ' + port)
  }
}

The key point is, check whether the *dist folder has been generated or not. If generated, it means we are in "production" mode, execFile the executable directly; otherwise, spawn the script using a Python shell.

In the end, run electron-packager to generate the bundled application. We also want to exclude some folders (For example, pycalc/ is no longer needed to be bundled), using regex (instead of glob, surprise!). The name, platform, and arch are inferred from package.json. For more options, check out the docs.

# we need to make sure we have bundled the latest Python code
# before running the below command!
# Or, actually, we could bundle the Python executable later,
# and copy the output into the correct distributable Electron folder...

./node_modules/.bin/electron-packager . --overwrite --ignore="pycalc$" --ignore="\.venv" --ignore="old-post-backup"
## Packaging app for platform win32 x64 using electron v1.7.6
## Wrote new app to ./pretty-calculator-win32-x64

I do not check asar format's availability. I guess it will slow down the startup speed.

After that, we have the generated packaged Electron in current directory! For me, the result is ./pretty-calculator-win32-x64/. On my machine, it's around 170 MB (Electron itself occupies more than 84.2 MB). I also tried to compress it, the generated .7z file is around 43.3 MB.

Copy / Move the folder(s) to anywhere or other machines to check the result! :-)

further faq

full code?

See GitHub electron-python-example.

solutions to errors

issue #6: ... failed with KeyError

issue #7: Uncaught Error: Module version mismatch. Expected 50, got 48.

Uninstall everything, set up the npm environment variables correctly especially for the electron version, remember to activate the virtualenv if using Python virtualenv.

further optimization?

Trim some unnecessary files in Python executable by configuring pyinstaller further. Trim Electron (is it possible?). Use even faster IPC methods (though ZeroMQ is one of the fastest in most cases).

What's more, use QT (huh??), rewrite necessary codes in Node.js / Go / C / C++ (huh??). You name it.

Can I use other programming languages besides Python?

Sure. The solution described here can also be applied to any other programming languages besides Python. Except that, if you want to use Electron as GUI of C/C++ applications, I strongly recommend using Node.js native C/C++ communication mechanism instead of using IPC. Moreover, if you have Java, C# application, using Swing or WPF are much more mature choices.

But, unfortunately, Electron is not for mobile applications and it makes little sense even if possible. Please use native GUI on those platforms.

conclusion and further thinkings

It's still a promising solution. For drawing interface, we want to use some markup language for declarative UI. HTML happens to be one of the best choices, and its companions JS and CSS happen to have one of the most optimized renderers: the web browser. That's why I am (so) interested in using web technologies for GUI when possible. A few years before the web browsers were not powerful enough, but the story is kind of different now.

I hope this post is helpful to you.

electron-python-example's People

Contributors

ar7max avatar fyears avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

electron-python-example's Issues

Crashes

Cannot run this repo
A JavaScript error occurred in the main process
Uncaught Exception:
Error: companyName is a required option to crashReporter.start

keyError using example

Hi,

Thanks for this great demo!

However - when I run it (python 3.6 or python 2.7) I get the following problems:

1 - running as is I get no result from the calculation and a console error reporting "Lost remote after 10000ms"

2 - If I instead run the python code in the background (rather than from the electron app) then fire the electron app I see the following errors:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/gevent/greenlet.py", line 536, in run
    result = self._run(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/zerorpc/core.py", line 166, in _async_task
    bufchan.close()
  File "/usr/local/lib/python3.6/site-packages/zerorpc/channel.py", line 202, in close
    self._channel.close()
  File "/usr/local/lib/python3.6/site-packages/zerorpc/heartbeat.py", line 70, in close
    self._channel.close()
  File "/usr/local/lib/python3.6/site-packages/zerorpc/channel.py", line 138, in close
    del self._multiplexer._active_channels[self._channel_id]
KeyError: '7abdbe44-4e8b-4b0a-879f-000000000000'
Fri Feb 17 12:28:19 2017 <Greenlet at 0x105142178: <bound method ServerBase._async_task of <zerorpc.core.Server object at 0x1045b6f28>>(<zerorpc.events.Event object at 0x104fc6870>)> failed with KeyError

This looks to be something to do with the way strings are being passed around, but any suggestions? Running on OSX

Installation Issue - electron version problem

If anyone is having trouble getting the application to work e.g. getting this error, it may be because you are using a newer version of electron (currently 1.8.8), it needs to be 1.7.6. However, running npm install --runtime=electron --target=1.7.6 as per the instructions will not work because of an issue in the package.json file. You need to change:

"devDependencies": { "electron": "^1.7.6",

which allows newer versions of electron, to

"devDependencies": { "electron": "1.7.6",

Hope this will help someone

zerorpc is not included while packaging

I built my app just following the instruction. Thanks for the great work. It's really helpful.
It works pretty well before I package the electron app, but when I finally package it, error comes (zerorpc module can not find).
The resources/app/node_modules directory has all other modules except those imported by zerorpc. I don't know why it comes, but I guess the key point is it's imported by git link.
Can you give me any suggestions? Thanks.

How to call javascript from python

How to call javascript from python,
I want to do something with serial port ,
But I don't know how to send message from python to javascript when python port received serial message.

getting node version mismatch on zerorpc

I tired both npm installl from your packages .json and uninstalling and reinstalling zerorpc. I am on node 7.5.0 and npm v 4.1.2 on ubuntu 17.01

/home/samantha/work/electron-python-example/node_modules/zeromq/build/Release/zmq.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 51. This version of Node.js requires
NODE_MODULE_VERSION 54. Please try re-compiling or re-installing
the module (for instance, using npm rebuild ornpm install).

No handlers could be found for logger "zerorpc.channel"

Hi, first of all thanks for your project it helped me a lot with my school project. Now I'm on the final steps, the app is working flawlessly if I run it via terminal but now I have to package it. I've followed the steps and configured everything (pyinstaller, zerorpc, the distribution folder, etc.) the app successfully builds but I don't know why the zerorpc server won't start (or communicate). I'll leave a link to my repository. https://github.com/cipiasentini/apripublico.git Thanks in advance

Edit. After some debugging I found that the problem was with the zerorpc server. If I start the zerorpc server from terminal and then connect to it (just following your example python pycalc/api.py and on another terminal zerorpc tcp://localhost:4242 calc "1 + 1" I get this error on the server: No handlers could be found for logger "zerorpc.channel"

python virtualenv

Hello, im trying to run this setup on win10 but the python part on virtualenv. Did you try it? Any hints?

thanks a lot

Lost remote after 10000ms - Issue connecting to zerorpc server after packaging python

After packaging the python executable with Pyinstaller, I suddenly have issues with the zerorpc server. It appears that my issue comes after execFile the python executable. I'm able to create the pyprocess, but it isn't able to connect to the python script as it did before when it was just spawning off the script.

This is the exact error:
D:_\pyCal\renderer.js:14 Error: Lost remote after 10000ms
at Object.createErrorResponse
(D:_\pyCal\node_modules\zerorpc\lib\util.js:53)
at ClientChannel.
(D:_\pyCal\node_modules\zerorpc\lib\client.js:163)
at emitOne (events.js:96)
at ClientChannel.emit (events.js:191)
at D:_\pyCal\node_modules\zerorpc\lib\channel.js:198
client.invoke @ D:_\pyCal\renderer.js:14
callbackErrorWrapper @ D:_\pyCal\node_modules\zerorpc\lib\client.js:105
(anonymous) @ D:_\pyCal\node_modules\zerorpc\lib\client.js:164
emitOne @ events.js:96
emit @ events.js:191
(anonymous) @ D:_\pyCal\node_modules\zerorpc\lib\channel.js:198

Build Independent of this Repo

Hi, fyears!

Sorry to bug you again, but I was hoping for some insight.

When I try to recreate this example outside of this specific repository, it doesn't work. There are no error messages anywhere - it just seems that the zerorpc connection doesn't work. I literally copied and pasted all of your code and ran through the build as I would if I had cloned this repo, but the connection between Python and JavaScript never happens.

Do you have any direction for me to go in? I'm running on Ubuntu 16.04.

Thank you so, so much for your time.

Confused on how Python is bundled

Heyoo, thanks so much for making this example!

I'm confused on how you'd bundle python -- at what point do you run PyInstaller? Can you tell Electron to run it as it's bundling things together? I want to make a little Python app that runs some Selenium tests, would I hook PyInstaller up to Electron, pass it some requirements.txt and my source files and it outputs a .exe/binary?

Sorry for bugging ya, thanks again for posting this ๐Ÿ’ƒ

Packaged path vs dev path

Hi,

Bit of a long-shot, but I'm trying to do something similar to your project - running python scripts inside an electron app. I'm finding that the python path reported by python changes between the dev run (npm start) and the packaged app.

It's pretty impossible to avoid having more than one python version on a mac, as it needs the default 2.7 installed for os-related scripts. When the app compiles/packages, it's reverting to the 2.7 path instead of the anaconda 3.6 path usually available when run in dev mode.

Did you encounter this problem also ?

Thanks

Ian

Compiling for Mac OS

Hi,

The code works perfect for me in dev version but when I try to package it using electron packager I've got an issue, the result does not show anymore on the packaged app.

If I open it with npm start instead I've got in the renderer console :

Error: Lost remote after 10000ms at Object.createErrorResponse

Could this be an error comming from the python packaged part ?

Some complementary information :
I use Mac OS 10.12.5 Sierra with Python 2.7.13 (Anaconda custom)
When is try to exec the compiled python api I've got the following error :

./api 1 + 1 ImportError: dlopen(/Users/xxx/Documents/e2p/pycalcdist/api/zmq.backend.cython.error.so, 2): Symbol not found: _zmq_errno Referenced from: /Users/xxx/Documents/e2p/pycalcdist/api/zmq.backend.cython.error.so Expected in: flat namespace in /Users/xxx/Documents/e2p/pycalcdist/api/zmq.backend.cython.error.so Failed to execute script api

I looked for many forums, uninstalled pyzmq and reinstalling it with pip but it didn't work.

UPDATE : I tried with python 3.5 in a conda virual env and it works. Fyi it does not work with python 3.6 because packaging is not yet supported

Thank you for your help,

Oliver

Windows? Mac?

Would this compile and run as a self-contained environment without the need of additional dependencies?

I am VERY interested in this approach, and am looking for a solid method of ensuring this is entirely cross-platform.

running python threads

I want to create electron app using python-shell. It clciks on button on gui and script executes the python thread which stores the data. This process takes time, so after clicking user can navigate to other tabs. How to do so?

Instructions for Windows fails

Unfortunately, it is not possible to make the program work by following the instructions, for users on a Windows 10 machine, or a virtual machine for Windows 10. Is this repo abandoned?

Latest Version of Electron

Hi, fyears,

I've been playing around with this repo for a couple of days now. Everything works perfectly as expected, but I was hoping to use the latest version of Electron. When I try that, the MessagePack script fails. I'm wondering if you have a solution for this.

Thanks so much!
Chiara

DIfferent Node.js version, DLL Initializing

Hi fyears,

I'm following your tutorial after so many days of trying to get along with tkinter.
In a way it feels weird to have two backends running seperatly (node and python), but in my case this is just what i need, because i build my framework, which I want to use, in python.

Unfortunately I'm facing an issue when running npm start. The window shows up, already showing the DOM like I want to look like, but the console opens up with the following error:

ELECTRON_ASAR.js:173
Uncaught Error: The module '\\?\C:\Users\Thomas\Projekte\merge-documents\settings\node_modules\zerorpc\node_modules\zeromq\build\Release\zmq.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 50. This version of Node.js requires
NODE_MODULE_VERSION 53. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or`npm install`).

[...]

So I run npm rebuild and try it again. Now the console shows the following error:

Uncaught Error: Eine DLL-Initialisierungsroutine ist fehlgeschlagen.
\\?\C:\Users\Thomas\Projekte\merge-documents\settings\node_modules\zerorpc\node_modules\zeromq\build\Release\zmq.node
    at process.module.(anonymous function) [as dlopen] (ELECTRON_ASAR.js:173:20)
    at Object.Module._extensions..node (module.js:598:18)
    at Object.module.(anonymous function) [as .node] (ELECTRON_ASAR.js:173:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:\Users\Thomas\Projekte\merge-documents\settings\node_modules\zerorpc\node_modules\zeromq\lib\index.js:6:11)
    at Object.<anonymous> (C:\Users\Thomas\Projekte\merge-documents\settings\node_modules\zerorpc\node_modules\zeromq\lib\index.js:839:3)

The german sentence of the uncaught error means "A DLL initialization routine failed" ;)

Thanks in advance,
Thomas

How to use the latest electron

It would be good to be able to use the latest version of electron rather than be stuck with 1.7.6, however for some reason the dependency on the special version of zerorpc repo you have kindly provided prevents this - see #23.

I thought I had solved the problem by installing the latest versions of electron etc. and inspired by #22, even the latest "official" zerorpc, which resulted in these dependencies in my package.json:

"devDependencies": {
  "electron": "^1.8.4",
  "electron-packager": "^11.1.0",
  "electron-rebuild": "^1.7.3"
},
"dependencies": {
  "zerorpc": "^0.9.7"
}

After running these commands

brew install zeromq
npm install
./node_modules/.bin/electron-rebuild

I was able to run the example successfully.

Unfortunately when I package the app and run it on a virgin Mac system, libzmq.5.dylib is not found - same issue as zeromq/zeromq.js#131.

Despite the advice in that issue to avoid brew's zeromq and to instead install npm's zeromq with npm i zeromq --save - the problem persists because zerorpc uses zmq which "doesn't provide prebuild statically linked binaries. So you can't package your app with this module". Which presumably is one of the reasons that you made your custom version of zerorpc which changes the source code slightly to require zeromq instead of zmq.

Its all a bit confusing - it seems strange to me that npm zeromq would tolerate being 'unpackagable' because it requires zmq. And I don't understand why using your custom zerorpc repo locks us into an old version of electron (module mismatch issue).

Aside: The need for specific version numbers all over the readme instructions, and the use of custom repos and old versions of electron might put people off this wonderful project/solution.

Is there a way we can use the latest electron e.g. 1.8.4 with this electron-python solution - in a way which is deployable/packagable?

npm install fails on Windows 11

I have tried many things, among which are downgrading Python 3.10.2 to Python 2, installing MS Build Tools 2015, installing the VS C++ Workload and installing zerorpc via pip; none of this has worked, and I have no clue as to what the problem could actually be.

Here's the logs:

npm WARN deprecated [email protected]: this library is no longer supported
npm WARN deprecated [email protected]: Deprecated due to CVE-2021-21366 resolved in 0.5.0
npm WARN deprecated [email protected]: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated [email protected]: request has been deprecated, see request/request#3142
npm ERR! code 1
npm ERR! path C:\Users\Impasse\Desktop\electron-python-example-master\node_modules\zeromq
npm ERR! command failed
npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node scripts/prebuild-install.js || (node scripts/preinstall.js && node-gyp rebuild)
npm ERR! Downloading libzmq for Windows
npm ERR! Download finished
npm ERR! Building the projects in this solution one at a time. To enable parallel build, please add the "-m" switch.
npm ERR! C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(356,5): error MSB6006: "CL.exe" exited with code -1073741515. [C:\Users\Impasse\Desktop\electron-python-example-master\node_modules\zeromq\build\zmq.vcxproj]
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using [email protected]
npm ERR! gyp info using [email protected] | win32 | x64
npm ERR! gyp info find Python using Python version 3.10.2 found at "C:\Users\Impasse\AppData\Local\Programs\Python\Python310\python.exe"
npm ERR! gyp info find VS using VS2022 (17.0.32126.317) found at:
npm ERR! gyp info find VS "C:\Program Files\Microsoft Visual Studio\2022\Community"
npm ERR! gyp info find VS run with --verbose for detailed information
npm ERR! gyp info spawn C:\Users\Impasse\AppData\Local\Programs\Python\Python310\python.exe
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args 'C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\gyp_main.py',
npm ERR! gyp info spawn args 'binding.gyp',
npm ERR! gyp info spawn args '-f',
npm ERR! gyp info spawn args 'msvs',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args 'C:\Users\Impasse\Desktop\electron-python-example-master\node_modules\zeromq\build\config.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args 'C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\addon.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args 'C:\Users\Impasse\AppData\Local\node-gyp\Cache\17.4.0\include\node\common.gypi',
npm ERR! gyp info spawn args '-Dlibrary=shared_library',
npm ERR! gyp info spawn args '-Dvisibility=default',
npm ERR! gyp info spawn args '-Dnode_root_dir=C:\Users\Impasse\AppData\Local\node-gyp\Cache\17.4.0',
npm ERR! gyp info spawn args '-Dnode_gyp_dir=C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp',
npm ERR! gyp info spawn args '-Dnode_lib_file=C:\\Users\\Impasse\\AppData\\Local\\node-gyp\\Cache\\17.4.0\\<(target_arch)\\node.lib',
npm ERR! gyp info spawn args '-Dmodule_root_dir=C:\Users\Impasse\Desktop\electron-python-example-master\node_modules\zeromq',
npm ERR! gyp info spawn args '-Dnode_engine=v8',
npm ERR! gyp info spawn args '--depth=.',
npm ERR! gyp info spawn args '--no-parallel',
npm ERR! gyp info spawn args '--generator-output',
npm ERR! gyp info spawn args 'C:\Users\Impasse\Desktop\electron-python-example-master\node_modules\zeromq\build',
npm ERR! gyp info spawn args '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args 'build/binding.sln',
npm ERR! gyp info spawn args '/clp:Verbosity=minimal',
npm ERR! gyp info spawn args '/nologo',
npm ERR! gyp info spawn args '/p:Configuration=Release;Platform=x64'
npm ERR! gyp info spawn args ]
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe failed with exit code: 1
npm ERR! gyp ERR! stack at ChildProcess.onExit (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\build.js:194:23)
npm ERR! gyp ERR! stack at ChildProcess.emit (node:events:520:28)
npm ERR! gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
npm ERR! gyp ERR! System Windows_NT 10.0.22000
npm ERR! gyp ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd C:\Users\Impasse\Desktop\electron-python-example-master\node_modules\zeromq
npm ERR! gyp ERR! node -v v17.4.0
npm ERR! gyp ERR! node-gyp -v v8.4.1
npm ERR! gyp ERR! not ok

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Impasse\AppData\Local\npm-cache_logs\2022-02-09T11_01_25_456Z-debug-0.log

npm install fails

Hi. I am trying to install the repo on my system with Windows 10. Python 3.5 and Nodejs 10.16.0.
When i run npm install i get the following error

`path\electron-python-example-master\electron-python-example-master>npm install

[email protected] install path\electron-python-example-master\electron-python-example-master\node_modules\zeromq
node scripts/prebuild-install.js || (node scripts/preinstall.js && node-gyp rebuild)

prebuild-install WARN install No prebuilt binaries found (target=10.16.0 runtime=node arch=x64 platform=win32)

Downloading libzmq for Windows
Download finished

path\electron-python-example-master\electron-python-example-master\node_modules\zeromq>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin\....\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" rebuild )
gyp ERR! configure error
gyp ERR! stack Error: Command failed: path\AppData\Local\Programs\Python\Python35\python.EXE -c import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack File "", line 1
gyp ERR! stack import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack ^
gyp ERR! stack SyntaxError: invalid syntax
gyp ERR! stack
gyp ERR! stack at ChildProcess.exithandler (child_process.js:294:12)
gyp ERR! stack at ChildProcess.emit (events.js:198:13)
gyp ERR! stack at maybeClose (internal/child_process.js:982:16)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)
gyp ERR! System Windows_NT 10.0.16299
gyp ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" "rebuild"
gyp ERR! cwd path\electron-python-example-master\electron-python-example-master\node_modules\zeromq
gyp ERR! node -v v10.16.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: node scripts/prebuild-install.js || (node scripts/preinstall.js && node-gyp rebuild)
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! path\AppData\Roaming\npm-cache_logs\2019-06-07T06_09_01_680Z-debug.log`

Is this repo not compatible with Python 3.5?

Update `package.json` for packaging as application

In the blog post, you have a section on creating a packaged application. I'm having some trouble getting it to work, however. Did you make any modifications to the package.json file? i.e. did you add an extraResources section to the build instructions so that electron-packager knows to include it? Thanks!

Example doesn't seem to work on macOs.

Hi,

I didn't manage to get the example to work on macOs:

image

The Python end seems to be fine though:

(python-2.7) Kali:electron-python-example kelsolaar$ python pycalc/api.py
start running on tcp://127.0.0.1:4242

npm install error

When I try to run
$ npm install --runtime=electron --target=1.4.15
I get the error

npm ERR! git clone [email protected]:github:fyears/zerorpc-node Cloning into bare repository '/root/.npm/_git-remotes/git-github-com-github-fyears-zerorpc-node-aabe8777'... npm ERR! git clone [email protected]:github:fyears/zerorpc-node Warning: Permanently added the RSA host key for IP address '192.30.253.112' to the list of known hosts. npm ERR! git clone [email protected]:github:fyears/zerorpc-node Permission denied (publickey). npm ERR! git clone [email protected]:github:fyears/zerorpc-node fatal: Could not read from remote repository. npm ERR! git clone [email protected]:github:fyears/zerorpc-node npm ERR! git clone [email protected]:github:fyears/zerorpc-node Please make sure you have the correct access rights npm ERR! git clone [email protected]:github:fyears/zerorpc-node and the repository exists. npm ERR! notarget No compatible version found: zerorpc@'github:fyears/zerorpc-node' npm ERR! notarget Valid install targets: npm ERR! notarget ["0.1.0","0.2.0","0.3.0","0.4.0","0.5.0","0.6.0","0.6.1","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.8.6","0.8.7","0.8.8","0.9.0","0.9.1","0.9.2","0.9.3","0.9.4","0.9.5","0.9.6","0.9.7"] npm ERR! notarget npm ERR! notarget This is most likely not a problem with npm itself. npm ERR! notarget In most cases you or one of your dependencies are requesting npm ERR! notarget a package version that doesn't exist.

I'm not quite sure what's happening. I have installed npm and nodejs through apt-get.

Here's the npm-debug.log
https://gist.github.com/adityarpillai/80000f77a54ab24aac57a87104ef536b

Module mismatch following readme instructions

Following the recommended readme instructions, where package.json contains:

  "devDependencies": {
    "electron": "^1.7.6",
    "electron-packager": "^9.0.1"
  }

results in a javascript error

The module '/Users/Me/Devel/electron-python-example/node_modules/zeromq/build/Release/zmq.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 54. This version of Node.js requires
NODE_MODULE_VERSION 57. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
    at process.module.(anonymous function) [as dlopen] 

because specifying "electron": "^1.7.6", these days (2018) will cause npm to actually pick up electron 1.8.4 - which won't work with your custom zerorpc version.

This is because the ^ symbol in package.json means the latest available 1.* version of electron is searched for and installed, see npm versioning.

I finally got the example to work by removing the ^

  "devDependencies": {
    "electron": "1.7.6",
    "electron-packager": "9.0.1"
  }

thus causing that exact version of electron to be installed, which matches your 'prebuilt' zerorpc dependency "zerorpc": "git+https://github.com/fyears/zerorpc-node.git".

I believe that the readme should be updated to remove the ^ from package.json to help users avoid this problem.

zmq dylib is not getting packaged for some reason

Your example works great! I've noticed a problem though when I try to run the packaged app on another machine.

zmq-dylib-fail

As you can see the dylib is not getting packaged up. Any ideas on how I can correct this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.