Eel Python Library
repository·main·Indexed 27 days ago
https://github.com/python-eel/eelA lightweight Python library for creating offline GUI applications using web technologies (HTML, CSS, and JavaScript). Eel allows bidirectional function calls between Python and the browser, enabling the use of Python's computational libraries alongside JavaScript's visualization libraries. It includes support for Jinja2 templating, asynchronous execution via Gevent, and packaging into standalone binaries using PyInstaller.
What's inside Eel
- Eel is a Python library used to create simple, Electron-like offline GUI applications using HTML/JS. It hosts a local webserver and allows you to annotate Python functions so they can be called from JavaScript, and vice versa. This enables combining Python's computational libraries (like Numpy or Tensorflow) with JavaScript's visualization libraries (like D3 or THREE.js).
Install Eel
mainInstall the core Eel library using
pip:pip install eelIf you require support for HTML templating via Jinja2, install the optional dependency:
pip install eel[jinja2]Handle Asynchronous Python with eel.sleep() and eel.spawn()
mainEel is built on Gevent. To avoid blocking the event loop, avoid using
time.sleep(). Instead, useeel.sleep()for non-blocking delays. To run a function in a separate greenlet (thread), useeel.spawn().import eel eel.init('web') def my_other_thread(): while True: print("I'm a thread") eel.sleep(1.0) # Use eel.sleep(), not time.sleep() eel.spawn(my_other_thread) eel.start('main.html', block=False) while True: print("I'm a main loop") eel.sleep(1.0)Build a distributable binary with PyInstaller
mainTo package your Eel application into a standalone program that runs without a Python interpreter, use PyInstaller via the
eelmodule.- Set up a virtual environment with your required Python version and packages.
- Install PyInstaller:
pip install PyInstaller. - Run the eel command to trigger the build process:
python -m eel [your_main_script] [your_web_folder]. - The build output will be located in a
dist/folder.
You can pass standard PyInstaller flags through the command. For example, use
--excludeto omit specific modules or--onefile --noconsoleto create a single executable windowed application.Start an Eel application
mainTo start an Eel application, first initialize the web files directory using
eel.init()and then calleel.start()with the name of your entry HTML file. By default, this starts a webserver onhttp://localhost:8000and opens the browser in App Mode if Chrome or Chromium is installed.import eel eel.init('web') eel.start('main.html')Run automated tests with Tox
mainEel uses
toxto run tests against supported Python versions (3.7+).Prerequisites:
- Chrome must be installed.
- A compatible ChromeDriver must be installed (ensure the ChromeDriver version matches your installed Chrome version).
Commands:
- To run tests against all supported versions:
tox - To run tests against a specific version (e.g., Python 3.6):
tox -e py36
Set up a development environment for Eel
mainTo develop with Eel, clone the repository, set up a virtual environment, and install the necessary requirements for production, testing, and metadata.
# Clone the repository git clone git@github.com:python-eel/Eel.git # Create and activate a virtual environment python3 -m venv venv source venv/bin/activate # Install requirements pip3 install -r requirements.txt # eel's 'prod' requirements pip3 install -r requirements-test.txt # pytest and selenium pip3 install -r requirements-meta.txt # toxUse Microsoft Edge as the browser mode
mainOn Windows 10, Microsoft Edge is typically installed by default. You can explicitly instruct Eel to use Edge by setting themodeparameter ineel.start()to'edge'. This is a useful fallback if you want to ensure a specific browser behavior on Windows 10 systems.Retrieve return values using Callbacks or Synchronous calls
mainEel provides two ways to get data back from the other side of the bridge:
1. Callbacks (Asynchronous)
Pass a callback function as a second set of parentheses when calling an exposed function. The callback is executed asynchronously with the return value.
2. Synchronous Returns
To wait for a value immediately, use an empty second set of parentheses:
eel.function()().- In Python: This blocks until the value is returned. A default timeout of 10,000ms (10 seconds) applies to prevent hanging. This timeout can be adjusted via
_js_result_timeoutineel.init(). - In JavaScript: You must use
awaitinside anasyncfunction:let n = await eel.py_function()();.
Warning: Synchronous returns in Python only work after
eel.start()has been called.# Python Callback eel.js_random()(lambda n: print('Got this from Javascript:', n)) # Python Synchronous n = eel.js_random()() print('Got this from Javascript:', n)// JavaScript Synchronous async function run() { let n = await eel.py_random()(); console.log("Got this from Python: " + n); } run();- In Python: This blocks until the value is returned. A default timeout of 10,000ms (10 seconds) applies to prevent hanging. This timeout can be adjusted via
Expose JavaScript functions to Python
mainTo make a JavaScript function callable from the Python backend, use
eel.expose(function_name). You can optionally provide a second argument to override the exposed name, which is useful for minified builds.eel.expose(my_javascript_function); function my_javascript_function(a, b, c, d) { if (a < b) { console.log(c * d); } }# Calling from Python eel.my_javascript_function(1, 2, 3, 4)// Overriding name for minification eel.expose(someFunction, "my_javascript_function");Expose Python functions to JavaScript
mainTo make a Python function callable from the frontend, decorate it with
@eel.expose. On the JavaScript side, these functions will be available on the globaleelobject.Note: You must include the Eel library in your HTML files via
<script type="text/javascript" src="/eel.js"></script>.@eel.expose def my_python_function(a, b): print(a, b, a + b)// In your HTML/JS file eel.my_python_function(1, 2);Configure eel.start() options
mainYou can pass several keyword arguments to
eel.start()to customize the application behavior. Key options include:mode: String specifying the browser (e.g.,'chrome','electron','edge','msie','custom'). UseNoneorFalseto not open a window. Default:'chrome'host: String for the Bottle server hostname. Default:'localhost'port: Integer for the Bottle server port. Use0for automatic selection. Default:8000block: Boolean determining ifstart()should block the calling thread. Default:Truejinja_templates: String specifying a folder for Jinja2 templates.cmdline_args: List of strings to pass as command line flags to the browser.size: Tuple of ints(width, height)for the main window.position: Tuple of ints(left, top)for the main window.geometry: Dictionary mapping relative page paths to window settings, e.g.,{'path/to/page.html': {'size': (200, 100), 'position': (300, 50)}}.close_callback: A function/lambda called when a websocket closes. It receives the page path and a list of remaining open websockets.app: An existing Bottle instance. If using a custom instance, calleel.register_eel_routes(app)first.shutdown_delay: Seconds to wait after a websocket closes before checking if Eel should shut down. Default:1.0
eel.start('main.html', mode='chrome-app', port=8080, cmdline_args=['--start-fullscreen', '--browser-startup-dialog'])