Skip to content

Commit

Permalink
Added 'widget' to execute_method, getAttribute & listAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Fleming committed Jan 31, 2024
1 parent a293470 commit 9711add
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 30 deletions.
138 changes: 126 additions & 12 deletions examples/generic.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,20 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import ipylab\n",
"\n",
"import ipywidgets as ipw\n",
"app = ipylab.JupyterFrontEnd()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'ipylab_BE': '83a513b1-0ab3-443f-9521-b740be0b8cd3', 'operation': 'FE_execute', 'kwgs': {'FE_execute': {'mode': 'execute_method', 'kwgs': {'method': 'listAttributes'}}, 'args': ('app.shell', 'function', 2)}, 'transform': <TransformMode.raw: 'raw'>}\n"
]
}
],
"outputs": [],
"source": [
"t = app.listMethods(\"app.shell\", depth=2)"
]
Expand Down Expand Up @@ -291,6 +283,128 @@
"source": [
"t = app.listAttributes(\"app.shell\", depth=2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## IpyWidgets\n",
"\n",
"It is also possible to run the same methods of `JupyterFrontEnd` on widgets by using the argument `widget`. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "2c8304bc05c34d01930c0f0a925bcc96",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HTML(value='<h3>Hello world</h3>')"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"widget = ipw.HTML('<h3>Hello world</h3>')\n",
"widget"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"t = app.listAttributes(widget=widget)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'string': ['cid', 'model_id', 'name', 'module', '_listenId'],\n",
" 'object': ['attributes',\n",
" '_previousAttributes',\n",
" 'changed',\n",
" '_buffered_state_diff_synced',\n",
" '_expectedEchoMsgIds',\n",
" '_attrsToUpdate',\n",
" 'widget_manager',\n",
" 'views',\n",
" 'state_change',\n",
" '_state_lock',\n",
" '_msg_buffer',\n",
" '_msg_buffer_callbacks',\n",
" '_buffered_state_diff',\n",
" 'comm',\n",
" '_events',\n",
" '_listeners'],\n",
" 'boolean': ['_changing', '_pending', '_closed', '_comm_live'],\n",
" 'undefined': ['id'],\n",
" 'number': ['_pending_msgs'],\n",
" 'function': ['constructor', 'defaults']}"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t.result()"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"t = app.getAttribute('views', widget=widget)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'70e808ce-e8a0-46ae-8278-62d1583c35d7': {}}"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t.result()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x"
]
}
],
"metadata": {
Expand Down
34 changes: 18 additions & 16 deletions ipylab/asyncwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ def execute_method(
*args,
callback: Callable[[any, any], None | Coroutine] = None,
transform: TransformMode | dict[str, str] = TransformMode.raw,
widget: Widget | None = None,
) -> asyncio.Task:
"""Call a method on the corresponding frontend object.
Expand All @@ -331,9 +332,7 @@ def execute_method(
operation="FE_execute",
FE_execute={
"mode": "execute_method",
"kwgs": {
"method": method,
},
"kwgs": {"method": method, "widget": pack(widget)},
},
transform=transform,
callback=callback,
Expand All @@ -346,9 +345,16 @@ def getAttribute(
*,
callback: Callable[[any, any], None | Coroutine] = None,
transform: TransformMode | dict[str, str] = TransformMode.raw,
widget: Widget | None = None,
):
"""A serialized verison of the attribute relative to this object."""
return self.execute_method("getAttribute", path, callback=callback, transform=transform)
return self.execute_method(
"getAttribute",
path,
callback=callback,
transform=transform,
widget=widget,
)

def listMethods(self, path: str = "", depth=2, skip_hidden=True) -> asyncio.Task[list[str]]:
"""Get a list of methods belonging to the object 'path' of the Frontend instance.
Expand All @@ -371,6 +377,7 @@ def listAttributes(
how="group",
callback: Callable[[any, any], None | Coroutine] = None,
transform: TransformMode | dict[str, str] = TransformMode.raw,
widget: Widget | None = None,
) -> asyncio.Task[dict | list]:
"""Get a mapping of attributes of the object at 'path' of the Frontend instance.
Expand All @@ -393,16 +400,11 @@ def callback_(content: dict, payload: list):
return payload

return self.execute_method(
"listAttributes", path, type, depth, callback=callback_, transform=transform
"listAttributes",
path,
type,
depth,
callback=callback_,
transform=transform,
widget=widget,
)


{
"ipylab_BE": "83a513b1-0ab3-443f-9521-b740be0b8cd3",
"operation": "FE_execute",
"kwgs": {
"FE_execute": {"mode": "execute_method", "kwgs": {"method": "listAttributes"}},
"args": ("app.shell", "function", 2),
},
"transform": "raw",
}
8 changes: 6 additions & 2 deletions src/widgets/ipylab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
IBackboneModelOptions,
ISerializers,
IWidgetRegistryData,
WidgetModel
WidgetModel,
unpack_models
} from '@jupyter-widgets/base';
import { ILabShell, JupyterFrontEnd, LabShell } from '@jupyterlab/application';
import { ICommandPalette } from '@jupyterlab/apputils';
Expand Down Expand Up @@ -157,8 +158,11 @@ export class IpylabModel extends DOMWidgetModel {
delete (payload as any).FE_execute;
switch (mode) {
case 'execute_method': {
let obj = this;
if (kwgs.widget)
obj = await unpack_models(kwgs.widget, this.widget_manager);
const owner = getNestedObject(
this,
obj,
kwgs.method.split('.').slice(0, -1).join('.')
);
var func = getNestedObject(this, kwgs.method) as Function;
Expand Down

0 comments on commit 9711add

Please sign in to comment.