Accessing cell subelements using API

I’m currently working on an extension in which I would like to modify and annotate certain cells based on a serverside extension. As part of this I need to at various points access specific children of the CodeCell.

From reading the documentation, the best way I can find to do this is to do something like this.

private getOutputPrompt(cell : Cell) : OutputPrompt {
  var top_iter = cell.children();
  top_iter.next();
  top_iter.next();
  let output : Widget = top_iter.next();
  if (output != undefined) {
    var output_iter = output.children();
    let outputprompt : Widget = output_iter.next();
    if (isinstance(outputprompt, OutputPrompt)) { return (outputprompt as OutputPrompt); }
  }
  return undefined;

This seems not super ideal - it’s relatively verbose, and seems kind of fragile. Maybe it’s just that I don’t know lumino or typescript very well, but is there a better way to do this?

Yeah: some of the smaller bits and bobs aren’t really part of the API of the core notebook implementation.

If you can describe your use case very concisely, preferably with an example/mockup, you might be able to lobby for an issue requesting a new extension point. Maybe lots of users want OutputPromptBling (i’m interested!), and there needs to be a convenient place for developers to add them (i’d abuse the hell out of this, avoiding context menus, e.g. New View, Switch Renderer).

Luckily that particular piece could use Cell.outputArea with find (give the docs, and the core source code, a chance, they’re not too bad to read!):

import {find} from '@lumino/algorithm'
import {Widget} from '@lumino/widgets'
import {OutputPrompt} from '@jupyterlab/outputarea'
import {CodeCell} from '@jupyterlab/cells'

function isOP(w: Widget): boolean { 
  return w instanceof OutputPrompt;
}
export function prompt(c: CodeCell): OutputPrompt{ 
  return find(c.outputArea.widgets, isOP) as OutputPrompt;
}

Is it relatively verbose? Sure. But from a fragility standpoint:

  • if someone had an alternate Notebook, sure, you be doomed
  • if the core API changes in the future, the types will keep you safe (or at least you’ll know there are 99 errors (take one down, pass it around) before getting it to compile, rather than it it just breaking mysteriously for a user.

To the latter point: pull in as little as you can, pin as hard as you can to core, sanely (e.g. ~2.2.2), and make it easy on yourself to do new releases or builds. I would personally prefer to get a support issue like…

Your extension won’t install with my version of Lab. Plz fix.

than…

Your extension installed fine in the version of Lab that came out yesterday, but then ate my dissertation HALP.

Best of luck!

Thanks! I hadn’t thought to see if lumino had something that could be used for this purpose. And yeah, that’s a good point about using the type system to avoid compilation errors.