Spaces:
Paused
Paused
from asyncio import create_subprocess_exec, subprocess | |
class Terminal: | |
""" | |
Class for running terminal commands asynchronously. | |
Methods: | |
run(commands: str) | |
commands: Terminal Commands. | |
Returns Process id (int) | |
terminate(pid: int) | |
pid: Process id returned in `run` method. | |
Returns True if terminated else False (bool) | |
output(pid: int) | |
pid: Process id returned in `run` method. | |
Returns Output of process (str) | |
error(pid: int) | |
pid: Process id returned in `run` method. | |
Returns Error of process (str) | |
""" | |
def __init__(self) -> None: | |
self._processes = {} | |
def _to_str(data: bytes) -> str: | |
return data.decode("utf-8").strip() | |
async def run(self, *args) -> int: | |
process = await create_subprocess_exec( | |
*args, stdout=subprocess.PIPE, stderr=subprocess.PIPE | |
) | |
pid = process.pid | |
self._processes[pid] = process | |
return pid | |
def terminate(self, pid: int) -> bool: | |
try: | |
self._processes.pop(pid) | |
self._processes[pid].kill() | |
return True | |
except KeyError: | |
return False | |
async def output(self, pid: int) -> str: | |
output = [] | |
while True: | |
out = self._to_str(await self._processes[pid].stdout.readline()) | |
if not out: | |
break | |
output.append(out) | |
return "\n".join(output) | |
async def error(self, pid: int) -> str: | |
error = [] | |
while True: | |
err = self._to_str(await self._processes[pid].stderr.readline()) | |
if not err: | |
break | |
error.append(err) | |
return "\n".join(error) | |
def _auto_remove_processes(self) -> None: | |
while self._processes: | |
for proc in self._processes.keys(): | |
if proc.returncode is not None: # process is still running | |
try: | |
self._processes.pop(proc) | |
except KeyError: | |
pass | |
class Executor: | |
pass | |