CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-eel

For little HTML GUI applications, with easy Python/JS interop

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

async-operations.mddocs/

Asynchronous Operations

Functions for managing asynchronous execution and non-blocking operations within the Gevent event loop used by Eel.

Capabilities

Non-blocking Sleep

Sleep function compatible with Gevent event loop that doesn't block other operations.

def sleep(seconds: Union[int, float]) -> None:
    """
    Non-blocking sleep compatible with Gevent event loop.
    
    Parameters:
    - seconds: Union[int, float] - Number of seconds to sleep
    
    Returns:
    None
    """

Usage Example:

import eel

@eel.expose
def long_running_task():
    print("Starting task...")
    eel.sleep(2)  # Non-blocking 2-second sleep
    print("Task completed!")
    return "Done"

# In JavaScript, this won't block the UI
# eel.long_running_task()(function(result) {
#     console.log(result); // "Done" after 2 seconds
# });

Greenlet Spawning

Spawn new Greenlets for concurrent execution of functions without blocking the main thread.

def spawn(function: Callable[..., Any], *args: Any, **kwargs: Any) -> Greenlet:
    """
    Spawn a new Greenlet for asynchronous execution.
    
    Parameters:
    - function: Callable - Function to execute asynchronously
    - *args: Any - Positional arguments for the function
    - **kwargs: Any - Keyword arguments for the function
    
    Returns:
    gvt.Greenlet - Greenlet object for the spawned task
    """

Usage Examples:

import eel

def background_task(name, duration):
    print(f"Background task {name} starting...")
    eel.sleep(duration)
    print(f"Background task {name} completed!")

@eel.expose
def start_background_tasks():
    # Spawn multiple concurrent tasks
    task1 = eel.spawn(background_task, "Task1", 3)
    task2 = eel.spawn(background_task, "Task2", 2)
    task3 = eel.spawn(background_task, "Task3", 1)
    
    return "Background tasks started"

# Example with cleanup
@eel.expose
def managed_background_task():
    def worker():
        try:
            # Long-running work
            for i in range(10):
                print(f"Working... {i}")
                eel.sleep(1)
        except Exception as e:
            print(f"Task failed: {e}")
    
    greenlet = eel.spawn(worker)
    return "Task spawned"

# Proper cleanup for spawned greenlets
import atexit

spawned_greenlets = []

def cleanup_greenlets():
    for greenlet in spawned_greenlets:
        if not greenlet.dead:
            greenlet.kill()

atexit.register(cleanup_greenlets)

@eel.expose
def spawn_with_tracking():
    def worker():
        # Your work here
        pass
    
    greenlet = eel.spawn(worker)
    spawned_greenlets.append(greenlet)
    return "Task started with cleanup tracking"

Gevent Integration

Eel uses Gevent for asynchronous operations. Understanding this is important for proper usage:

  • Event Loop: All Eel operations run in a Gevent event loop
  • Greenlets: Lightweight threads that yield control cooperatively
  • Non-blocking: Use eel.sleep() instead of time.sleep() to avoid blocking
  • Concurrency: Multiple operations can run concurrently using eel.spawn()

Best Practices

Avoiding Blocking Operations

# BAD: Blocks the entire application
import time

@eel.expose
def bad_long_task():
    time.sleep(5)  # Blocks everything!
    return "Done"

# GOOD: Non-blocking
@eel.expose  
def good_long_task():
    eel.sleep(5)  # Allows other operations
    return "Done"

Managing Spawned Tasks

# Keep track of spawned greenlets for proper cleanup
active_tasks = []

@eel.expose
def start_managed_task():
    def worker():
        try:
            # Your task logic
            for i in range(100):
                # Do work
                eel.sleep(0.1)  # Yield control
        finally:
            # Clean up from active_tasks list
            pass
    
    greenlet = eel.spawn(worker)
    active_tasks.append(greenlet)
    return "Task started"

@eel.expose
def stop_all_tasks():
    for task in active_tasks:
        if not task.dead:
            task.kill()
    active_tasks.clear()
    return "All tasks stopped"

Install with Tessl CLI

npx tessl i tessl/pypi-eel

docs

async-operations.md

browser-management.md

build-tools.md

core-functions.md

index.md

tile.json