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.
Files changed (52) hide show
  1. {simulo-0.13.1/src/simulo.egg-info → simulo-0.13.2}/PKG-INFO +1 -1
  2. {simulo-0.13.1 → simulo-0.13.2}/pyproject.toml +1 -1
  3. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset.py +10 -10
  4. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/cancel_api.py +1 -1
  5. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/cli.py +57 -5
  6. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/view_session_api.py +1 -1
  7. {simulo-0.13.1 → simulo-0.13.2/src/simulo.egg-info}/PKG-INFO +1 -1
  8. {simulo-0.13.1 → simulo-0.13.2}/MANIFEST.in +0 -0
  9. {simulo-0.13.1 → simulo-0.13.2}/PYPI.md +0 -0
  10. {simulo-0.13.1 → simulo-0.13.2}/setup.cfg +0 -0
  11. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/__init__.py +0 -0
  12. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/__init__.py +0 -0
  13. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/_entrypoint.py +0 -0
  14. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/_mounts.py +0 -0
  15. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/_runner.py +0 -0
  16. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/app.py +0 -0
  17. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset_api.py +0 -0
  18. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset_package.py +0 -0
  19. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/asset_pins.py +0 -0
  20. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/builtin_aliases.py +0 -0
  21. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/bundle.py +0 -0
  22. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/config.py +0 -0
  23. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/credentials.py +0 -0
  24. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/discovery.py +0 -0
  25. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/http.py +0 -0
  26. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/jobs_api.py +0 -0
  27. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/learning.py +0 -0
  28. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/login.py +0 -0
  29. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/manifest.py +0 -0
  30. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/mode.py +0 -0
  31. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/packaging.py +0 -0
  32. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/registry.py +0 -0
  33. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/runtime.py +0 -0
  34. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/runtime_display.py +0 -0
  35. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/seed_ref.py +0 -0
  36. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/stub.py +0 -0
  37. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/submit_api.py +0 -0
  38. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/__init__.py +0 -0
  39. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/inference/app.py.tmpl +0 -0
  40. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/inference/simuloignore.tmpl +0 -0
  41. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/scenario/app.py.tmpl +0 -0
  42. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/scenario/simuloignore.tmpl +0 -0
  43. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/training/app.py.tmpl +0 -0
  44. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/templates/training/simuloignore.tmpl +0 -0
  45. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/_client/volume.py +0 -0
  46. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/callbacks.py +0 -0
  47. {simulo-0.13.1 → simulo-0.13.2}/src/simulo/py.typed +0 -0
  48. {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/SOURCES.txt +0 -0
  49. {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/dependency_links.txt +0 -0
  50. {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/entry_points.txt +0 -0
  51. {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/requires.txt +0 -0
  52. {simulo-0.13.1 → simulo-0.13.2}/src/simulo.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Simulo SDK and CLI — define robotics simulation and training apps in Python and run them on the Simulo cloud.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simulo"
7
- version = "0.13.1"
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**, §6). The grammar
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 — see :meth:`require_kind`).
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/so-arm-100:v3``); :meth:`from_registry` names one, and :attr:`path`
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
- (§6). The handle is directly consumable wherever a model source is
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; on the worker it resolves to the real model asset. The return
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 ``"world"``."""
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 runner (cloud worker or local
256
- ``run-package``) exported for this asset. When set, it is authoritative.
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
- return _drain_logs(client, str(handle.job_id), follow=True)
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/world asset packages in your "
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 (§5.1)."
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 (§5.4)."
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
- result: int = args.func(args, extras)
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simulo
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Simulo SDK and CLI — define robotics simulation and training apps in Python and run them on the Simulo cloud.
5
5
  Author-email: Simulo Team <team@simulo.ai>
6
6
  License: BSD-3-Clause
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes