Skip to content

Commit

Permalink
Update SDK to version 0.11.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Roboto-Bot-O committed Oct 10, 2024
1 parent 8fd37b6 commit aa733b4
Show file tree
Hide file tree
Showing 11 changed files with 3,558 additions and 242 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ cdk/cdk.context.json
**/.pytest_cache
**/dist/
**/venv/
**/.ipynb_checkpoints

3,357 changes: 3,137 additions & 220 deletions build-support/lockfiles/python-default.lock

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions build-support/requirements/tools/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ dependencies = [
]

[project.optional-dependencies]
sdk_examples = [
"ipython~=8.28",
"jupyter~=1.1",
"matplotlib~=3.9",
"pillow~=10.4",
]

types = [
"pandas-stubs>=2.0",
"types-requests===2.31.0.1",
Expand Down
33 changes: 33 additions & 0 deletions examples/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
python_sources(
name="notebook-utils",
)

resources(
name="notebooks",
sources=["*.ipynb"],
)

# To run:
# pants run packages/roboto/examples:jupyter
pex_binary(
name="jupyter",
dependencies=[
":notebooks",
":notebook-utils",
"//packages/roboto/src/roboto:roboto-src",

# roboto[analytics] extras
"//build-support:3rdparty#numpy",
"//build-support:3rdparty#pandas",
"//build-support:3rdparty#stumpy",

# build-support[sdk_examples] extras
"//build-support:3rdparty-dev-tools#ipython",
"//build-support:3rdparty-dev-tools#jupyter",
"//build-support:3rdparty-dev-tools#matplotlib",
"//build-support:3rdparty-dev-tools#pillow",
],
script="jupyter",
args=["lab", f"--notebook-dir='{build_file_dir()}'"],
execution_mode="venv",
)
39 changes: 39 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
SDK usage examples
==================

This directory contains Jupyter notebooks demonstrating the use and features of the Roboto Python SDK.

## Setup

1. Setup your environment for [programmatic access to the Roboto platform](http://docs.roboto.ai/getting-started/programmatic-access.html)

2. Create a virtual environment using Python >= 3.10:
```bash
python -m venv .venv
```

3. Install the SDK with relevant pip extras:

_This assumes you're running this command from the root of the repository._

```bash
.venv/bin/python -m pip install .[analytics,examples]
```

## Running the examples

Start the Jupyter server and run the cells in notebooks of interest:
```bash
.venv/bin/jupyter lab --notebook-dir=examples
```

_If you're running the `jupyter lab` command from the `examples` directory itself, there's no need to specify the `--notebook-dir` argument. It's only necessary if you're running it from the root of the repository._

## Learn more

For more information, check out:
* [General Docs](https://docs.roboto.ai/)
* [User Guides](https://docs.roboto.ai/user-guides/index.html)
* [SDK Reference](https://docs.roboto.ai/reference/python-sdk/roboto/index.html)
* [CLI Reference](https://docs.roboto.ai/reference/cli.html)
* [About Roboto](https://www.roboto.ai/about)
159 changes: 159 additions & 0 deletions examples/match_visualization_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Copyright (c) 2024 Roboto Technologies, Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

"""
This is a collection of utilities used by the similarity search example notebook
to format and display the results of a Roboto similarity search.
"""

import base64
import io
import math

from IPython.core.pylabtools import print_figure
from IPython.display import HTML, display
import PIL.Image
import matplotlib.pyplot
import matplotlib.ticker

import roboto
import roboto.analytics

NANO_SEC_PER_SEC = 1e9


def images_frames_to_encoded_gif(image_frames, fps=10, loops=math.inf) -> str:
images = [PIL.Image.open(io.BytesIO(frame)) for frame in image_frames]
buffer = io.BytesIO()

frame_duration_ms = (1 / fps) * 1000

# https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif-saving
images[0].save(
buffer,
format="GIF",
save_all=True,
append_images=images[1:],
duration=frame_duration_ms,
loop=0 if loops == math.inf else loops, # 0 means loop forever
)

buffer.seek(0)

return base64.b64encode(buffer.getvalue()).decode("utf-8")


def format_log_time(log_time: int) -> str:
sec, nano_sec = divmod(log_time, NANO_SEC_PER_SEC)
return f"{int(sec)}.{int(nano_sec)}"


def plot_match(match: roboto.analytics.Match) -> matplotlib.pyplot.Figure:
fig, ax = matplotlib.pyplot.subplots()

fig.set_size_inches(5, 3)
ax.plot(match.subsequence)
ax.set_xticks([match.start_time, match.end_time])
ax.xaxis.set_major_formatter(
matplotlib.ticker.FuncFormatter(lambda val, _: format_log_time(val))
)
matplotlib.pyplot.setp(ax.spines.values(), lw=0.5)

return fig


def format_match(
match: roboto.analytics.Match,
image_topic_name: str,
additional_image_context_duration_seconds: float = 1.5,
roboto_client: roboto.RobotoClient | None = None,
) -> str:
additional_image_context_duration_ns = int(
additional_image_context_duration_seconds * NANO_SEC_PER_SEC
)
FALLBACK_GIF = "R0lGODlhAQABAIAAAAUEBA==" # 1x1 transparent GIF
gif = FALLBACK_GIF
if match.context.file_id is not None:
try:
file = roboto.File.from_id(
match.context.file_id, roboto_client=roboto_client
)
image_topic = file.get_topic(image_topic_name)
image_topic_data = image_topic.get_data(
message_paths_include=["data"],
start_time=match.start_time - additional_image_context_duration_ns,
end_time=match.end_time + additional_image_context_duration_ns,
)
image_frames = [msg["data"] for msg in image_topic_data]
gif = images_frames_to_encoded_gif(image_frames)
except BaseException:
pass

fig = plot_match(match)
plot_image = print_figure(
fig,
bbox_inches="tight",
base64=True,
dpi=600,
)
matplotlib.pyplot.close(fig)

return f"""\
<div style="display: flex; align-items: center; margin-bottom: 20px; width: 100%;">
<div style="style="flex: 0 0 10%; margin-right: 10px; text-align: center;">
{match.distance}
</div>
<div style="flex: 1; margin-right: 10px; text-align: center;">
<img
src="data:image/png;base64,{plot_image}"
style="height: auto; max-width: 100%"
/>
</div>
<div style="flex: 1; margin-right: 10px; text-align: center;">
<img
src="data:image/gif;base64,{gif}"
style="height: auto; max-width: 100%;"
/>
</div>
<div style="flex: 0 0 10%; margin-right: 10px; text-align: center;">
<a
href="https://app.roboto.ai/files/{match.context.file_id}"
target="_blank"
>
View in Roboto
</a>
</div>
</div>
"""


def print_match_results(
matches: list[roboto.analytics.Match],
image_topic: str,
additional_image_context_duration_seconds: float = 1.5,
roboto_client: roboto.RobotoClient | None = None,
) -> None:
HEADER_HTML = """\
<div style="display: flex; align-items: center; margin-bottom: 10px; width: 100%; font-weight: bold;">
<div style="flex: 0 0 10%; margin-right: 10px; text-align: center;">Distance</div>
<div style="flex: 1; margin-right: 10px; text-align: center;">Matching sequence</div>
<div style="flex: 1; text-align: center;">Camera topic</div>
<div style="flex: 0 0 10%; margin-right: 10px; text-align: center;">Link</div>
</div>
"""
display(HTML(HEADER_HTML))

for match in matches:
display(
HTML(
format_match(
match,
image_topic,
additional_image_context_duration_seconds,
roboto_client,
)
)
)
121 changes: 121 additions & 0 deletions examples/similarity-search.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "cb4e0010-2301-48ba-acec-921f1a7911ee",
"metadata": {},
"source": [
"### Initialization"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "de8b8546-fbd3-44a1-83ce-b5dcbc944748",
"metadata": {},
"outputs": [],
"source": [
"import roboto\n",
"import roboto.query\n",
"\n",
"\n",
"roboto_config = roboto.RobotoConfig.from_env(\"prod\")\n",
"roboto_client = roboto.RobotoClient.from_config(roboto_config)\n",
"query_client = roboto.query.QueryClient(\n",
" roboto_client=roboto_client,\n",
" owner_org_id=\"og_najtcyyee2qa\" # Drone Racing EU\n",
")\n",
"robotosearch = roboto.RobotoSearch(query_client=query_client)"
]
},
{
"cell_type": "markdown",
"id": "d2726851-7334-4091-a846-a73dd09f0b97",
"metadata": {},
"source": [
"### Retrieve Event and Find Similar Signals"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3aa216bd-e8fa-4997-abed-9a60c8bb16bb",
"metadata": {},
"outputs": [],
"source": [
"import roboto.analytics\n",
"\n",
"\n",
"event = roboto.domain.events.Event.from_id(\n",
" \"ev_6funfjngoznn17x3\", \n",
" roboto_client=roboto_client\n",
")\n",
"\n",
"# This is the topic on which the event was made.\n",
"# In this example, it's the \"/snappy_imu\" topic.\n",
"source_topic = roboto.Topic.from_id(\n",
" event.topic_ids[0], \n",
" roboto_client=roboto_client\n",
")\n",
"topics_to_match_against = robotosearch.find_topics(f\"topic.name = '{source_topic.name}'\")\n",
"\n",
"query_signal = event.get_data_as_df(\n",
" message_paths_include=[\"linear_acceleration\", \"angular_velocity\"]\n",
")\n",
"\n",
"matches = roboto.analytics.find_similar_signals(\n",
" query_signal,\n",
" topics_to_match_against,\n",
" max_matches_per_topic=1,\n",
" normalize=True\n",
")"
]
},
{
"cell_type": "markdown",
"id": "0413e6da-eeeb-4bb2-85a5-9b4898fd5a4e",
"metadata": {},
"source": [
"### Inspect Results"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "72baea36-6364-4194-8f81-c60b0d600de0",
"metadata": {},
"outputs": [],
"source": [
"from match_visualization_utils import print_match_results\n",
"\n",
"\n",
"print_match_results(\n",
" matches[:5], \n",
" image_topic=\"/snappy_cam/stereo_l\", \n",
" roboto_client=roboto_client\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ analytics = [
"stumpy>=1.13",
]

examples = [
"ipython~=8.28",
"jupyter~=1.1",
"matplotlib~=3.9",
"pillow~=10.4",
]

[project.scripts]
roboto = "roboto.cli:entry"

Expand Down
Loading

0 comments on commit aa733b4

Please sign in to comment.