generator-electron-flask v1.0.17
generator-electron-flask

Create an Electron App project that auto-starts a Flask server the electron app can call for services. Deployable as a single App that users can double click on and run.
Installation
Before running this generator, ensure you have installed nodejs, npm and python. Read my Python and Nodejs installation tips if you need assistance.
First, install Yeoman and generator-electron-flask using npm (we assume you have pre-installed node.js).
npm install -g yo
npm install -g generator-electron-flaskor from GitHub
$ git clone https://github.com/abulka/generator-electron-flask
$ cd generator-electron-flask
$ npm install
$ npm linkThen generate your new project:
yo electron-flaskAnswering the questions e.g.
_-----_ ╭──────────────────────────╮
| | │ Welcome to the amazing │
|--(o)--| │ generator-electron-flask │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? App Name myapp
? Description My Electron application description
? Author's Name Fred Smith
? Author's Email fred@example.com
? license: Apache 2.0
? Package keywords (comma to split) python, js, great-app
? Run flask on port number? 5000
? Initial flask url (e.g. /hello or /hello-vue) to display? / hello
? Choose from misc options (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Electron logging
◯ Print current working directory on startup
◯ Print node and electron versions on starrtup
◉ Fully quit on Mac on exit (without needing CMD-Q)
◉ Open Electron/Chrome DevTools in final appRemember to cd myapp to enter into your new project directory, where you can edit it and run it.
Resulting App
Activate the python virtual environment created by this generator . venv/bin/activate then run npm start.
Here is the resulting electron app, with a flask server running inside:

The generated project contains useful demos of sending events, triggering menu items etc. which can all be deleted to make way for your own code. The javascript libraries vue.js, fomantic and jquery are used in the demos - these references can also be removed if you do not wish to use them.
To update this generator
npm update generator-electron-flask -gPlease update regularly as this generator is being actively developed as of mid 2021.
Scripts
You will find various useful scripts in the bin directory of your generated project. You need to put this directory in your PATH if you wish to utilise them. There are both Mac, Linux and Windows scripts available. For documentation on these scripts, see scripts documentation.
It may be possible to make npm script equivalents of these scripts, however since we are coordinating both a python flask app and an electron app, I chose to create bash/batch scripts.
Typical workflow
You can run the flask app independently by running bin/runflask. Then browse at http://localhost:5000 to test any ajax endpoints, and endpoints that render html pages.
You can test your electron app by running bin/runelectron which will run the electron app and automaticaly run flask in development mode, then kill flask upon exiting.
Once the electron-flask project is generated for you, the main workflow during development is editing code then calling runelectron aka. npm start whilst your python virtual environment is activated. In this way, the flask server spawned by electron should hopefully be invoked with the correct version of Python.
If you are not using a virtual environment then ensure you have installed all the dependencies in requirements.txt into your default Python environment with pip install -r requirements.txt.
For deployment, simply run the script bin/build and the resulting app will appear in e.g. out/YOURAPP-YOUROS-x64/ where YOUROS is one of
- darwin-x64
- linux-x64
- win32-x64
Double click on the executable to run it. For example, for MacOS assuming the app name is myapp, you would double click on out/myapp-darwin-x64/myapp.app
Architecture
The flask server is spawned as a child process by the Electron app main process - see src/index.js.
┌──────src/index.html─────────────────────────┐ ┌──────src/index.js───────────────────────────┐
│ │ │ │
│ electron render process html - always here │ │ main electron process javascript │
│ │ │ │
│ (you can make this html content blank │ │ (contains code to spawn flask server │
│ so that the iframe dominates │ │ on startup, and kill flask server │
│ except the iframe should always be here) │ │ on quit.) │
│ │ └───┬─────────────────────────────────────────┘
│ ┌──────iframe────────────────────────────┐ │ ▼
│ │ │ │ ┌──────src-flask-server/app.py────┐
│ │ initial flask page displayed here │ │───▶│ │
│ │ e.g. /hello │ │ │ flask server │
│ │ │──┼───▶│ │
│ │ all subsequent page navigation happens│◀─┼────│ /hello │
│ │ inside this iframe. │ │ │ /hello-vue │
│ │ │ │ │ /etc │
│ └────────────────────────────────────────┘ │ │ │
└─────────────────────────────────────────────┘ └─────────────────────────────────┘ The other main architectural idea here is that flask rendered pages are loaded in an iframe of the render process browser window. If they are loaded in the main render process browser window, you lose electron interprocess communication. For more information see page navigation documentation.
Electron Terminology
There are probably better explanations of how Electron works, but here is my understanding, which will help you understand this documentation.
- We start with the nodejs electron
main processwhich is pure javascriptsrc/index.jsand is the entry point. It is a nodejs process with access to the file system and where you define native OS menus etc. It is responsible for launching the browser window containing the UI. The browser window runs in a separate render process. The main process loads the initial HTML into the browser window. - The electron
render processis the browser window containing e.g.src/index.htmland its associated javascript.
Now, with the electron-flask project (this project) we introduce a 3rd process:
- The
flask serverprocess, which is written in Python. The flask server also has access to the filesystem, networking and all operating system features. Flask is spawned asynchronously by the electron main process using the commandrequire('child_process').spawn(pythonExePath)and is killed by the main process when electron app exits.
Anyone can talk to the flask server - it's just an endpoint:
- the javascript of the main electron process
src/index.js - the javascript of the electron render process in
src/index.html - any flask generated html page
For documentation on how to achieve communication between all the above, see the events documentation.
File structure generated
Root files
- package.json <------ javascript electron project npm config and requirements
- requirements.txt <------ flask Python project requirements
- bin <------ handy scriptsSource code dirs
src <------ Javascript Electron App
├── index.css
├── index.html <------ electron render process HTML (incl. iframe) + javascript
└── index.js <------ electron main process javascript
src-flask-server/ <------ Python flask server
├── app.py
├── static
│ ├── css
│ │ └── hello.css
│ ├── images
│ │ └── hello.png
│ └── js
│ └── hello-vue.js
└── templates
└── hello.html
└── hello-vue.htmlTemporary build dirs:
- build/
- dist/
- out/Local Javascript and Python libraries and runtimes:
- node_modules/
- venv/For production
The Flask executable is created by Pyinstaller. The template and static dirs, plus the python runtime are embedded in the executable. When the executable runs, all these files are unzipped into a temporary directory, then run.
When you make the final Electron executable app, the Flask executable is embedded inside the Electron app in its Resources directory.
Events
You can communicate between any of these
- a flask page (flask page in render process's iframe)
- the electron render process html page
- the electron main process
For documentation on how to achieve communication between all the above, see the events documentation.
Debugging your generated project
You can debug both electron and flask in the vscode debugger.
A vscode project directory is generated with some launch configurations ready to go.
Debugging Electron
Using vscode, you can step into electron by launching with
{
"name": "ELECTRON Debug Main Process",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": [
"."
],
"outputCapture": "std",
"env": {
"ELECTRON_FLASK_DONT_LAUNCH_FLASK": "1"
},
}Look in the vscode Debug Console for output.
See also electron launching flask documentation for advanced discussion on this important topic.
Debugging Flask
Using vscode you can launch the flask app with
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "src-flask-server.app",
"FLASK_ENV": "development"
},
"args": [
"run",
"--no-debugger"
],
"jinja": true
},Note the setting of FLASK_APP has been changed from the default of "app.py" to "src-flask-server.app" to reflect that the flask project is in a subdirectory.
Misc Notes
On the use of vue.js in demo
Note that vue is initialised to use delimiters: ["${", "}"] to distinguish from the flask templating {{ }}.
Husky pre commit
During the development of this project, checking in using git would trigger a pre commit hook that runs husky. For some reason husky would try to scan the templates folder and complain about invalid syntax - due to the yoeman <%> tags. Not sure why this template folder isn't being completely ignored?
Quick fix
mv .git/hooks/pre-commit .git/hooks/pre-commit-OFFLINETemporary fix
git commit --no-verifyMore discussion: https://stackoverflow.com/questions/63943401/husky-pre-commit-hook-failed-add-no-verify-to-bypass
License
Apache-2.0 © Andy Bulka