armnet-runtime 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,217 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py,cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+ cover/
52
+
53
+ # Translations
54
+ *.mo
55
+ *.pot
56
+
57
+ # Django stuff:
58
+ *.log
59
+ local_settings.py
60
+ db.sqlite3
61
+ db.sqlite3-journal
62
+
63
+ # Flask stuff:
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ .pybuilder/
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ # For a library or package, you might want to ignore these files since the code is
85
+ # intended to run in multiple environments; otherwise, check them in:
86
+ # .python-version
87
+
88
+ # pipenv
89
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
90
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
91
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
92
+ # install all needed dependencies.
93
+ #Pipfile.lock
94
+
95
+ # poetry
96
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
97
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
98
+ # commonly ignored for libraries.
99
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
100
+ #poetry.lock
101
+
102
+ # pdm
103
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
104
+ #pdm.lock
105
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
106
+ # in version control.
107
+ # https://pdm.fming.dev/#use-with-ide
108
+ .pdm.toml
109
+
110
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
111
+ __pypackages__/
112
+
113
+ # Celery stuff
114
+ celerybeat-schedule
115
+ celerybeat.pid
116
+
117
+ # SageMath parsed files
118
+ *.sage.py
119
+
120
+ # Environments
121
+ .env
122
+ .venv
123
+ venv/
124
+ ENV/
125
+ env.bak/
126
+ venv.bak/
127
+
128
+ # Spyder project settings
129
+ .spyderproject
130
+ .spyproject
131
+
132
+ # Rope project settings
133
+ .ropeproject
134
+
135
+ # mkdocs documentation
136
+ /site
137
+ armnet/site/
138
+
139
+ # mypy
140
+ .mypy_cache/
141
+ .dmypy.json
142
+ dmypy.json
143
+
144
+ # Pyre type checker
145
+ .pyre/
146
+
147
+ # pytype static type analyzer
148
+ .pytype/
149
+
150
+ # Cython debug symbols
151
+ cython_debug/
152
+
153
+ # PyCharm
154
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
155
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
156
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
157
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
158
+ #.idea/
159
+ .vscode
160
+ .DS_Store
161
+ .cursor/debug.log
162
+ .idea
163
+
164
+ # robot data and assets
165
+ data/
166
+ datadump
167
+ checkpoints_act
168
+ wandb
169
+
170
+
171
+ # model checkpoints
172
+
173
+ # ROS and real robots
174
+ logfile.asc
175
+ armnet/robot_cell.json
176
+
177
+ # cpp
178
+ devel
179
+
180
+ Log/
181
+ annotations
182
+ unsloth_compiled_cache/
183
+ node_modules
184
+
185
+ # Terraform
186
+ .terraform/
187
+ .terraform.lock.hcl
188
+ terraform.tfstate
189
+ terraform.tfstate.backup
190
+
191
+ # experimental
192
+ experimental/*/images/*.png
193
+ *.p12
194
+ build_log.txt
195
+ outputs
196
+ **/.gradio/
197
+
198
+ # outputs
199
+ **/*.mp4
200
+ **/*.parquet
201
+ activation_cache/
202
+ sae_checkpoints/
203
+ sae_dataset_on_the_fly/
204
+ safety_violation_analysis/
205
+ **/feature_analysis_results/
206
+ datasets/
207
+
208
+ missiontracker/examples/models/*openpi*
209
+ missiontracker/examples/models/fiper_models
210
+ pilot_checkpoints
211
+ checkpoints/
212
+ assets/*pi0*
213
+ # Apptainer/Singularity images (built locally, multi-GB)
214
+ *.sif
215
+
216
+ # Git worktrees
217
+ .worktrees/
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.4
2
+ Name: armnet-runtime
3
+ Version: 0.1.0
4
+ Summary: armnet runtime SDK — used by code running inside customer containers on a cell.
5
+ Project-URL: Homepage, https://armnet.dev
6
+ Project-URL: Documentation, https://safe-robotics.github.io/alpha-robotics/packages/runtime/
7
+ Author: Ville Kuosmanen
8
+ License: Apache-2.0
9
+ Requires-Python: <3.13,>=3.12
10
+ Requires-Dist: armnet-core>=0.1.0
11
+ Requires-Dist: protobuf<7,>=5
12
+ Requires-Dist: pydantic<3,>=2.6
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=8; extra == 'dev'
15
+ Description-Content-Type: text/markdown
16
+
17
+ # armnet-runtime
18
+
19
+ The runtime SDK for the [Armnet](https://armnet.dev) managed arm farm — the
20
+ package you install **inside your container image**. It provides the `@main`
21
+ decorator, the `Context` your function receives, and the `armnet-runtime`
22
+ console script the container runs. It has a deliberately tiny dependency
23
+ footprint so it's cheap to bake into every image.
24
+
25
+ ```python
26
+ from armnet_runtime import Context, main
27
+
28
+ @main
29
+ def run(ctx: Context) -> dict:
30
+ ctx.report_progress("starting")
31
+ obs = ctx.cell.get_observation()
32
+ ...
33
+ return {"ok": True}
34
+ ```
35
+
36
+ Container `CMD`:
37
+
38
+ ```dockerfile
39
+ CMD ["armnet-runtime", "/app/main.py"]
40
+ ```
41
+
42
+ Code that submits jobs from a dev machine or CI uses
43
+ [`armnet-client`](https://pypi.org/project/armnet-client/) instead.
44
+
45
+ ## Install
46
+
47
+ ```bash
48
+ pip install armnet-runtime
49
+ ```
50
+
51
+ ## Documentation
52
+
53
+ Full guides and API reference: **<https://safe-robotics.github.io/alpha-robotics/packages/runtime/>**
@@ -0,0 +1,37 @@
1
+ # armnet-runtime
2
+
3
+ The runtime SDK for the [Armnet](https://armnet.dev) managed arm farm — the
4
+ package you install **inside your container image**. It provides the `@main`
5
+ decorator, the `Context` your function receives, and the `armnet-runtime`
6
+ console script the container runs. It has a deliberately tiny dependency
7
+ footprint so it's cheap to bake into every image.
8
+
9
+ ```python
10
+ from armnet_runtime import Context, main
11
+
12
+ @main
13
+ def run(ctx: Context) -> dict:
14
+ ctx.report_progress("starting")
15
+ obs = ctx.cell.get_observation()
16
+ ...
17
+ return {"ok": True}
18
+ ```
19
+
20
+ Container `CMD`:
21
+
22
+ ```dockerfile
23
+ CMD ["armnet-runtime", "/app/main.py"]
24
+ ```
25
+
26
+ Code that submits jobs from a dev machine or CI uses
27
+ [`armnet-client`](https://pypi.org/project/armnet-client/) instead.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ pip install armnet-runtime
33
+ ```
34
+
35
+ ## Documentation
36
+
37
+ Full guides and API reference: **<https://safe-robotics.github.io/alpha-robotics/packages/runtime/>**
@@ -0,0 +1,61 @@
1
+ syntax = "proto3";
2
+
3
+ // Wire format for streaming Rerun visualization data off a robot cell.
4
+ //
5
+ // A customer's @main code calls `ctx.log_rerun_data(...)` inside the cell
6
+ // container. That serializes a RerunPacket, which the cell publishes on the
7
+ // NATS subject `logs.<job_id>.rerun`. The orchestrator forwards packets over a
8
+ // websocket to the client's orchestrate script, which decodes them and replays
9
+ // each entry via `rr.log(...)` into the viewer started with `rr.init(...)`.
10
+ //
11
+ // Protobuf is used because these packets carry (lightly compressed) images at
12
+ // high frequency and protos encode compactly to bytes. Regenerate the Python
13
+ // bindings with runtime/scripts/gen_proto.sh after editing this file.
14
+
15
+ package remoterobo.rerun;
16
+
17
+ enum ImageEncoding {
18
+ IMAGE_ENCODING_UNSPECIFIED = 0;
19
+ // JPEG-encoded bytes (lossy, small). Decoded client-side via rr.EncodedImage.
20
+ IMAGE_ENCODING_JPEG = 1;
21
+ // Raw uint8 pixels in HWC order (lossless, larger). Decoded into an ndarray.
22
+ IMAGE_ENCODING_RAW_RGB = 2;
23
+ }
24
+
25
+ message Image {
26
+ bytes data = 1;
27
+ ImageEncoding encoding = 2;
28
+ uint32 width = 3;
29
+ uint32 height = 4;
30
+ uint32 channels = 5;
31
+ }
32
+
33
+ // One Rerun log call: an entity path plus a typed value.
34
+ message RerunEntry {
35
+ // Rerun entity path, e.g. "observation.images.cam_high" or "action.shoulder_pan".
36
+ string entity_path = 1;
37
+ oneof value {
38
+ double scalar = 2;
39
+ Image image = 3;
40
+ }
41
+ }
42
+
43
+ // A batch of entries logged at one logical timestep.
44
+ message RerunPacket {
45
+ string job_id = 1;
46
+ // Unix time in seconds when the packet was produced (used for ordering /
47
+ // debugging; the client logs in receive order). Kept equal to `obs_ts` for
48
+ // backward compatibility.
49
+ double timestamp = 2;
50
+ repeated RerunEntry entries = 3;
51
+
52
+ // Latency instrumentation (unix seconds, set in the cell container):
53
+ // - obs_ts: when the observation was handed to the streamer (production).
54
+ // - submit_ts: when the packet was serialized and emitted to stdout, i.e.
55
+ // after any queue wait + image encoding.
56
+ // The client compares these against its own clock at replay time to attribute
57
+ // latency to the runtime (obs_ts -> submit_ts, same clock) vs. the transport
58
+ // (submit_ts -> replay, crosses machines so it includes any clock skew).
59
+ double obs_ts = 4;
60
+ double submit_ts = 5;
61
+ }
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "armnet-runtime"
7
+ version = "0.1.0"
8
+ description = "armnet runtime SDK \u2014 used by code running inside customer containers on a cell."
9
+ readme = "README.md"
10
+ requires-python = ">=3.12,<3.13"
11
+ license = { text = "Apache-2.0" }
12
+ authors = [{ name = "Ville Kuosmanen" }]
13
+
14
+ dependencies = [
15
+ "armnet-core>=0.1.0",
16
+ "pydantic>=2.6,<3",
17
+ # Wire format for Rerun visualization packets (armnet_runtime.rerun).
18
+ "protobuf>=5,<7",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://armnet.dev"
23
+ Documentation = "https://safe-robotics.github.io/alpha-robotics/packages/runtime/"
24
+
25
+ [project.optional-dependencies]
26
+ dev = [
27
+ "pytest>=8",
28
+ ]
29
+
30
+ [project.scripts]
31
+ armnet-runtime = "armnet_runtime.cli:run"
32
+
33
+ [tool.uv.sources]
34
+ armnet-core = { workspace = true }
35
+
36
+ [tool.hatch.build.targets.wheel]
37
+ packages = ["src/armnet_runtime"]
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ # Regenerate the Rerun protobuf bindings.
3
+ #
4
+ # Requires `protoc` on PATH (e.g. `apt-get install protobuf-compiler` or
5
+ # `brew install protobuf`). The generated module is checked in so that normal
6
+ # installs do not need protoc.
7
+ set -euo pipefail
8
+
9
+ here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ runtime_root="$(dirname "$here")"
11
+ proto_dir="$runtime_root/proto"
12
+ out_dir="$runtime_root/src/armnet_runtime"
13
+
14
+ protoc \
15
+ --proto_path="$proto_dir" \
16
+ --python_out="$out_dir" \
17
+ "$proto_dir/rerun.proto"
18
+
19
+ # protoc emits `rerun_pb2.py`; we keep it as a private module.
20
+ mv "$out_dir/rerun_pb2.py" "$out_dir/_rerun_pb2.py"
21
+
22
+ echo "generated $out_dir/_rerun_pb2.py"
@@ -0,0 +1,66 @@
1
+ """armnet runtime SDK \u2014 used inside customer containers on a cell.
2
+
3
+ Customer-facing surface: a ``@main`` decorator and a :class:`Context`. The
4
+ container's entrypoint is the ``armnet-runtime`` console script
5
+ (installed by this package); it loads the user's file, finds the
6
+ ``@main``-decorated function, builds the context, and calls it.
7
+
8
+ Typical use::
9
+
10
+ from armnet_runtime import main, Context
11
+
12
+ @main
13
+ def run(ctx: Context):
14
+ seed = ctx.args.get("seed", 0)
15
+ ctx.report_progress("starting")
16
+ ...
17
+ return {"success_rate": 1.0}
18
+
19
+ Wire types (``Embodiment``, ``Task``, ``JobSpec``, ``JobResult``, ...) are
20
+ re-exported from :mod:`armnet_core` for ergonomics, so customer code
21
+ never needs to know about the core package directly.
22
+ """
23
+
24
+ from armnet_core import (
25
+ Embodiment,
26
+ Job,
27
+ JobResult,
28
+ JobSpec,
29
+ JobStatus,
30
+ RemoteExecutionError,
31
+ Task,
32
+ TerminalStatus,
33
+ )
34
+
35
+ from armnet_runtime.context import (
36
+ BIMANUAL_SO101_EMBODIMENT,
37
+ SO101_EMBODIMENT,
38
+ Cell,
39
+ CompletionStatus,
40
+ Context,
41
+ ResetTimeoutException,
42
+ require_so101_embodiment,
43
+ )
44
+ from armnet_runtime.decorator import MainRegistrationError, main
45
+
46
+ __all__ = [
47
+ "BIMANUAL_SO101_EMBODIMENT",
48
+ "SO101_EMBODIMENT",
49
+ "Cell",
50
+ "CompletionStatus",
51
+ "Context",
52
+ "require_so101_embodiment",
53
+ "Embodiment",
54
+ "Job",
55
+ "JobResult",
56
+ "JobSpec",
57
+ "JobStatus",
58
+ "MainRegistrationError",
59
+ "RemoteExecutionError",
60
+ "ResetTimeoutException",
61
+ "Task",
62
+ "TerminalStatus",
63
+ "main",
64
+ ]
65
+
66
+ __version__ = "0.1.0"
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rerun.proto
4
+ # Protobuf Python Version: 5.26.1
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0brerun.proto\x12\x10remoterobo.rerun\"y\n\x05Image\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x31\n\x08\x65ncoding\x18\x02 \x01(\x0e\x32\x1f.remoterobo.rerun.ImageEncoding\x12\r\n\x05width\x18\x03 \x01(\r\x12\x0e\n\x06height\x18\x04 \x01(\r\x12\x10\n\x08\x63hannels\x18\x05 \x01(\r\"f\n\nRerunEntry\x12\x13\n\x0b\x65ntity_path\x18\x01 \x01(\t\x12\x10\n\x06scalar\x18\x02 \x01(\x01H\x00\x12(\n\x05image\x18\x03 \x01(\x0b\x32\x17.remoterobo.rerun.ImageH\x00\x42\x07\n\x05value\"\x82\x01\n\x0bRerunPacket\x12\x0e\n\x06job_id\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x01\x12-\n\x07\x65ntries\x18\x03 \x03(\x0b\x32\x1c.remoterobo.rerun.RerunEntry\x12\x0e\n\x06obs_ts\x18\x04 \x01(\x01\x12\x11\n\tsubmit_ts\x18\x05 \x01(\x01*d\n\rImageEncoding\x12\x1e\n\x1aIMAGE_ENCODING_UNSPECIFIED\x10\x00\x12\x17\n\x13IMAGE_ENCODING_JPEG\x10\x01\x12\x1a\n\x16IMAGE_ENCODING_RAW_RGB\x10\x02\x62\x06proto3')
18
+
19
+ _globals = globals()
20
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
21
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'rerun_pb2', _globals)
22
+ if not _descriptor._USE_C_DESCRIPTORS:
23
+ DESCRIPTOR._loaded_options = None
24
+ _globals['_IMAGEENCODING']._serialized_start=393
25
+ _globals['_IMAGEENCODING']._serialized_end=493
26
+ _globals['_IMAGE']._serialized_start=33
27
+ _globals['_IMAGE']._serialized_end=154
28
+ _globals['_RERUNENTRY']._serialized_start=156
29
+ _globals['_RERUNENTRY']._serialized_end=258
30
+ _globals['_RERUNPACKET']._serialized_start=261
31
+ _globals['_RERUNPACKET']._serialized_end=391
32
+ # @@protoc_insertion_point(module_scope)