The IPython spec allows for a very restricted set of messages, and particularly one for executing a string of code. This requires that for any communication to change the state of the user namespace on the server, or to perform a computation and receive output, the client must form a valid python string of code. This is error-prone and ignores the richer facilities we have for passing data back and forth between the client and the server.
Another way to look at it is: the IPython server has the ability to pass rich data (i.e., JSON) to the client, but the client can only pass strings back to the server to execute. This IPEP provides a way for the client to pass JSON back to a custom message handler on the server.
Since the kernel dispatches messages, the kernel is the place to add a function for dispatching custom messages to a custom message handler, based on the message type. A new method should be added to the shell object returned from
get_ipython() which registers a handler with the kernel. This seems a bit klunky, given that the shell doesn't really reference the kernel currently. Alternatively, a new function can be injected into the user space somehow directly by the kernel to register a method handler.
Here are two ideas for dealing with how to encode message types:
custommessage type that is added to the spec, and then the message handler is chosen based on a new subtype field, or on a
msg_typeattribute in the content dictionary. This preserves the top-level message type namespace by just nesting custom messages into the content field. It also nicely isolates the user code from the routing information in the message header. However, it might be wasteful to basically embed messages inside of other messages
matplotlib.image_update). The top-level namespace is preserved for the IPython message spec. This puts the IPython core messages on the same level as custom message handlers.
_request, like the IPython ones do?
matplotlib.update, then should a
matplotlib.update_replymessage type automatically be created for a return message (and return status of the handler, etc.)? This would mirror the
I see little reason to provide a message handler with more than the content and the metadata dictionaries.
silent=Truemight imply this)
execute_requesthandling. This functionality should be abstracted out to a context manager.
Jason Grout has some experiments he has been doing with custom messages and implementing Sage interacts, available in his sagecell code, diffs at https://github.com/jasongrout/sagecell/compare/interact-messages. These won't apply directly, of course, but give the idea of what sorts of things need to be considered.
Jason Grout submitted a (now closed) pull request for custom message handlers: https://github.com/ipython/ipython/pull/1700. A lot of discussion there informed some of the options presented in this IPEP.