Skip to content
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

Add support for getters #587

Merged
merged 19 commits into from
Nov 30, 2023
Merged

Conversation

bnmajor
Copy link
Collaborator

@bnmajor bnmajor commented Dec 14, 2022

-- WIP --

Guided by the items discussed in #568 this branch attempts to add support for getter functions. Adapting approaches in the ipython_blocking and jupyter-ui-poll libraries the general approach is to:

  • Temporarily overwrite execute_request handler in IPython in order to collect and queue requests
  • Once the viewer is created the background thread calls execute_next_request to start the cycle of processing the remaining cells
  • Pop requests off one at a time and inspect for getters
    • If getters are found we create a future and attach a callback that sets the result once it is received. Once all results have resolved the cell is re-run so that it may return the results.
    • If no getters are found the request is just run as usual

Issues:

  • Currently the user namespace is not being updated when the cell is re-run properly so cell output is always wrong

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@bnmajor bnmajor force-pushed the getters branch 2 times, most recently from c4df265 to dd42dbf Compare December 14, 2022 03:39
@bnmajor bnmajor force-pushed the getters branch 2 times, most recently from 9a35f4e to 42f05fa Compare December 22, 2022 19:38
Comment on lines 323 to 326
if 'getImageInterpolationEnabled' not in self.results:
self.call_getter('getImageInterpolationEnabled')
elif self.results['getImageInterpolationEnabled'].done():
return self.results.pop('getImageInterpolationEnabled').result()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put this sequence of calls in a decorator?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, updated!

@bnmajor
Copy link
Collaborator Author

bnmajor commented Dec 27, 2022

This approach is making progress but is still a bit naive and has a lot of additional cases/needs to take into account. Starting a list here of key concerns and shortcomings so that they are addressed as this moves forward:

  • We are currently running getters twice - once before and once during cell execution. This approach needs to be re-thought as there are plenty of use cases where this would not return the correct value. ex:
print(viewer.get_axes_enabled()) # False by default
viewer.set_axes_enabled(True)
print(viewer.get_axes_enabled()) # Should be True, will return False
  • Need to confirm that none of the approaches that we settle on inadvertently affect the notebook history or output
  • Currently using regex to identify getters. There are plenty of cases where a getter or setter may not be called directly so this is not a viable approach.

@thewtex
Copy link
Member

thewtex commented Dec 27, 2022

Todos

  • Multiple viewers
  • Test notebook: 1) set, get, throws exceptions
  • Intercept getters during execution instead of after

which should help with all three points above.

-> merge

Create another issue as needed for setting cell output with a getter output.

@thewtex
Copy link
Member

thewtex commented Jan 4, 2023

@bnmajor this timeout only occurs when the tests are executed through nbmake?

@alex-treebeard are notebook events processed in a different way when executed through nbmake?

@thewtex
Copy link
Member

thewtex commented Jan 4, 2023

@alex-treebeard suggested that there may be a to resolve via the way nbmake uses nbclient.

@bnmajor
Copy link
Collaborator Author

bnmajor commented Jan 5, 2023

@thewtex So it seems like the nbmake issue is not actually with the getters/setters but with the fact that in testing the itk-viewer is never actually created (so any cells with getters/setters timeout waiting for it to be created before being run). If I use the --overwrite flag to see the results produced from testing there is no embedded screenshot which seems to backup this theory....

@thewtex
Copy link
Member

thewtex commented Jan 6, 2023

@bnmajor oh, good catch! 💡

Indeed

This widget rendering is not performed against a browser during execution

@oeway any ideas / suggestions / pointers to have ImJoy talk to a headless chromium browser?

@alex-treebeard
Copy link

@thewtex been doing a bit of reading around widgets. Is it necessary to load the browser in order to initialise the ITK widget?

What needs to run in order to unblock the getters from executing against an initialised viewer object?

@thewtex
Copy link
Member

thewtex commented Jan 18, 2023

@alex-treebeard

Is it necessary to load the browser in order to initialise the ITK widget?

It is not necessary to import and run the Python code. However, a browser is necessary for the graphical context and JavaScript environment to perform renderings and work with the client-side widget state.

What needs to run in order to unblock the getters from executing against an initialised viewer object?

One way or another, we need to be talking to, e.g., Chrome / Electron in Headless Mode, when running in nbmake / nbclient.

@alex-treebeard
Copy link

@thewtex have you checked out galata?

It's possible to stand up a jupyter lab instance in a test environment, then we could potentially run nbmake against its kernel.

@thewtex
Copy link
Member

thewtex commented Jan 21, 2023

@alex-treebeard great idea!!

Yes, we could use a version of nb_run.py that uses galata and something along the lines of:

https://github.com/jupyterlab/jupyterlab/blob/2250b956294558de58a99e4a26286270654eb416/galata/test/galata/notebook.spec.ts#L91-L115

Getters are designed with the expectation that they will be called twice. On the
first pass the getter is added to a queue and a callback function is set on each.
Once the getter resolves the result is set in the results dict and getters are
ready to be called again to return their result.
This allows us to grab the cell id and raw cell string for re-running cells
with getters.
Intercept execute_requests (which will be all cells queued to run after the
Viewer class has been instantiated. Once the itk_viewer has been created the
queue is processed one request at a time. If a cell contains getters, futures
are created for each and a callback function is set to set the result as they
resolve. Once all of the results are set the cell is run and the queue
continues to be processed.
@thewtex
Copy link
Member

thewtex commented Nov 30, 2023

Let's merge this, then, in separate PR's

  • Document getters limitations in sphinx
  • Address the JS testing issues

@bnmajor bnmajor marked this pull request as ready for review November 30, 2023 17:54
@bnmajor bnmajor merged commit 3f01065 into InsightSoftwareConsortium:main Nov 30, 2023
6 checks passed
@bnmajor bnmajor deleted the getters branch November 30, 2023 18:39
bnmajor added a commit to bnmajor/itkwidgets that referenced this pull request Dec 11, 2023
Improved testing is a current work in progress (as discussed in issue InsightSoftwareConsortium#587).
Until we resolve the outstanding issues no viewer is actually being created, so
the queue that waits for cell completion before progressing causes all
subsequent cells after the first viewer is created to fail. This temporarily
ignores those cells in the CI tests. These changes should be removed after
testing is fixed.
This was referenced Dec 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants