-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python object inspector for the Jupyter Notebook #7873
Comments
Good, you saw the existing variable explorer extension. There is also a lot of work going into the debugger extension, which has a variable inspector: https://github.com/jupyterlab/debugger
I would have suggested ipyevents, but apparently you already tried that. Can ipyevents be extended to give target information? If you do go custom, writing a custom widget extension has the advantage that it may work in other frontends |
I've asked @mwcraig to comment. The debugger looks promising. When does it come out of beta? ;) |
Not sure. They are working hard on it. |
+1 to a structured representation of objects, Polynote does a decent job of this for Scala. I played around with a library to do this in Colab a while back, an example is: https://colab.research.google.com/gist/blois/e432e3aa45de92a09baf9a6644269a0e/copy-of-inspector.ipynb (need to execute the notebook to expand the objects). All of the code for that one is https://github.com/blois/colab_inspector/tree/master/source/inspector. |
@blois, thanks, I'll have a look. |
Thanks @allefeld for sharing that, it looks good. For now the variable inspector in the debugger extension (which can be tested on Binder) is still being iterated on. The goal is to keep it language agnostic and use standard calls from the Debug Adapter Protocol (see this JEP) to request variables from the kernel. There is also a table view, which can be more convenient to inspect other types of variables and for other categories of users. |
After thinking about this some more, I realized it's not enough to be able to listen to mouse events and get their target. To expand a subtree in response to a click I would need to be able to manipulate the DOM of an So as far as I can tell, there is no way around creating a new widget, which would need an extension. I tried to follow Building a Custom Widget - Email widget, but I can't even get this example to work (chokes on cell Please tell me if I'm wrong. |
Sorry, for the incessant commenting, I hope this stuff is interesting for someone beside me, at least for future reference. In the meantime I found I also found I believe
Anyone care to create |
@allefeld - I don't know that it does what you're after but it's kind of neat: |
As mentioned in my response from nteract/vdom#83, my project idom (inspired byvdom) is probably the closest you're going to get to arbitrary DOM manipulation. You can try it out in this notebook. |
I created a first draft of a package for an interactive Python object and data inspector for the Jupyter Notebook. https://github.com/allefeld/ipyinspector Subnodes are created as parent items are expanded, based on the functionality of It also uses Comments welcome! Optimally as issues on the repository. I'm not sure it makes sense to create a PyPI package for such a small amount of code (~170 lines), so I invite comments on how to best publish this. |
@blois I think google colab removed some functions on the frontend so this example doesn't work anymore. |
I'm having trouble getting edit: doesn't work in google colab either :( import idom
import idom_jupyter
from typing import Mapping, Collection
DEFAULT_STYLE = """
.idom-inspector-key-repr {
font-weight: bold;
padding-right: 10px;
margin-right: 5px;
border-right: 1px solid black;
}
"""
@idom.component
def Inspector(value, style=DEFAULT_STYLE):
return idom.html.div(
{"class": "idom-inspector"},
idom.html.style(style),
idom.html.ul(Node("root", value))
)
@idom.component
def Node(key, value):
is_open, set_is_open = idom.hooks.use_state(False)
if not is_open:
fields = {}
else:
if isinstance(value, Mapping):
fields = dict(value)
elif isinstance(value, Collection) and not isinstance(value, str):
fields = {i: v for i, v in enumerate(value)}
elif hasattr(value, "__dict__"):
fields = {k: v for k, v in value.__dict__.items() if not k.startswith("_")}
elif hasattr(value, "__slots__"):
slots = [value.__slots__] if isinstance(value.__slots__, str) else value.__slots__
fields = {k: getattr(value, k) for k in slots}
else:
fields = {}
if is_open:
disabled = not fields
else:
disabled = False
return idom.html.li(
idom.html.input(
{
"class": "idom-inspector-open-button",
"type": "checkbox",
"onClick": lambda event: set_is_open(not is_open),
"disabled": disabled,
}
),
idom.html.label(
{"class": "idom-inspector-repr-container"},
idom.html.span({"class": "idom-inspector-key-repr"}, str(key)),
idom.html.span({"class": "idom-inspector-value-repr"}, str(value))
),
idom.html.ul(
[Node(k, v) for k, v in fields.items()]
)
) |
@Kreijstal I just updated my code- it was using a browser feature which has since been removed (custom elements v0). |
Update: |
I'm not entirely sure this is the right place, if not sorry & please redirect me.
It is a mixture between a feature suggestion and a request for comments.
When working with JavaScript, I very much appreciate the object inspector that comes with Chrome's Developer Tools Console:
I think it would be great to have something like that for use within a Python notebook.
So I started to make a very rough draft:
This draft implementation creates HTML for the nested list and shows it using
IPython.display.HTML
. It also injects some CSS for styling and JavaScript to make list items expandable / collapsable. So far so good.The problem is that Python object hierarchies are huge (actually infinite, because every object's
__class__
is also an object with a__class__
, etc.), so I have to limit the hierarchy to a few levels.A better approach would be to dynamically generate subtrees when items are expanded. For that I would need to make the Python implementation aware of JavaScript
click
events. I tried ipyevents, but it does not give event target information, and the requiredipywidgets.HTML
(instead ofIPython.display.HTML
) apparently messes with my CSS & JS.Questions:
Just to be sure, no such interactive object inspector exists yet, right? I checked but I may have missed something. There is the variable inspector extension, but it doesn't allow exploring object hierarchies in the way I have in mind.
What would be the most straightforward way to send detailed JS event information to Python, or to request additional HTML elements from Python? I know that an extension could do this, but is there a way short of that complexity?
Any other comments / recommendations?
Thanks!
The text was updated successfully, but these errors were encountered: