Skip to content

Commit 59d9d08

Browse files
committed
update redundancy
1 parent 9ef67f5 commit 59d9d08

3 files changed

Lines changed: 25 additions & 48 deletions

File tree

centml/cli/shell.py

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,11 @@
99
from centml.sdk import auth
1010
from centml.sdk.api import get_centml_client
1111
from centml.sdk.config import settings
12-
from centml.sdk.shell import ShellError
13-
from centml.sdk.shell.session import build_ws_url, exec_session, interactive_session, resolve_pod
12+
from centml.sdk.shell import ShellError, build_ws_url, exec_session, interactive_session, resolve_pod
1413

1514

16-
@click.command(help="Open an interactive shell to a deployment pod")
17-
@click.argument("deployment_id", type=int)
18-
@click.option("--pod", default=None, help="Specific pod name (auto-selects first running pod)")
19-
@click.option("--shell", "shell_type", default=None, type=click.Choice(["bash", "sh", "zsh"]), help="Shell type")
20-
@handle_exception
21-
def shell(deployment_id, pod, shell_type):
22-
if not sys.stdin.isatty():
23-
raise click.ClickException("Interactive shell requires a terminal (TTY)")
24-
15+
def _connect_args(deployment_id, pod, shell_type):
16+
"""Resolve pod, build WebSocket URL, and obtain auth token."""
2517
with get_centml_client() as cclient:
2618
try:
2719
pod_name, warning = resolve_pod(cclient, deployment_id, pod)
@@ -32,6 +24,19 @@ def shell(deployment_id, pod, shell_type):
3224

3325
ws_url = build_ws_url(settings.CENTML_PLATFORM_API_URL, deployment_id, pod_name, shell_type)
3426
token = auth.get_centml_token()
27+
return ws_url, token
28+
29+
30+
@click.command(help="Open an interactive shell to a deployment pod")
31+
@click.argument("deployment_id", type=int)
32+
@click.option("--pod", default=None, help="Specific pod name (auto-selects first running pod)")
33+
@click.option("--shell", "shell_type", default=None, type=click.Choice(["bash", "sh", "zsh"]), help="Shell type")
34+
@handle_exception
35+
def shell(deployment_id, pod, shell_type):
36+
if not sys.stdin.isatty():
37+
raise click.ClickException("Interactive shell requires a terminal (TTY)")
38+
39+
ws_url, token = _connect_args(deployment_id, pod, shell_type)
3540
exit_code = asyncio.run(interactive_session(ws_url, token))
3641
sys.exit(exit_code)
3742

@@ -43,16 +48,6 @@ def shell(deployment_id, pod, shell_type):
4348
@click.option("--shell", "shell_type", default=None, type=click.Choice(["bash", "sh", "zsh"]), help="Shell type")
4449
@handle_exception
4550
def exec_cmd(deployment_id, command, pod, shell_type):
46-
with get_centml_client() as cclient:
47-
try:
48-
pod_name, warning = resolve_pod(cclient, deployment_id, pod)
49-
except ShellError as exc:
50-
raise click.ClickException(str(exc)) from exc
51-
if warning:
52-
click.echo(f"{warning} Use --pod to specify a different pod.", err=True)
53-
54-
ws_url = build_ws_url(settings.CENTML_PLATFORM_API_URL, deployment_id, pod_name, shell_type)
55-
token = auth.get_centml_token()
56-
cmd_str = " ".join(command)
57-
exit_code = asyncio.run(exec_session(ws_url, token, cmd_str))
51+
ws_url, token = _connect_args(deployment_id, pod, shell_type)
52+
exit_code = asyncio.run(exec_session(ws_url, token, " ".join(command)))
5853
sys.exit(exit_code)

centml/sdk/shell/__init__.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,14 @@
11
"""SDK shell module -- reusable shell/exec session logic (no Click dependency)."""
22

33
from centml.sdk.shell.exceptions import NoPodAvailableError, PodNotFoundError, ShellError
4-
from centml.sdk.shell.renderer import char_to_sgr, color_sgr, pyte_extract_text, render_dirty
5-
from centml.sdk.shell.session import (
6-
BEGIN_MARKER,
7-
END_MARKER,
8-
PRINTF_BEGIN,
9-
PRINTF_END,
10-
build_ws_url,
11-
exec_session,
12-
forward_io,
13-
interactive_session,
14-
resolve_pod,
15-
)
4+
from centml.sdk.shell.session import build_ws_url, exec_session, interactive_session, resolve_pod
165

176
__all__ = [
187
"ShellError",
198
"NoPodAvailableError",
209
"PodNotFoundError",
21-
"color_sgr",
22-
"char_to_sgr",
23-
"render_dirty",
24-
"pyte_extract_text",
2510
"build_ws_url",
2611
"resolve_pod",
27-
"forward_io",
2812
"interactive_session",
2913
"exec_session",
30-
"BEGIN_MARKER",
31-
"END_MARKER",
32-
"PRINTF_BEGIN",
33-
"PRINTF_END",
3414
]

centml/sdk/shell/session.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ async def interactive_session(ws_url, token):
178178
"""
179179
fd = sys.stdin.fileno()
180180
old_settings = termios.tcgetattr(fd)
181+
loop = asyncio.get_running_loop()
182+
signals_installed = False
181183
try:
182184
tty.setraw(fd)
183185
cols, rows = shutil.get_terminal_size()
@@ -189,11 +191,10 @@ async def interactive_session(ws_url, token):
189191
sys.stdout.buffer.write(b"\033[?1049h\033[2J\033[H")
190192
sys.stdout.buffer.flush()
191193

192-
loop = asyncio.get_running_loop()
193-
194194
shutdown = asyncio.Event()
195195
loop.add_signal_handler(signal.SIGTERM, shutdown.set)
196196
loop.add_signal_handler(signal.SIGHUP, shutdown.set)
197+
signals_installed = True
197198

198199
headers = {"Authorization": f"Bearer {token}"}
199200
async with websockets.connect(ws_url, additional_headers=headers, close_timeout=2) as ws:
@@ -214,8 +215,9 @@ def _send_resize():
214215

215216
return exit_code
216217
finally:
217-
loop.remove_signal_handler(signal.SIGTERM)
218-
loop.remove_signal_handler(signal.SIGHUP)
218+
if signals_installed:
219+
loop.remove_signal_handler(signal.SIGTERM)
220+
loop.remove_signal_handler(signal.SIGHUP)
219221
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
220222
# Leave alternate screen buffer, restore cursor and attributes.
221223
sys.stdout.buffer.write(b"\033[?1049l\033[?25h\033[0m")

0 commit comments

Comments
 (0)