Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
# vision-lib
This package provides some helpers and common components for working with the vision-api (e.g. for building a pipeline stage). See umbrella repo here: https://github.com/starwit/starwit-awareness-engine

Common components shared by the stages of the [Starwit Awareness Engine](https://github.com/starwit/starwit-awareness-engine) (SAE).

SAE stages communicate by passing `SaeMessage` protobufs (defined in [vision-api](https://github.com/starwit/vision-api)) through [Valkey](https://valkey.io/) streams. This library bundles the pieces most stages need:

- **Pipeline I/O** – read and write protobuf messages to/from Valkey streams.
- **Message helpers** – validate messages and extract raw/JPEG video frames.
- **Testing helpers** – record and replay traffic via the `.saedump` file format (see [format spec](./doc/saedump-format.md)).

Functionality is provided for both Python and Java. Since all SAE stages are written in Python, the [Python package](./python) is the primary one and offers the fuller feature set; the [Java package](./java) covers stream reading/writing and dump replay.

## Packages

| Package | Coordinates | Docs |
| --- | --- | --- |
| Python | `visionlib` | [python/README.md](./python/README.md) |
| Java | `de.starwit:vision-lib` | [java/README.md](./java/README.md) |
55 changes: 55 additions & 0 deletions doc/saedump-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# `.saedump` file format

An `.saedump` file records the `SaeMessage` traffic of one or more Valkey streams so it can be replayed later (e.g. for testing a stage without live input).

## Structure

A dump is a **UTF-8 text file** consisting of JSON objects separated by a semicolon (`;`), including a trailing separator after the last object:

```
<header>;<event>;<event>; … ;
```

- The **first** object is a *header* describing the dump.
- Every **following** object is an *event* wrapping a single recorded message.

The events are self-contained JSON objects separated by `;`, such that dump can trivially be read incrementally without loading the whole file into memory.

## Header

```json
{
"start_time": 1720187724.6267505,
"recorded_streams": ["geomapper:stream1"]
}
```

| Field | Type | Description |
| --- | --- | --- |
| `start_time` | float | Unix timestamp (seconds) when recording started. |
| `recorded_streams` | string[] | Keys of the streams contained in this dump. |

## Event

```json
{
"meta": {
"record_time": 1720187724.685442,
"source_stream": "geomapper:stream1"
},
"data_b64": "ChoKB3N0cmVhbTEQ…"
}
```

| Field | Type | Description |
| --- | --- | --- |
| `meta.record_time` | float | Unix timestamp (seconds) when the message was recorded. |
| `meta.source_stream` | string | Stream the message was read from. |
| `data_b64` | string | Base64-encoded `SaeMessage` protobuf (as defined in [vision-api](https://github.com/starwit/vision-api)). |

The `data_b64` value can essentially be taken verbatim from a Valkey stream entry and it also can be written into a stream on playback.

## Reading a dump

- **Python:** `visionlib.saedump` – `message_splitter()` yields the raw objects; parse the first with `DumpMeta` and the rest with `Event`.
- **Java:** `de.starwit.testing.SaeDump` – iterate to receive decoded `SaeMessage` objects.
123 changes: 71 additions & 52 deletions java/README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,71 @@
# vision-lib Java edition
## How-To Use
### Java / Maven
- Add maven repository to your `~/.m2/settings.xml` (adapt example / your config as necessary):
```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">

<activeProfiles>
<activeProfile>github</activeProfile>
</activeProfiles>

<profiles>
<profile>
<id>github</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/starwit/vision-lib</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>

<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USER</username>
<password>GITHUB_TOKEN_WITH_PACKAGE_READ_PERMISSIONS</password>
</server>
</servers>
</settings>

```

- Add dependency to your project:
```xml
<dependency>
<groupId>de.starwit</groupId>
<artifactId>vision-lib</artifactId>
<version>0.2.0</version>
</dependency>
```
# vision-lib (Java)

Java edition of the [Starwit Awareness Engine](https://github.com/starwit/starwit-awareness-engine) (SAE) common components. See the [repository overview](../README.md) for the bigger picture. This package covers stream reading/writing and `.saedump` replay; the [Python package](../python) offers the fuller feature set.

## Installation

The package is published to GitHub Packages. Add the repository to your `~/.m2/settings.xml` (adapt as necessary):

```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">

<activeProfiles>
<activeProfile>github</activeProfile>
</activeProfiles>

<profiles>
<profile>
<id>github</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/starwit/vision-lib</url>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>

<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USER</username>
<password>GITHUB_TOKEN_WITH_PACKAGE_READ_PERMISSIONS</password>
</server>
</servers>
</settings>
```

Then add the dependency to your project:

```xml
<dependency>
<groupId>de.starwit</groupId>
<artifactId>vision-lib</artifactId>
<version>0.3.0</version>
</dependency>
```

## What's available

All classes move `SaeMessage` protobufs and hold resources that must be closed (use try-with-resources).

- **[`de.starwit.pipeline`](src/main/java/de/starwit/pipeline)** – [`SaeReader`](src/main/java/de/starwit/pipeline/SaeReader.java) and [`SaeWriter`](src/main/java/de/starwit/pipeline/SaeWriter.java) read/write messages from/to Valkey streams.
- **[`de.starwit.testing`](src/main/java/de/starwit/testing)** – [`SaeDump`](src/main/java/de/starwit/testing/SaeDump.java) replays a `.saedump` recording as `SaeMessage` objects (see the [format specification](../doc/saedump-format.md)).

## Development

### Building and testing

```bash
mvn verify
```

Tests use [Testcontainers](https://testcontainers.com/) to spin up a Valkey/Redis instance, so a working Docker installation is required.
48 changes: 39 additions & 9 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,48 @@
# Python version of vision-lib
# vision-lib (Python)

## How to run tests
Activate the environment and run `pytest`.
If you see weird docker errors, that is probably because you're running rootless docker.
(see https://github.com/testcontainers/testcontainers-python/issues/537)
The solution to this is to make sure that `DOCKER_HOST` points at the correct docker socket, i.e.:\
`export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock`
Common components for building [Starwit Awareness Engine](https://github.com/starwit/starwit-awareness-engine) (SAE) stages in Python. See the [repository overview](../README.md) for the bigger picture.

## Installation

The package is not published to PyPI; install it directly from the Git repository, pinned to a [release tag](https://github.com/starwit/vision-lib/tags).

```bash
poetry add git+https://github.com/starwit/vision-lib.git@1.0.1#subdirectory=python
# or
pip install "git+https://github.com/starwit/vision-lib.git@1.0.1#subdirectory=python"
```

## What's available

- **[`visionlib.pipeline`](visionlib/pipeline/__init__.py)** – move `SaeMessage` protobufs through Valkey streams:
- [`ValkeyConsumer`](visionlib/pipeline/consumer.py) – read messages from one or more streams.
- [`ValkeyPublisher`](visionlib/pipeline/publisher.py) – write messages to a stream; `ValkeyPipelinePublisher` batches writes into one round-trip.
- [`get_raw_frame_data`](visionlib/pipeline/tools.py) – extract a video frame as a numpy array (JPEG decoded transparently).
- [`formats`](visionlib/pipeline/formats.py) – validate `SaeMessage` / `PositionMessage` objects.
- [`settings`](visionlib/pipeline/settings.py) – YAML config source and log-level enum for `pydantic-settings`.
- **[`visionlib.saedump`](visionlib/saedump.py)** – read `.saedump` recordings (see the [format specification](../doc/saedump-format.md)).

## Development

### Running tests

Activate the environment and run `pytest`. Tests spin up a Valkey instance via [testcontainers](https://testcontainers-python.readthedocs.io/), so a working Docker installation is required.

If you see weird docker errors, it is probably because you are running rootless Docker
(see [this issue](https://github.com/testcontainers/testcontainers-python/issues/537)).
Make sure `DOCKER_HOST` points at the correct socket:

```bash
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
```

## Changelog

### 1.0.1
- Restrict pyturbojpeg to 1.x (2.x requires libjpeg-turbo 3.x, which is not avaiable on Ubuntu 24.04 LTS)
- Restrict pyturbojpeg to 1.x (2.x requires libjpeg-turbo 3.x, which is not available on Ubuntu 24.04 LTS)

### 1.0.0
- Migrate from redis-py to valkey-py
- Use `valkey-py>=6.1.1`
- Breaks compatibility: imports and constructor calls for consumer and publisher must be changed!
- Provide cleaner imports (`from visionlib.pipeline import ValkeyConsumer`)
- Provide cleaner imports (`from visionlib.pipeline import ValkeyConsumer`)
Loading