MCPcopy Index your code
hub / github.com/commandoperator/cmdop-sdk / Transport

Class Transport

python/src/cmdop/_transport.py:87–303  ·  view source on GitHub ↗

Owns one persistent ``cmdop-core`` subprocess and the id-mux over it.

Source from the content-addressed store, hash-verified

85
86
87class Transport:
88 """Owns one persistent ``cmdop-core`` subprocess and the id-mux over it."""
89
90 def __init__(self, cfg: ClientConfig, bin_path: str) -> None:
91 self._cfg = cfg
92 self._bin = bin_path
93 self._proc: asyncio.subprocess.Process | None = None
94 self._reader_task: asyncio.Task | None = None
95 self._stderr_task: asyncio.Task | None = None
96 self._pending: dict[int, _Pending] = {}
97 self._next_id = 1
98 self._closed = False
99 self._start_lock = asyncio.Lock()
100
101 # -- lifecycle ---------------------------------------------------------
102
103 async def _ensure_started(self) -> asyncio.subprocess.Process:
104 if self._proc is not None:
105 return self._proc
106 async with self._start_lock:
107 if self._proc is not None:
108 return self._proc
109 env = {
110 **os.environ,
111 "CMDOP_TOKEN": self._cfg.token,
112 "CMDOP_BASE_URL": self._cfg.base_url,
113 # Django platform plane (skills) — separate credential + base URL.
114 "CMDOP_API_BASE_URL": self._cfg.api_base_url,
115 }
116 if self._cfg.api_key:
117 env["CMDOP_API_KEY"] = self._cfg.api_key
118 proc = await asyncio.create_subprocess_exec(
119 self._bin,
120 "--stdio",
121 stdin=asyncio.subprocess.PIPE,
122 stdout=asyncio.subprocess.PIPE,
123 stderr=asyncio.subprocess.PIPE,
124 env=env,
125 )
126 self._proc = proc
127 self._reader_task = asyncio.create_task(self._read_loop())
128 self._stderr_task = asyncio.create_task(self._drain_stderr())
129 return proc
130
131 async def _drain_stderr(self) -> None:
132 """Drain the core's stderr so its diagnostics never block / corrupt the
133 protocol pipe. We discard it (set CMDOP_DEBUG=1 to have the core log to a
134 file); a host that wants it can read the core's log file."""
135 assert self._proc is not None and self._proc.stderr is not None
136 try:
137 while True:
138 line = await self._proc.stderr.readline()
139 if not line:
140 return
141 except Exception: # noqa: BLE001 - stderr drain must never raise
142 return
143
144 async def _read_loop(self) -> None:

Callers 3

__init__Method · 0.90
_make_transportFunction · 0.90
_make_transportFunction · 0.90

Calls

no outgoing calls

Tested by 2

_make_transportFunction · 0.72
_make_transportFunction · 0.72