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 standalone application #2

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

fcollonval
Copy link

@fcollonval fcollonval commented Nov 4, 2024

This PR transforms the repository in a mono-repository with 3 packages:

  • app folder: root package with the webpack configuration and bootstrap code for a standalone web app running on top of a Jupyter Server
  • packages/application folder: stand alone application front-end code
  • packages/lab folder: JupyterLab extension to display a Jupyter Notebook as a Mercury dashboard through a new viewer; it is also consumed by the stand alone app.

The dashboard view, uses only regular Cells. Controller widgets are placed in the sidebar by moving the output area node into it (and hiding the unwanted prompt).

An helper to convert regular ipywidget.Widget (and derived widgets such as anywidget) has been created in mercure_app.decorator.as_controller. Wrapping any widget instance with it will convert the widget in a controller; i.e. when changing the widget model state (e.g. the value of an input text), it will execute all cells below the cell defining the controller.

See the demo:

mercury_dashboard_demo_20241216.mp4

Copy link
Author

@fcollonval fcollonval left a comment

Choose a reason for hiding this comment

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

The current code has the following main short comings:

  • There is no ability to run cells in the new viewer. Therefore the effect of a changed value in a widget is not reflected easily.
  • The widgets are not always placed on the left panel as outputs may appear only later when loading a document.
  • Custom viewer is derived from the notebook viewer. But there are too many copy-paste to make it easy to maintain on the long term. I would suggest to switch to custom ContentFactory instead.

Small things:

  • Set up a proper webpack production configuration
  • Fix loading proper language in code cell editor for syntax highlighting
  • Check the packaging and version bump

Not tested yet:

  • third party ipywidgets

@fcollonval fcollonval marked this pull request as draft November 4, 2024 17:53
@pplonski
Copy link
Contributor

pplonski commented Nov 5, 2024

Thank you @fcollonval! I've cloned your repo and successfully installed standalone app in development version. I was able to start extension in the Jupyter Lab and I was able to run standalone app.

In the standalone app, cells should be re-executed after a widget change. We don't want other cell execution methods. Widget changes are the only way to interact with the notebook. Widgets should be displayed on the left. I plan to create custom wrappers of ipywidgets with additional CSS so they will be displayed on the left. Those two are the most important because they define how the Mercury framework will work.

When I was trying to create standalone app I was using below code:

function main(): void {
  const manager = new ServiceManager();
  void manager.ready.then(() => {
    createApp(manager);
  });
}

function createApp(manager: ServiceManager.IManager): void {

  const notebookPath = PageConfig.getOption('notebookPath');

  // const commands = new CommandRegistry();
  const languages = new EditorLanguageRegistry();
  const rendermime = new RenderMimeRegistry({
    initialFactories: standardRendererFactories,
    // latexTypesetter: new MathJaxTypesetter(),
    // markdownParser: createMarkdownParser(languages)
  });

  const mimeTypeService = new CodeMirrorMimeTypeService(languages);

  const docRegistry = new DocumentRegistry();
  
  const mFactory = new NotebookModelFactory({});
  
  const factoryService = new CodeMirrorEditorFactory({
    //extensions: editorExtensions(),
    //languages
  });
  const editorFactory = factoryService.newInlineEditor;

  const contentFactory = new NotebookPanel.ContentFactory({ editorFactory });
  const wFactory = new MercuryWidgetFactory({
    name: 'Mercury',
    fileTypes: ['notebook'],
    modelName: 'notebook',
    preferKernel: true,
    canStartKernel: true,
    rendermime: rendermime,
    contentFactory,
    editorConfig: StaticNotebook.defaultEditorConfig,
    notebookConfig: StaticNotebook.defaultNotebookConfig,
    mimeTypeService: mimeTypeService, 
    editorFactoryService: factoryService,
    notebookPanel: null
  });
  docRegistry.addModelFactory(mFactory);
  docRegistry.addWidgetFactory(wFactory);


  const opener = {
    open: (widget: Widget) => {
      // Do nothing for sibling widgets for now.
    },
    get opened() {
      return {
        connect: () => {
          return false;
        },
        disconnect: () => {
          return false;
        }
      };
    }
  };
  const docManager = new DocumentManager({
    registry: docRegistry,
    manager,
    opener
  });
  const nbWidget = docManager.open(notebookPath) as MercuryWidget;
  const panel = new Panel();
  panel.id = 'main';
  panel.addWidget(nbWidget);
  Widget.attach(panel, document.body);
}

but above code doesn't display ipywidgets, not sure if you will find it helpful.

@fcollonval
Copy link
Author

Hi @pplonski with the latest commit, the cells below the updated ipywidgets are automatically executed by using a kernel message listener.

demo_mercury_auto_execute_below.mp4

The current code has the following main short comings:

  • Cells below the one outputting a widget are automatically executed if the widget is updated; except if the cell outputs a widget - e.g. in the above video, the cell adding the integer slider, is not re-executed when the input text changes. I don't know if this is the expected behavior or not.
  • The widgets are not always placed on the left panel as outputs may appear only later when loading a document.
  • Custom viewer is derived from the notebook viewer. But there are too many copy-paste to make it easy to maintain on the long term. I would suggest to switch to custom ContentFactory instead.

Small things:

  • Set up a proper webpack production configuration
  • Fix loading proper language in code cell editor for syntax highlighting
  • Check the packaging and version bump

Not tested yet:

  • third party ipywidgets

@fcollonval fcollonval marked this pull request as ready for review December 16, 2024 09:45
@fcollonval
Copy link
Author

Hi @pplonski

I completed the work we discussed. This PR is now ready.

I updated the first comment to reflect the latest status.

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.

2 participants