# Custom front-end talking to remote iPython Kernel: Blank response instead of 'execute\_reply'

**URL:** <https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229>\
**Category:** Kernels\
**Tags:** how-to, help-wanted\
**Created:** [August 5, 2022, 12:33am UTC](https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229 "2022-08-05T00:33:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![levlzer0](https://avatars.discourse-cdn.com/v4/letter/l/8491ac/32.png) [@levlzer0](https://discourse.jupyter.org/u/levlzer0)\
**Post date:** [August 5, 2022, 12:33am UTC](https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229/1 "2022-08-05T00:33:49Z")

</div>

Hi All,

I’m building a web python ‘notebook’ that would execute python code against a remote iPython kernel.

I am running to issues with communicating to the remote kernel from my custom front-end.

For development, I have both front-end (web notebook) and ipython kernel running in local. iPython kernel is deployed and running in a docker container. Front-end is a simple nodejs program that uses zeroMQ to send requests to iPython kernel. I have studied the [messaging protocol](https://ipython.readthedocs.io/en/1.x/development/messaging.html) and understand that the python code to be executed has to sent as msg type ‘execute\_request’ and the response would be of msg type ‘execute\_reply’.  
I’m able to send a valid ‘execute\_request’ after signing the message but the response I receive is blank. Though I can see that the remote iPython kernel generating the ‘execute\_reply’ message.

ipython kernel log:

```auto
[IPKernelApp] Created profile dir: '/home/myuser/.ipython/profile_default'
[IPKernelApp] Searching path ['/home/myuser/.ipython/profile_default', '/usr/etc/ipython', '/usr/local/etc/ipython', '/etc/ipython'] for config files
[IPKernelApp] Attempting to load config file: ipython_config.py
[IPKernelApp] Looking for ipython_config in /etc/ipython
[IPKernelApp] Looking for ipython_config in /usr/local/etc/ipython
[IPKernelApp] Looking for ipython_config in /usr/etc/ipython
[IPKernelApp] Looking for ipython_config in /home/myuser/.ipython/profile_default
[IPKernelApp] Attempting to load config file: ipython_kernel_config.py
[IPKernelApp] Looking for ipython_kernel_config in /etc/ipython
[IPKernelApp] Looking for ipython_kernel_config in /usr/local/etc/ipython
[IPKernelApp] Looking for ipython_kernel_config in /usr/etc/ipython
[IPKernelApp] Looking for ipython_kernel_config in /home/myuser/.ipython/profile_default
[IPKernelApp] Loading connection file /home/myuser/connection-file.json
[IPKernelApp] Starting the kernel at pid: 1
[IPKernelApp] shell ROUTER Channel on port: 39807
[IPKernelApp] stdin ROUTER Channel on port: 45359
[IPKernelApp] control ROUTER Channel on port: 40673
[IPKernelApp] iopub PUB Channel on port: 41097
[IPKernelApp] Heartbeat REP Channel on port: 49695
[IPKernelApp] Writing connection file: /home/myuser/connection-file.json
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing /home/myuser/connection-file.json
NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work.

To exit, you will have to explicitly quit this process, by either sending
"quit" from a client, or using Ctrl-\ in UNIX-like environments.

To read more about this, see https://github.com/ipython/ipython/issues/2049

To connect another client to this kernel, use:
    --existing /home/myuser/connection-file.json
[IPKernelApp] Seeing logger to stderr, rerouting to raw filedescriptor.
[IPKernelApp] Loading IPython extensions...
[IPKernelApp] Loading IPython extension: storemagic
[IPKernelApp] 
***MESSAGE TYPE:execute_request***
[IPKernelApp] Content: {'code': 'print("Hello world!")', 'silent': False, 'store_history': True, 'user_expressions': {}, 'allow_stdin': False, 'stop_on_error': True}
   --->
   
[IPKernelApp] execute_request: {'header': {'msg_id': 'db3792b4-0728-405c-9cac-5347b2724ad6', 'msg_type': 'execute_request', 'date': datetime.datetime(2022, 8, 4, 22, 40, 14, 903096, tzinfo=datetime.timezone.utc), 'version': '5.0'}, 'msg_id': 'db3792b4-0728-405c-9cac-5347b2724ad6', 'msg_type': 'execute_request', 'parent_header': {}, 'metadata': {}, 'content': {'code': 'print("Hello world!")', 'silent': False, 'store_history': True, 'user_expressions': {}, 'allow_stdin': False, 'stop_on_error': True}, 'buffers': []}
[IPKernelApp] {'header': {'msg_id': '7ed44e24-674afba1bf1df2f4a224aff3_1_5', 'msg_type': 'execute_reply', 'username': 'username', 'session': '7ed44e24-674afba1bf1df2f4a224aff3', 'date': datetime.datetime(2022, 8, 4, 22, 40, 14, 917864, tzinfo=datetime.timezone.utc), 'version': '5.3'}, 'msg_id': '7ed44e24-674afba1bf1df2f4a224aff3_1_5', 'msg_type': 'execute_reply', 'parent_header': {'msg_id': 'db3792b4-0728-405c-9cac-5347b2724ad6', 'msg_type': 'execute_request', 'date': datetime.datetime(2022, 8, 4, 22, 40, 14, 903096, tzinfo=datetime.timezone.utc), 'version': '5.0'}, 'content': {'status': 'ok', 'execution_count': 1, 'user_expressions': {}, 'payload': []}, 'metadata': {'started': datetime.datetime(2022, 8, 4, 22, 40, 14, 904511, tzinfo=datetime.timezone.utc), 'dependencies_met': True, 'engine': 'aac4c779-9b2d-4ec6-a932-7c230c31e6e6', 'status': 'ok'}, 'tracker': <zmq.sugar.tracker.MessageTracker object at 0x7f9a3468a890>}
[IPKernelApp] 
***MESSAGE TYPE:execute_request***
[IPKernelApp] Content: {'code': 'print("Hello world!")', 'silent': False, 'store_history': True, 'user_expressions': {}, 'allow_stdin': False, 'stop_on_error': True}
   --->

```

This is my nodejs program:

```auto
const zmq = require("zeromq");
const crypto = require("crypto");
const { v4: uuidv4 } = require('uuid');

const shell_socket = zmq.socket('dealer');
let shell_addr = "tcp://localhost:39807";

console.log("\nConnecting shell socket at " + shell_addr + "...");
shell_socket.connect(shell_addr);

shell_socket.on("message", function(msg){
  console.log("\nShell socket says:\n");
  console.log("output:", msg.toString())
});

let key = <key>;
let header = {"msg_id": uuidv4(), "msg_type": "execute_request"};
let parent_header = {};
let metadata = {};
let content = {'code': 'print("Hello world!)")',
                'silent': false,
                'store_history': true,
                'user_expressions': {},
                'allow_stdin': false,
                'stop_on_error': true };

let sign = JSON.stringify(header)
              + JSON.stringify(parent_header)
              + JSON.stringify(metadata)
              + JSON.stringify(content);
let hmac_digest = crypto.createHmac("sha256", key).update(sign).digest("hex");

shell_socket.send(["","<IDS|MSG>",hmac_digest,
          JSON.stringify(header),
          JSON.stringify(parent_header),
          JSON.stringify(metadata),
          JSON.stringify(content)]);

```

Output:

```auto
~/workspace/web_notebook$ node index.js 

Connecting shell socket at tcp://localhost:39807...

Shell socket says:

output: 

```

I am not able to figure out what I’m doing wrong. Could someone guide me or point to any resource that can help? I looked online for a working example but nothing exists for a non python client.  
I have tried both ‘req’ and ‘dealer’ socket with zeroMQ and the behavior is the same.

Note: Using jupyter console pointed to the remote kernel in the same setup works fine.

```auto
/workspace/web_notebook$ jupyter console --existing connection-file.json 
Jupyter console 6.4.4

Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: print("Hello world!")
Hello world!

In [2]:

```

connection-file.json

```auto
{
  "shell_port": 39807,
  "iopub_port": 41097,
  "stdin_port": 45359,
  "control_port": 40673,
  "hb_port": 49695,
  "ip": "0.0.0.0",
  "key": <key>,
  "transport": "tcp",
  "signature_scheme": "hmac-sha256",
  "kernel_name": ""
}

```

---

<div class="post-metadata">

**Author:** ![bollwyvl](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/bollwyvl/32/904_2.png) [@bollwyvl](https://discourse.jupyter.org/u/bollwyvl)\
**Post date:** [August 6, 2022, 9:45pm UTC](https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229/2 "2022-08-06T21:45:58Z")

</div>

As the reference implementation, the [`jupyter_client` code base](https://github.com/jupyter/jupyter_client/) has the most concrete and up-to-date implementation information, and is _de facto_ the “real” specification.

In the nodejs world, there’s also the [ijavascript](https://github.com/n-riesco/ijavascript) stack which has some pieces which may be relevant.

Either way, the debugging effort might benefit from getting [wireshark](https://www.wireshark.org/) up and running so that traces can be compared between different implementations.

---

<div class="post-metadata">

**Author:** ![levlzer0](https://avatars.discourse-cdn.com/v4/letter/l/8491ac/32.png) [@levlzer0](https://discourse.jupyter.org/u/levlzer0)\
**Post date:** [August 7, 2022, 4:39pm UTC](https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229/3 "2022-08-07T16:39:27Z")

</div>

@bollwyvl Thank you for your suggestion. Let me have a look at the ijavascript and see if it can help me.

Meanwhile, I placed the nodejs program and ipython within the same docker container and ran the program, the response is still blank.

I also figured there is an [open stack overflow thread](https://stackoverflow.com/questions/29448354/talking-to-an-ipython-kernel-with-node-js-no-response-to-kernel-info-request) from years ago with the same issue that I am running into.

---

<div class="post-metadata">

**Author:** ![Appsky](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/appsky/32/10107_2.png) [@Appsky](https://discourse.jupyter.org/u/Appsky)\
**Post date:** [June 8, 2023, 6:10am UTC](https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229/4 "2023-06-08T06:10:21Z")

</div>

Hi @levlzer0 , were you able to fix it?

The callback of shell\_socket.on is returning more than one parameter.

```auto
shell_socket.on("message", function(...msg){
 console.log("\nShell socket says:\n");
 console.log("output:", msg.toString())
});

```

Also, there is a JS library that can serve as a client [n-riesco](https://github.com/n-riesco)/**[jmp](https://github.com/n-riesco/jmp)**

But I was not able to get the result of the code.

---

<div class="post-metadata">

**Author:** ![Appsky](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/appsky/32/10107_2.png) [@Appsky](https://discourse.jupyter.org/u/Appsky)\
**Post date:** [June 8, 2023, 3:26pm UTC](https://discourse.jupyter.org/t/custom-front-end-talking-to-remote-ipython-kernel-blank-response-instead-of-execute-reply/15229/5 "2023-06-08T15:26:47Z")

</div>

I fixed my issue, I had to subscribe on iopub\_socket

```auto
iopub_socket.subscribe('');

```
