simulo 0.13.1__tar.gz → 0.13.2__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.
- {simulo-0.13.1/src/simulo.egg-info → simulo-0.13.2}/PKG-INFO +1 -1
- {simulo-0.13.1 → simulo-0.13.2}/pyproject.toml +1 -1
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset.py +10 -10
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/cancel_api.py +1 -1
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/cli.py +57 -5
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/view_session_api.py +1 -1
- {simulo-0.13.1 → simulo-0.13.2/src/simulo.egg-info}/PKG-INFO +1 -1
- {simulo-0.13.1 → simulo-0.13.2}/MANIFEST.in +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/PYPI.md +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/setup.cfg +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/__init__.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/__init__.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/_entrypoint.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/_mounts.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/_runner.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/app.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset_api.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset_package.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset_pins.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/builtin_aliases.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/bundle.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/config.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/credentials.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/discovery.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/http.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/jobs_api.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/learning.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/login.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/manifest.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/mode.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/packaging.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/registry.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/runtime.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/runtime_display.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/seed_ref.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/stub.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/submit_api.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/__init__.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/inference/app.py.tmpl +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/inference/simuloignore.tmpl +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/scenario/app.py.tmpl +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/scenario/simuloignore.tmpl +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/training/app.py.tmpl +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/training/simuloignore.tmpl +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/volume.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/callbacks.py +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo/py.typed +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/SOURCES.txt +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/dependency_links.txt +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/entry_points.txt +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/requires.txt +0 -0
- {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simulo"
|
|
7
|
-
version = "0.13.
|
|
7
|
+
version = "0.13.2"
|
|
8
8
|
description = "Simulo SDK and CLI — define robotics simulation and training apps in Python and run them on the Simulo cloud."
|
|
9
9
|
readme = "PYPI.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
A registry asset ref is ``[<publisher>/]<kind>/<name>[:v<N>]`` (e.g.
|
|
4
4
|
``robot/so-arm-100:v3``, ``simulo/world/warehouse:v2``, or the unpinned
|
|
5
|
-
``robot/forklift`` — resolved to an exact version **at submit
|
|
5
|
+
``robot/forklift`` — resolved to an exact version **at submit**). The grammar
|
|
6
6
|
is the ONE shared parser from ``simulo.interfaces.platform.asset_catalog`` — the
|
|
7
7
|
CLI, the control plane, the worker, and the console all parse through it, so the
|
|
8
8
|
grammar can never drift. This handle carries the parsed ``kind`` (``robot`` /
|
|
9
|
-
``world``), which enables **kind safety** (``Robot(asset=<world asset>)`` fails
|
|
10
|
-
with a one-line explanation
|
|
9
|
+
``world`` / ``prop``), which enables **kind safety** (``Robot(asset=<world asset>)`` fails
|
|
10
|
+
with a one-line explanation naming the mismatched kind).
|
|
11
11
|
|
|
12
12
|
The on-disk :attr:`path` only exists in **execution mode**:
|
|
13
13
|
|
|
@@ -131,7 +131,7 @@ class Asset:
|
|
|
131
131
|
"""A read-only, registry-resolved resource mounted into running jobs.
|
|
132
132
|
|
|
133
133
|
A registry ref is ``[<publisher>/]<kind>/<name>[:v<N>]`` (e.g.
|
|
134
|
-
``robot/
|
|
134
|
+
``simulo/robot/cartpole:v1``); :meth:`from_registry` names one, and :attr:`path`
|
|
135
135
|
resolves to its read-only mount inside a running job. ``Asset`` is also how a
|
|
136
136
|
task names USD/URDF model sources to load into a scene — :meth:`usd` /
|
|
137
137
|
:meth:`urdf`.
|
|
@@ -154,8 +154,8 @@ class Asset:
|
|
|
154
154
|
|
|
155
155
|
``uri`` is a catalog ref ``[<publisher>/]<kind>/<name>[:v<N>]`` — the
|
|
156
156
|
publisher defaults to your own org, ``simulo`` names the global catalog,
|
|
157
|
-
and an omitted ``:v<N>`` is resolved to the current latest **at submit
|
|
158
|
-
|
|
157
|
+
and an omitted ``:v<N>`` is resolved to the current latest **at submit**.
|
|
158
|
+
The handle is directly consumable wherever a model source is
|
|
159
159
|
accepted — ``Robot(asset=...)`` for a ``robot`` ref, ``scene.add(...)``
|
|
160
160
|
for a ``world`` ref.
|
|
161
161
|
"""
|
|
@@ -166,7 +166,7 @@ class Asset:
|
|
|
166
166
|
"""Name a USD model source to load into a scene.
|
|
167
167
|
|
|
168
168
|
At submit time this returns an inert, torch-free spec object so authoring
|
|
169
|
-
stays lean;
|
|
169
|
+
stays lean; in the execution runtime it resolves to the real model asset. The return
|
|
170
170
|
type depends on mode, so it is typed ``Any``.
|
|
171
171
|
"""
|
|
172
172
|
return cls._model_asset("usd", path)
|
|
@@ -194,7 +194,7 @@ class Asset:
|
|
|
194
194
|
|
|
195
195
|
@property
|
|
196
196
|
def kind(self) -> str:
|
|
197
|
-
"""The ``<kind>`` segment of the ref — ``"robot"`` or ``"
|
|
197
|
+
"""The ``<kind>`` segment of the ref — ``"robot"``, ``"world"``, or ``"prop"``."""
|
|
198
198
|
return self._ref.kind
|
|
199
199
|
|
|
200
200
|
@property
|
|
@@ -252,8 +252,8 @@ class Asset:
|
|
|
252
252
|
|
|
253
253
|
Resolution order, in execution mode:
|
|
254
254
|
|
|
255
|
-
1. ``SIMULO_ASSET_<uri>`` — the mount the
|
|
256
|
-
|
|
255
|
+
1. ``SIMULO_ASSET_<uri>`` — the mount the execution environment
|
|
256
|
+
exported for this asset. When set, it is authoritative.
|
|
257
257
|
2. The on-disk catalog cache ``~/.simulo/assets/<org>/<kind>/<name>/v<N>/``
|
|
258
258
|
— the colon-free layout ``simulo asset get`` writes into. Used for a
|
|
259
259
|
local run with no runner-provided mount.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""HTTP client for the job cancel endpoint (stdlib only, torch-free).
|
|
2
2
|
|
|
3
3
|
Wire contract (job-cancel-and-demo-apps plan — see
|
|
4
|
-
``context/implementation-plans/job-cancel-and-demo-apps-plan.md``; the control
|
|
4
|
+
``context/implementation-plans/archive/job-cancel-and-demo-apps-plan.md``; the control
|
|
5
5
|
plane's half of this route is built by a parallel PR, so this client codes
|
|
6
6
|
directly against the plan's PINNED contract rather than waiting on it):
|
|
7
7
|
``POST /v1/jobs/{job_id}/cancel`` (Cognito bearer, org-scoped).
|
|
@@ -80,6 +80,7 @@ from __future__ import annotations
|
|
|
80
80
|
|
|
81
81
|
import argparse
|
|
82
82
|
import hashlib
|
|
83
|
+
import importlib.metadata
|
|
83
84
|
import importlib.resources
|
|
84
85
|
import json
|
|
85
86
|
import math
|
|
@@ -325,6 +326,9 @@ def _submit_app(
|
|
|
325
326
|
fallback) so every construction anywhere in the discovery-time control flow is
|
|
326
327
|
captured, mounted or not.
|
|
327
328
|
"""
|
|
329
|
+
if not app_file.is_file():
|
|
330
|
+
raise SystemExit(f"No such app file: {app_file}")
|
|
331
|
+
|
|
328
332
|
previous_mode = os.environ.get("SIMULO_MODE")
|
|
329
333
|
os.environ["SIMULO_MODE"] = DISCOVERY
|
|
330
334
|
try:
|
|
@@ -458,7 +462,19 @@ def _follow_and_report(handle: JobHandle) -> int:
|
|
|
458
462
|
assert handle.base_url is not None, "a cloud JobHandle always carries a base_url"
|
|
459
463
|
client = JobsApiClient(handle.base_url, token=handle.token)
|
|
460
464
|
print(f"Following job {handle.job_id} (--detach to submit without waiting)...", file=sys.stderr, flush=True)
|
|
461
|
-
|
|
465
|
+
try:
|
|
466
|
+
return _drain_logs(client, str(handle.job_id), follow=True)
|
|
467
|
+
except KeyboardInterrupt:
|
|
468
|
+
# The submit already succeeded — only the client-side follow loop
|
|
469
|
+
# died. Say so explicitly: without this, a user watching a raw
|
|
470
|
+
# traceback (or even a bare "^C") could easily read Ctrl-C as having
|
|
471
|
+
# killed the job itself, when it is still running server-side.
|
|
472
|
+
print(
|
|
473
|
+
f"\nInterrupted — the job is still running in the cloud. Reattach with:"
|
|
474
|
+
f" simulo logs {handle.job_id} --follow",
|
|
475
|
+
file=sys.stderr,
|
|
476
|
+
)
|
|
477
|
+
return 130
|
|
462
478
|
|
|
463
479
|
|
|
464
480
|
def _cmd_run(args: argparse.Namespace, extras: Sequence[str]) -> int:
|
|
@@ -4322,6 +4338,21 @@ def _nonnegative_int(value: str) -> int:
|
|
|
4322
4338
|
return parsed
|
|
4323
4339
|
|
|
4324
4340
|
|
|
4341
|
+
def _resolve_version() -> str:
|
|
4342
|
+
"""Resolve the installed ``simulo`` distribution version for ``--version``.
|
|
4343
|
+
|
|
4344
|
+
Reads the installed wheel's metadata (``importlib.metadata``) rather than a
|
|
4345
|
+
hardcoded string, so it can never drift from what ``pip show simulo``
|
|
4346
|
+
reports. Falls back to a plain placeholder if the distribution metadata is
|
|
4347
|
+
unavailable (e.g. running this module straight from a source checkout with
|
|
4348
|
+
no installed ``simulo`` distribution at all).
|
|
4349
|
+
"""
|
|
4350
|
+
try:
|
|
4351
|
+
return importlib.metadata.version("simulo")
|
|
4352
|
+
except importlib.metadata.PackageNotFoundError:
|
|
4353
|
+
return "unknown"
|
|
4354
|
+
|
|
4355
|
+
|
|
4325
4356
|
def _build_parser() -> argparse.ArgumentParser:
|
|
4326
4357
|
parser = argparse.ArgumentParser(
|
|
4327
4358
|
prog="simulo",
|
|
@@ -4330,6 +4361,18 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4330
4361
|
"(simulo jobs / logs / result / recordings / models / view / cancel)."
|
|
4331
4362
|
),
|
|
4332
4363
|
)
|
|
4364
|
+
# ``action="version"`` fires (prints + exits 0) while argparse is still
|
|
4365
|
+
# consuming optionals — before the subparsers' ``required=True`` check
|
|
4366
|
+
# runs — so ``simulo --version`` / ``simulo -v`` work standalone, with no
|
|
4367
|
+
# subcommand needed. No other short flag is registered anywhere on this
|
|
4368
|
+
# parser (or any subparser), so ``-v`` is free to alias ``--version``.
|
|
4369
|
+
parser.add_argument(
|
|
4370
|
+
"--version",
|
|
4371
|
+
"-v",
|
|
4372
|
+
action="version",
|
|
4373
|
+
version=f"simulo {_resolve_version()}",
|
|
4374
|
+
help="Show the simulo version and exit.",
|
|
4375
|
+
)
|
|
4333
4376
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
4334
4377
|
|
|
4335
4378
|
run = sub.add_parser(
|
|
@@ -4499,7 +4542,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4499
4542
|
asset = sub.add_parser(
|
|
4500
4543
|
"asset",
|
|
4501
4544
|
help=(
|
|
4502
|
-
"Publish, validate, browse, and manage robot
|
|
4545
|
+
"Publish, validate, browse, and manage robot, world, and prop asset packages in your "
|
|
4503
4546
|
"organization's catalog and the Simulo global catalog (USD or URDF)."
|
|
4504
4547
|
),
|
|
4505
4548
|
)
|
|
@@ -4570,7 +4613,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4570
4613
|
"publish",
|
|
4571
4614
|
help=(
|
|
4572
4615
|
"Publish a USD or URDF package as a new immutable asset version: inspect + "
|
|
4573
|
-
"upload + cloud-validate in one command
|
|
4616
|
+
"upload + cloud-validate in one command."
|
|
4574
4617
|
),
|
|
4575
4618
|
)
|
|
4576
4619
|
asset_publish.add_argument("path", help="Directory (or single USD/URDF file) to publish.")
|
|
@@ -4718,7 +4761,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
4718
4761
|
"get",
|
|
4719
4762
|
help=(
|
|
4720
4763
|
"Download an org-catalog asset version to the local cache (~/.simulo/assets/...); "
|
|
4721
|
-
"global assets are usable in jobs but not exportable
|
|
4764
|
+
"global assets are usable in jobs but not exportable."
|
|
4722
4765
|
),
|
|
4723
4766
|
)
|
|
4724
4767
|
asset_get.add_argument("ref", help="Asset reference, e.g. robot/forklift:v3 (unpinned = latest published version).")
|
|
@@ -5013,7 +5056,16 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
5013
5056
|
_make_output_encoding_safe()
|
|
5014
5057
|
parser = _build_parser()
|
|
5015
5058
|
args, extras = parser.parse_known_args(argv)
|
|
5016
|
-
|
|
5059
|
+
try:
|
|
5060
|
+
result: int = args.func(args, extras)
|
|
5061
|
+
except KeyboardInterrupt:
|
|
5062
|
+
# Last-resort safety net: every dispatched command already has its own
|
|
5063
|
+
# clean handling (``_observe_handler`` for the observe verbs,
|
|
5064
|
+
# ``_follow_and_report`` for ``simulo run``'s post-submit follow), so
|
|
5065
|
+
# this only fires for a Ctrl-C in whatever's left uncovered. Either
|
|
5066
|
+
# way, standard SIGINT exit code, never a raw traceback.
|
|
5067
|
+
print("\nInterrupted.", file=sys.stderr)
|
|
5068
|
+
return 130
|
|
5017
5069
|
return result
|
|
5018
5070
|
|
|
5019
5071
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""HTTP client for the live-view session mint endpoint (stdlib only, torch-free).
|
|
2
2
|
|
|
3
3
|
Wire contract (live-visualization plan, Wave 2 PR3 — control-plane; see
|
|
4
|
-
``context/implementation-plans/live-visualization-plan.md`` and PR3's
|
|
4
|
+
``context/implementation-plans/archive/live-visualization-plan.md`` and PR3's
|
|
5
5
|
``simulo_control_plane.jobs.view_sessions.mint_view_session``):
|
|
6
6
|
``POST /v1/jobs/{job_id}/view-session`` mints a short-lived (TTL <= 5 min)
|
|
7
7
|
gateway-audience session for watching a running ``--viewstream`` job's live
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|