communicate with docker container and execute command, support stream output Args: command: the command to execute stream_callback: optional callback function, for handling stream output the function signature should be callback(text: str)
(command, stream_callback=None)
| 401 | return {"status": -1, "result": "Response parsing error"} |
| 402 | |
| 403 | def run_command_in_container(command, stream_callback=None): |
| 404 | """ |
| 405 | communicate with docker container and execute command, support stream output |
| 406 | |
| 407 | Args: |
| 408 | command: the command to execute |
| 409 | stream_callback: optional callback function, for handling stream output |
| 410 | the function signature should be callback(text: str) |
| 411 | |
| 412 | Returns: |
| 413 | dict: the complete JSON result returned by the docker container |
| 414 | """ |
| 415 | hostname = 'localhost' |
| 416 | port = 12345 |
| 417 | buffer_size = 4096 |
| 418 | |
| 419 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
| 420 | s.connect((hostname, port)) |
| 421 | s.sendall(command.encode()) |
| 422 | |
| 423 | partial_line = "" |
| 424 | while True: |
| 425 | chunk = s.recv(buffer_size) |
| 426 | if not chunk: |
| 427 | break |
| 428 | |
| 429 | # add new received data to the unfinished data |
| 430 | data = partial_line + chunk.decode('utf-8') |
| 431 | lines = data.split('\n') |
| 432 | |
| 433 | # except the last line, process all complete lines |
| 434 | for line in lines[:-1]: |
| 435 | if line: |
| 436 | try: |
| 437 | response = json.loads(line) |
| 438 | if response['type'] == 'chunk': |
| 439 | # process stream output |
| 440 | if stream_callback: |
| 441 | stream_callback(response['data']) |
| 442 | elif response['type'] == 'final': |
| 443 | # return the final result |
| 444 | return { |
| 445 | 'status': response['status'], |
| 446 | 'result': response['result'] |
| 447 | } |
| 448 | except json.JSONDecodeError: |
| 449 | print(f"Invalid JSON: {line}") |
| 450 | |
| 451 | # save the possibly unfinished last line |
| 452 | partial_line = lines[-1] |
| 453 | |
| 454 | # if the loop ends normally without receiving a final response |
| 455 | return { |
| 456 | 'status': -1, |
| 457 | 'result': 'Connection closed without final response' |
| 458 | } |
| 459 | |
| 460 |
nothing calls this directly
no outgoing calls
no test coverage detected