Skip to content

pyscript.workers

This module provides access to named web workers defined in <script> tags, and utilities for dynamically creating workers from Python code.

Named workers are Python web workers defined in HTML with a name attribute that can be referenced from the main thread or other workers. This module provides the workers object for accessing named workers and the create_named_worker() function for dynamically creating them.

Accessing named workers:

<!-- Define a named worker -->
<script type="py" worker name="calculator">
def add(a, b):
    return a + b

__export__ = ["add"]
</script>

<!-- Access from main thread -->
<script type="mpy">
from pyscript import workers


calc = await workers["calculator"]
result = await calc.add(5, 3)
print(result)  # 8
</script>

Dynamically creating named workers:

from pyscript import create_named_worker


# Create a worker from a Python file.
worker = await create_named_worker(
    src="./background_tasks.py",
    name="task-processor"
)

# Use the worker's exported functions.
result = await worker.process_data([1, 2, 3, 4, 5])
print(result)

Key features: - Access (await) named workers via dictionary-like syntax. - Dynamically create workers from Python. - Cross-interpreter support (Pyodide and MicroPython).

Worker access is asynchronous - you must await workers[name] to get a reference to the worker. This is because workers may not be ready immediately at startup.

workers = _ReadOnlyWorkersProxy() module-attribute

Global proxy for accessing named web workers.

create_named_worker(src, name, config=None, type='py') async

Dynamically create a web worker with a src Python file, a unique name and optional config (dict or JSON string) and type (py for Pyodide or mpy for MicroPython, the default is py).

This function creates a new web worker by injecting a <script> tag into the document. The worker will be accessible via the workers proxy once it's ready.

It returns a promise that resolves to the worker reference when ready.

from pyscript import create_named_worker


# Create a Pyodide worker.
worker = await create_named_worker(
    src="./my_worker.py",
    name="background-worker"
)

# Use the worker.
result = await worker.process_data()

# Create with standard PyScript configuration.
worker = await create_named_worker(
    src="./processor.py",
    name="data-processor",
    config={"packages": ["numpy", "pandas"]}
)

# Use MicroPython instead.
worker = await create_named_worker(
    src="./lightweight_worker.py",
    name="micro-worker",
    type="mpy"
)

Info

The worker script should define __export__ to specify which functions or objects are accessible from the main thread.

Source code in pyscript/workers.py
async def create_named_worker(src, name, config=None, type="py"):
    """
    Dynamically create a web worker with a `src` Python file, a unique
    `name` and optional `config` (dict or JSON string) and `type` (`py`
    for Pyodide or `mpy` for MicroPython, the default is `py`).

    This function creates a new web worker by injecting a `<script>` tag into
    the document. The worker will be accessible via the `workers` proxy once
    it's ready.

    It returns a promise that resolves to the worker reference when ready.

    ```python
    from pyscript import create_named_worker


    # Create a Pyodide worker.
    worker = await create_named_worker(
        src="./my_worker.py",
        name="background-worker"
    )

    # Use the worker.
    result = await worker.process_data()

    # Create with standard PyScript configuration.
    worker = await create_named_worker(
        src="./processor.py",
        name="data-processor",
        config={"packages": ["numpy", "pandas"]}
    )

    # Use MicroPython instead.
    worker = await create_named_worker(
        src="./lightweight_worker.py",
        name="micro-worker",
        type="mpy"
    )
    ```

    !!! info

        **The worker script should define** `__export__` to specify which
        functions or objects are accessible from the main thread.
    """
    # Create script element for the worker.
    script = js.document.createElement("script")
    script.type = type
    script.src = src
    # Mark as a worker with a name.
    script.setAttribute("worker", "")
    script.setAttribute("name", name)
    # Add configuration if provided.
    if config:
        if isinstance(config, str):
            config_str = config
        else:
            config_str = json.dumps(config)
        script.setAttribute("config", config_str)
    # Inject the script into the document and await the result.
    js.document.body.append(script)
    return await workers[name]