Skip to content

Commit dd00cbb

Browse files
committed
clean up implementation
1 parent c49e5c5 commit dd00cbb

4 files changed

Lines changed: 6 additions & 26 deletions

File tree

centml/cli/shell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def _connect_args(deployment_id, pod, shell_type):
1919
pod_name, warning = resolve_pod(cclient, deployment_id, pod)
2020
except ShellError as exc:
2121
raise click.ClickException(str(exc)) from exc
22-
if warning:
22+
if warning is not None:
2323
click.echo(f"{warning} Use --pod to specify a different pod.", err=True)
2424

2525
ws_url = build_ws_url(settings.CENTML_PLATFORM_API_URL, deployment_id, pod_name, shell_type)

centml/sdk/shell/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"""SDK shell module -- reusable shell/exec session logic (no Click dependency)."""
2-
31
from centml.sdk.shell.exceptions import NoPodAvailableError, PodNotFoundError, ShellError
42
from centml.sdk.shell.session import build_ws_url, exec_session, interactive_session, resolve_pod
53

centml/sdk/shell/exceptions.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
"""SDK exceptions for shell operations (no Click dependency)."""
2-
3-
41
class ShellError(Exception):
52
"""Base exception for shell operations."""
63

centml/sdk/shell/session.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"""WebSocket session logic for shell and exec commands (no Click dependency)."""
2-
31
import asyncio
42
import json
53
import shutil
@@ -16,17 +14,18 @@
1614
from centml.sdk import PodStatus
1715
from centml.sdk.shell.exceptions import NoPodAvailableError, PodNotFoundError
1816

17+
# exec_session wraps commands between BEGIN/END markers so it can separate
18+
# real command output from shell noise (prompt, echoed input, login banners).
1919
BEGIN_MARKER = "__CENTML_BEGIN_5f3a__"
2020
END_MARKER = "__CENTML_END_5f3a__"
2121

2222
# printf octal \137 = underscore. The decoded output matches BEGIN/END_MARKER,
2323
# but the literal command text does NOT, so shell echo won't trigger false matches.
24-
PRINTF_BEGIN = r"\137\137CENTML_BEGIN_5f3a\137\137"
25-
PRINTF_END = r"\137\137CENTML_END_5f3a\137\137"
24+
PRINTF_BEGIN = BEGIN_MARKER.replace("__", r"\137\137")
25+
PRINTF_END = END_MARKER.replace("__", r"\137\137")
2626

2727

2828
def build_ws_url(api_url, deployment_id, pod_name, shell_type=None):
29-
"""Build the WebSocket URL for a terminal connection."""
3029
parsed = urllib.parse.urlparse(api_url)
3130
ws_scheme = "wss" if parsed.scheme == "https" else "ws"
3231
ws_base = parsed._replace(scheme=ws_scheme).geturl()
@@ -37,20 +36,6 @@ def build_ws_url(api_url, deployment_id, pod_name, shell_type=None):
3736

3837

3938
def resolve_pod(cclient, deployment_id, pod_name=None) -> Tuple[str, Optional[str]]:
40-
"""Resolve which pod to connect to.
41-
42-
Args:
43-
cclient: CentMLClient instance.
44-
deployment_id: The deployment ID.
45-
pod_name: Optional specific pod name to target.
46-
47-
Returns:
48-
Tuple of (pod_name, optional_warning_message).
49-
50-
Raises:
51-
NoPodAvailableError: If no running pods found.
52-
PodNotFoundError: If specified pod not found among running pods.
53-
"""
5439
status = cclient.get_status_v3(deployment_id)
5540
running_pods = []
5641
for revision in status.revision_pod_details_list or []:
@@ -102,7 +87,7 @@ async def _read_ws():
10287
msg = json.loads(raw_msg)
10388
data = msg.get("data", "")
10489
if data:
105-
sys.stdout.buffer.write(data.replace("\n", "\r\n").encode("utf-8", errors="replace"))
90+
sys.stdout.buffer.write(data.encode("utf-8", errors="replace"))
10691
sys.stdout.buffer.flush()
10792
elif msg.get("error"):
10893
sys.stderr.buffer.write(f"Error: {msg['error']}\r\n".encode())

0 commit comments

Comments
 (0)