Eel Python Library

repository·main·Indexed 27 days ago

https://github.com/python-eel/eel

A 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.

Tokens
2.2K
Snippets
8
Records
12
Agent score
42%

What's inside Eel

  1. Overview of Eel

    main
    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).
  2. Handle Asynchronous Python with eel.sleep() and eel.spawn()

    main

    Eel is built on Gevent. To avoid blocking the event loop, avoid using time.sleep(). Instead, use eel.sleep() for non-blocking delays. To run a function in a separate greenlet (thread), use eel.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)
  3. Build a distributable binary with PyInstaller

    main

    To package your Eel application into a standalone program that runs without a Python interpreter, use PyInstaller via the eel module.

    1. Set up a virtual environment with your required Python version and packages.
    2. Install PyInstaller: pip install PyInstaller.
    3. Run the eel command to trigger the build process: python -m eel [your_main_script] [your_web_folder].
    4. The build output will be located in a dist/ folder.

    You can pass standard PyInstaller flags through the command. For example, use --exclude to omit specific modules or --onefile --noconsole to create a single executable windowed application.

  4. Start an Eel application

    main

    To start an Eel application, first initialize the web files directory using eel.init() and then call eel.start() with the name of your entry HTML file. By default, this starts a webserver on http://localhost:8000 and opens the browser in App Mode if Chrome or Chromium is installed.

    import eel
    eel.init('web')
    eel.start('main.html')
  5. Run automated tests with Tox

    main

    Eel uses tox to 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
  6. Set up a development environment for Eel

    main

    To 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   # tox 
  7. Use Microsoft Edge as the browser mode

    main
    On Windows 10, Microsoft Edge is typically installed by default. You can explicitly instruct Eel to use Edge by setting the mode parameter in eel.start() to 'edge'. This is a useful fallback if you want to ensure a specific browser behavior on Windows 10 systems.
  8. Retrieve return values using Callbacks or Synchronous calls

    main

    Eel 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_timeout in eel.init().
    • In JavaScript: You must use await inside an async function: 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();
  9. Expose JavaScript functions to Python

    main

    To 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");
  10. Expose Python functions to JavaScript

    main

    To make a Python function callable from the frontend, decorate it with @eel.expose. On the JavaScript side, these functions will be available on the global eel object.

    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);
  11. Configure eel.start() options

    main

    You 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'). Use None or False to not open a window. Default: 'chrome'
    • host: String for the Bottle server hostname. Default: 'localhost'
    • port: Integer for the Bottle server port. Use 0 for automatic selection. Default: 8000
    • block: Boolean determining if start() should block the calling thread. Default: True
    • jinja_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, call eel.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'])