Welp: we don’t really know what you’re trying to build, so just relying on experience of doing weird things that are sometimes surprising to users.
The client, kernel process and notebook process(es) are intentionally very separate concerns, and typically don’t share much directly… while the server (and therefore any server extension) knows where the kernel actually is, the client generally won’t have access to that information, directly. And the kernel will generally have no idea how to talk directly to the server’s REST API.
One can’t rely on most of the above pieces sharing the same environment variables, file system, user, IP address, port, or computer, as kernels and servers can be launched in all kinds of different ways, from a “traditional” localhost:8888
to JupyterHub, (Enterprise) Kernel Gateway. Then there’s totally insane stuff like JupyterLite.
When a kernel finally does appear to the user in the UI, which harmonizes all these possible deployment scenarios, things that appear in a notebook but aren’t computable by the kernel may well be very surprising to a user. There’s also no way that one could persist what was being done with the thing (whatever it is) unless it exists within the .ipynb
, as saved: this can be achieved by manipulating the cells or the notebook’s metadata.
The snippet approach accepts that pretty much all “programming language” kernels (there are niche ones, like SQL) will probably be able to access a REST API (e.g. requests
for python
, curl
for bash
).
# snippet created with my-extension
import requests, IPython
my_data = requests.get("https://my-server/api/my-rest-api?token=abc1234").json()
IPython.display({"application/my-data+json": my_data}, raw=True)
…then your UI would be displayed, and the user would have access to the underlying data.
The higher-touch approach, with ipywidgets
, would potentially be a better integration, but at the end of it, won’t provide much more computable value than the API, and can be hard to reason about wrapping a REST service with an evented API/GUI.
Yet another approach, if your endpoint has an OpenAPI description, would be to generate and ship language-specific bindings with e.g. swagger-codegen, but this brings a raft of other challenges.