How to wait until the receive function is not invoked (set the client input in kc.input())?

16 views Asked by At

I am trying to build a Python IDE using the Jupyter client kernel.

My problem is: Not being able to provide the client input in the kc.input() that I receive after sending the prompt: :

await self.send(text_data=json.dumps({'input_request':mseg["content"]["prompt"]}))

need help here

if msg["msg_type"] == "execute_input":
    mseg = kc.get_stdin_msg(timeout=1)
    await self.send(text_data=json.dumps({'input_request':     mseg["content"]["prompt"]}))
     
***I want it to wait until it doesn't receive input (invoke the receive function)***
 
    print("Stored input:", self.input_received)
    kc.input(5)

I try to declare the kc = BlockingKernelClient() in the class so can use in if i received any input but kernel get stop till then.

Full Code

import json

from channels.generic.websocket import AsyncWebsocketConsumer
from jupyter_client import BlockingKernelClient
from jupyter_client import KernelManager

class CodeExecutionConsumer(AsyncWebsocketConsumer):
    input_received = '' 
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
       
    async def connect(self):
        await self.accept()

    async def disconnect(self, close_code):
        pass
    
    async def receive(self, text_data):
        await super().receive(text_data)
        data = json.loads(text_data)
        code = data.get('code', '')
        input_text = data.get('input','')

        if input_text: 
            print("input text:",input_text)
            await self.handle_input(input_text)
        else:
            result = await self.execute_code(code)
            print(code,result)
            # await self.send(text_data=json.dumps({'result': result}))

    async def handle_input(self, input_text):
        print("Received input:", input_text)
        self.input_received = input_text
        
    async def execute_code(self, code):
        kc = BlockingKernelClient()
        kc.load_connection_file(connection_file="./confs/c1.json")
        kc.start_channels()

        try:
            msg_id = kc.execute(code)

            while True:
                msg = kc.get_iopub_msg(timeout=1)
                if msg["msg_type"] == "stream" and msg["content"]["name"] == "stdout":
                    result = msg["content"]["text"]
                    print(result)
                    # break
                    await self.send(text_data=json.dumps({'result': result}))
                    # return result
                elif msg["msg_type"] == "execute_input":
                    mseg = kc.get_stdin_msg(timeout=1)
                    await self.send(text_data=json.dumps({'input_request': mseg["content"]["prompt"]}))
                    # input_data = await self.receive_input(mseg)
                    print("Stored input:", self.input_received)
                    kc.input(5)

        except KeyboardInterrupt:
            return "Code execution interrupted by user."
        except:
            pass
        finally:
            kc.stop_channels()

also if there is any better way to code, please help.

0

There are 0 answers