appose 0.10.1
Appose: multi-language interprocess cooperation with shared memory.
Requires Python: >=3.9
Keywords: java, python, cross-language, interprocess

# Appose Python

[![Build Status](https://github.com/apposed/appose-python/actions/workflows/build.yml/badge.svg)](https://github.com/apposed/appose-python/actions/workflows/build.yml)

> [!NOTE]
> **QUICK START:** [Appose Workshop](https://fiji.github.io/i2k-2025-appose/)

|   |   |
|---|---|
| <img src="https://docs.apposed.org/en/latest/_static/icons/hammer-solid-full.svg" width="24" height="24"> | **Build environments** based on community standards ([pixi](https://pixi.sh), [mamba](https://mamba.readthedocs.io/en/latest/user_guide/micromamba.html), [uv](https://docs.astral.sh/uv/)) |
| <img src="https://docs.apposed.org/en/latest/_static/icons/code-solid-full.svg" width="24" height="24"> | **Run scripts** in those environments as worker processes |
| <img src="https://docs.apposed.org/en/latest/_static/icons/microchip-solid-full.svg" width="24" height="24"> | **Share memory** between processes to avoid copying data |
|   |

## What is Appose?

Appose is a library for interprocess cooperation with shared memory.
The guiding principles are *simplicity* and *efficiency*.

Appose was written to enable **easy execution of Python-based deep learning
from Java without copying tensors**, but its utility extends beyond that.
The steps for using Appose are:

* Build an Environment with the dependencies you need.
* Create a Service linked to a *worker*, which runs in its own process.
* Execute scripts on the worker by launching Tasks.
* Receive status updates from the task asynchronously via callbacks.

For more about Appose as a whole, see https://apposed.org.

## What is this project?

This is the **Python implementation of Appose**.

## How do I use it?

The name of the package is `appose`.

### PyPI/Pip

To use [the PyPI package](https://pypi.org/project/appose),
add `appose` to your project dependencies.

Depending on how your project is set up, this might entail editing
`requirements.txt`, `setup.py`, `setup.cfg`, and/or `pyproject.toml`.

If you are just starting out, we recommend using `pyproject.toml` (see
[this guide](https://packaging.python.org/en/latest/tutorials/packaging-projects/#creating-pyproject-toml)):

```toml
dependencies = [
  "appose"
]
```

### Conda/Mamba

To use [the conda-forge package](https://anaconda.org/conda-forge/appose),
add `appose` to your `environment.yml`'s `dependencies` section:

```yaml
dependencies:
  - appose
```

## Examples

Here is a minimal example for calling into Java from Python:

```python
import appose
env = appose.java(vendor="zulu", version="17").build()
with env.groovy() as groovy:
    task = groovy.task("5 + 6")
    task.wait_for()
    result = task.outputs["result"]
    assert 11 == result
```

*Note: The `appose.java` builder is planned, but not yet implemented.*

Here is an example using a few more of Appose's features:

```python
import appose
from time import sleep

golden_ratio_in_groovy = """
// Approximate the golden ratio using the Fibonacci sequence.
previous = 0
current = 1
for (i=0; i<iterations; i++) {
    if (task.cancelRequested) {
        task.cancel()
        break
    }
    task.update(null, i, iterations)
    v = current
    current += previous
    previous = v
}
task.outputs["numer"] = current
task.outputs["denom"] = previous
"""

env = appose.java(vendor="zulu", version="17").build()
with env.groovy() as groovy:
    task = groovy.task(golden_ratio_in_groovy)

    def task_listener(event):
        match event.responseType:
            case ResponseType.UPDATE:
                print(f"Progress {task.current}/{task.maximum}")
            case ResponseType.COMPLETION:
                numer = task.outputs["numer"]
                denom = task.outputs["denom"]
                ratio = numer / denom
                print(f"Task complete. Result: {numer}/{denom} =~ {ratio}");
            case ResponseType.CANCELATION:
                print("Task canceled")
            case ResponseType.FAILURE:
                print(f"Task failed: {task.error}")

    task.listen(task_listener)

    task.start()
    sleep(1)
    if not task.status.is_finished():
        # Task is taking too long; request a cancelation.
        task.cancel()

    task.wait_for()
```

Of course, the above examples could have been done all in one language. But
hopefully they hint at the possibilities of easy cross-language integration.

## Issue tracker

All implementations of Appose use the same issue tracker:

https://github.com/apposed/appose/issues