runtime-sdk 0.4.0__tar.gz → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtime-sdk
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Runtime Python SDK and CLI
5
5
  Project-URL: Repository, https://github.com/The-Money-Company-Limited/runtimevm
6
6
  Project-URL: Issues, https://github.com/The-Money-Company-Limited/runtimevm/issues
@@ -56,7 +56,7 @@ runtime login --api-key rt_live_...
56
56
  # Computers
57
57
  runtime create # in a real TTY, creates then drops you into the console
58
58
  runtime create myapp --command "python3 app.py" --cwd /home/ubuntu --port 3000
59
- runtime enter <id> # enter a fresh console session on an existing computer
59
+ runtime enter <name-or-id> # accepts slug/name like test, or the computer id
60
60
  runtime list
61
61
  runtime info <id>
62
62
  runtime start <id>
@@ -37,7 +37,7 @@ runtime login --api-key rt_live_...
37
37
  # Computers
38
38
  runtime create # in a real TTY, creates then drops you into the console
39
39
  runtime create myapp --command "python3 app.py" --cwd /home/ubuntu --port 3000
40
- runtime enter <id> # enter a fresh console session on an existing computer
40
+ runtime enter <name-or-id> # accepts slug/name like test, or the computer id
41
41
  runtime list
42
42
  runtime info <id>
43
43
  runtime start <id>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "runtime-sdk"
3
- version = "0.4.0"
3
+ version = "0.4.2"
4
4
  description = "Runtime Python SDK and CLI"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1,18 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ from runtime_sdk.client import RuntimeAPIError, RuntimeClient
4
+ from runtime_sdk.config import PendingSignup, RuntimeConfig, RuntimeConfigError
5
+
6
+ try:
7
+ __version__ = version("runtime-sdk")
8
+ except PackageNotFoundError: # pragma: no cover - local source tree fallback
9
+ __version__ = "0.0.0"
10
+
11
+ __all__ = [
12
+ "PendingSignup",
13
+ "RuntimeAPIError",
14
+ "RuntimeClient",
15
+ "RuntimeConfig",
16
+ "RuntimeConfigError",
17
+ "__version__",
18
+ ]
@@ -16,6 +16,7 @@ from urllib.parse import urljoin, urlparse
16
16
  from websockets.exceptions import ConnectionClosed
17
17
  from websockets.sync.client import connect as websocket_connect
18
18
 
19
+ from runtime_sdk import __version__
19
20
  from runtime_sdk.client import DEFAULT_WARMUP_TIMEOUT, RuntimeAPIError, RuntimeClient
20
21
  from runtime_sdk.config import (
21
22
  DEFAULT_BASE_URL,
@@ -123,6 +124,7 @@ class _UI:
123
124
  def build_parser() -> argparse.ArgumentParser:
124
125
  parser = argparse.ArgumentParser(prog="runtime")
125
126
  parser.add_argument("--base-url", help="Runtime API base URL")
127
+ parser.add_argument("--version", action="version", version=f"runtime-sdk {__version__}")
126
128
 
127
129
  # Subcommand is optional: bare `runtime` defaults to `create`.
128
130
  subparsers = parser.add_subparsers(dest="command", required=False)
@@ -372,6 +374,57 @@ def _computer_status_label(c: dict[str, Any]) -> str:
372
374
 
373
375
 
374
376
 
377
+ def _computer_matches_ref(c: dict[str, Any], ref: str) -> bool:
378
+ ref = ref.strip()
379
+ if not ref:
380
+ return False
381
+
382
+ candidates = {
383
+ str(c.get("id") or "").strip(),
384
+ str(c.get("slug") or "").strip(),
385
+ str(c.get("hostname") or "").strip(),
386
+ str(c.get("public_url") or "").strip(),
387
+ }
388
+
389
+ public_url = str(c.get("public_url") or "").strip()
390
+ if public_url:
391
+ parsed = urlparse(public_url)
392
+ if parsed.netloc:
393
+ candidates.add(parsed.netloc)
394
+ first_label = parsed.netloc.split(".", 1)[0].strip()
395
+ if first_label:
396
+ candidates.add(first_label)
397
+
398
+ return ref in {value for value in candidates if value}
399
+
400
+
401
+
402
+ def _resolve_computer_ref(client: RuntimeClient, ref: str) -> str:
403
+ ref = ref.strip()
404
+ if not ref:
405
+ raise RuntimeAPIError("computer id is required")
406
+ if ref.startswith("cmp_"):
407
+ return ref
408
+
409
+ try:
410
+ payload = client.list_computers()
411
+ except RuntimeAPIError:
412
+ return ref
413
+
414
+ computers = payload.get("computers") or []
415
+ if not isinstance(computers, list):
416
+ computers = []
417
+
418
+ matches = [c for c in computers if isinstance(c, dict) and _computer_matches_ref(c, ref)]
419
+ if len(matches) == 1:
420
+ resolved = str(matches[0].get("id") or "").strip()
421
+ return resolved or ref
422
+ if len(matches) > 1:
423
+ raise RuntimeAPIError(f"multiple computers matched {ref!r}; use the exact computer id")
424
+ return ref
425
+
426
+
427
+
375
428
  def _computer_table_layout(computers: list[dict[str, Any]]) -> dict[str, int]:
376
429
  term_width = shutil.get_terminal_size((100, 20)).columns
377
430
  slug_width = max(
@@ -774,6 +827,7 @@ def handle_info(config: RuntimeConfig, computer_id: str | None) -> int:
774
827
  return report_error("computer is missing an id")
775
828
 
776
829
  client = RuntimeClient(base_url=config.base_url, api_key=config.api_key)
830
+ computer_id = _resolve_computer_ref(client, computer_id)
777
831
  result = client.get_computer(computer_id)
778
832
  return report_success(result, lambda p: _render_computer_panel(p, title="computer"))
779
833
 
@@ -797,6 +851,7 @@ def handle_start(config: RuntimeConfig, computer_id: str | None) -> int:
797
851
  return report_error("computer is missing an id")
798
852
 
799
853
  client = RuntimeClient(base_url=config.base_url, api_key=config.api_key)
854
+ computer_id = _resolve_computer_ref(client, computer_id)
800
855
  result = _with_spinner(f"warming {computer_id}…", lambda: client.start_computer(computer_id))
801
856
 
802
857
  def render(payload: dict[str, Any]) -> None:
@@ -826,6 +881,8 @@ def handle_enter(config: RuntimeConfig, computer_id: str | None) -> int:
826
881
  if not computer_id:
827
882
  return report_error("computer is missing an id")
828
883
 
884
+ client = RuntimeClient(base_url=config.base_url, api_key=config.api_key)
885
+ computer_id = _resolve_computer_ref(client, str(computer_id))
829
886
  return _enter_computer(config, str(computer_id))
830
887
 
831
888
 
@@ -853,6 +910,7 @@ def handle_delete(config: RuntimeConfig, computer_id: str | None) -> int:
853
910
  return 0
854
911
 
855
912
  client = RuntimeClient(base_url=config.base_url, api_key=config.api_key)
913
+ computer_id = _resolve_computer_ref(client, computer_id)
856
914
  client.delete_computer(computer_id)
857
915
 
858
916
  def render(_: dict[str, Any]) -> None:
@@ -895,6 +953,7 @@ def handle_run(
895
953
  return report_error("command is required")
896
954
 
897
955
  client = RuntimeClient(base_url=config.base_url, api_key=config.api_key)
956
+ computer_id = _resolve_computer_ref(client, computer_id)
898
957
  result = _with_spinner(
899
958
  f"running on {computer_id}…",
900
959
  lambda: client.run_command(
@@ -937,6 +996,7 @@ def handle_publish(config: RuntimeConfig, computer_id: str | None, port: int | N
937
996
  return report_error("port must be between 1 and 65535")
938
997
 
939
998
  client = RuntimeClient(base_url=config.base_url, api_key=config.api_key)
999
+ computer_id = _resolve_computer_ref(client, computer_id)
940
1000
  _with_spinner(
941
1001
  f"publishing port {port} on {computer_id}…",
942
1002
  lambda: client.publish_port(computer_id, port),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtime-sdk
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Runtime Python SDK and CLI
5
5
  Project-URL: Repository, https://github.com/The-Money-Company-Limited/runtimevm
6
6
  Project-URL: Issues, https://github.com/The-Money-Company-Limited/runtimevm/issues
@@ -56,7 +56,7 @@ runtime login --api-key rt_live_...
56
56
  # Computers
57
57
  runtime create # in a real TTY, creates then drops you into the console
58
58
  runtime create myapp --command "python3 app.py" --cwd /home/ubuntu --port 3000
59
- runtime enter <id> # enter a fresh console session on an existing computer
59
+ runtime enter <name-or-id> # accepts slug/name like test, or the computer id
60
60
  runtime list
61
61
  runtime info <id>
62
62
  runtime start <id>
@@ -1,4 +0,0 @@
1
- from runtime_sdk.client import RuntimeAPIError, RuntimeClient
2
- from runtime_sdk.config import PendingSignup, RuntimeConfig, RuntimeConfigError
3
-
4
- __all__ = ["PendingSignup", "RuntimeAPIError", "RuntimeClient", "RuntimeConfig", "RuntimeConfigError"]
File without changes