extension_dev.rst 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. .. _developer_extensions:
  2. Extension Developer Guide
  3. -------------------------
  4. .. warning::
  5. The extension developer API is not stable and will evolve in JupyterLab
  6. releases in the near future.
  7. JupyterLab can be extended in four ways via:
  8. - **application plugins (top level):** Application plugins extend the
  9. functionality of JupyterLab itself.
  10. - **mime renderer extensions (top level):** Mime Renderer extensions are
  11. a convenience for creating an extension that can render mime data and
  12. potentially render files of a given type.
  13. - **theme extensions (top level):** Theme extensions allow you to customize the appearance of
  14. JupyterLab by adding your own fonts, CSS rules, and graphics to the application.
  15. - **document widget extensions (lower level):** Document widget extensions
  16. extend the functionality of document widgets added to the
  17. application, and we cover them in :ref:`documents`.
  18. See :ref:`xkcd_extension_tutorial` to learn how to make a simple JupyterLab extension.
  19. A JupyterLab application is comprised of:
  20. - A core Application object
  21. - Plugins
  22. Plugins
  23. ~~~~~~~
  24. A plugin adds a core functionality to the application:
  25. - A plugin can require other plugins for operation.
  26. - A plugin is activated when it is needed by other plugins, or when
  27. explicitly activated.
  28. - Plugins require and provide ``Token`` objects, which are used to
  29. provide a typed value to the plugin's ``activate()`` method.
  30. - The module providing plugin(s) must meet the
  31. `JupyterLab.IPluginModule <https://jupyterlab.github.io/jupyterlab/application/interfaces/jupyterlab.ipluginmodule.html>`__
  32. interface, by exporting a plugin object or array of plugin objects as
  33. the default export.
  34. We provide two cookie cutters to create JuptyerLab plugin extensions in
  35. `CommonJS <https://github.com/jupyterlab/extension-cookiecutter-js>`__ and
  36. `TypeScript <https://github.com/jupyterlab/extension-cookiecutter-ts>`__.
  37. The default plugins in the JupyterLab application include:
  38. - `Terminal <https://github.com/jupyterlab/jupyterlab/blob/master/packages/terminal-extension/src/index.ts>`__
  39. - Adds the ability to create command prompt terminals.
  40. - `Shortcuts <https://github.com/jupyterlab/jupyterlab/blob/master/packages/shortcuts-extension/src/index.ts>`__
  41. - Sets the default set of shortcuts for the application.
  42. - `Images <https://github.com/jupyterlab/jupyterlab/blob/master/packages/imageviewer-extension/src/index.ts>`__
  43. - Adds a widget factory for displaying image files.
  44. - `Help <https://github.com/jupyterlab/jupyterlab/blob/master/packages/help-extension/src/index.tsx>`__
  45. - Adds a side bar widget for displaying external documentation.
  46. - `File
  47. Browser <https://github.com/jupyterlab/jupyterlab/blob/master/packages/filebrowser-extension/src/index.ts>`__
  48. - Creates the file browser and the document manager and the file
  49. browser to the side bar.
  50. - `Editor <https://github.com/jupyterlab/jupyterlab/blob/master/packages/fileeditor-extension/src/index.ts>`__
  51. - Add a widget factory for displaying editable source files.
  52. - `Console <https://github.com/jupyterlab/jupyterlab/blob/master/packages/console-extension/src/index.ts>`__
  53. - Adds the ability to launch Jupyter Console instances for
  54. interactive kernel console sessions.
  55. A dependency graph for the core JupyterLab plugins (along with links to
  56. their source) is shown here: |dependencies|
  57. .. danger::
  58. Installing an extension allows for arbitrary code execution on the
  59. server, kernel, and in the client's browser. You should therefore
  60. take steps to protect against malicious changes to your extension's
  61. code. This includes ensuring strong authentication for your npm
  62. account.
  63. Application Object
  64. ~~~~~~~~~~~~~~~~~~
  65. The JupyterLab Application object is given to each plugin in its
  66. ``activate()`` function. The Application object has a:
  67. - commands - used to add and execute commands in the application.
  68. - keymap - used to add keyboard shortcuts to the application.
  69. - shell - a JupyterLab shell instance.
  70. JupyterLab Shell
  71. ~~~~~~~~~~~~~~~~
  72. The JupyterLab
  73. `shell <https://jupyterlab.github.io/jupyterlab/application/classes/applicationshell.html>`__
  74. is used to add and interact with content in the application. The
  75. application consists of:
  76. - A top area for things like top level menus and toolbars
  77. - Left and right side bar areas for collapsible content
  78. - A main work area for user activity.
  79. - A bottom area for things like status bars
  80. Phosphor
  81. ~~~~~~~~
  82. The Phosphor library is used as the underlying architecture of
  83. JupyterLab and provides many of the low level primitives and widget
  84. structure used in the application. Phosphor provides a rich set of
  85. widgets for developing desktop-like applications in the browser, as well
  86. as patterns and objects for writing clean, well-abstracted code. The
  87. widgets in the application are primarily **Phosphor widgets**, and
  88. Phosphor concepts, like message passing and signals, are used
  89. throughout. **Phosphor messages** are a *many-to-one* interaction that
  90. enables information like resize events to flow through the widget
  91. hierarchy in the application. **Phosphor signals** are a *one-to-many*
  92. interaction that enable listeners to react to changes in an observed
  93. object.
  94. Extension Authoring
  95. ~~~~~~~~~~~~~~~~~~~
  96. An Extension is a valid `npm
  97. package <https://docs.npmjs.com/getting-started/what-is-npm>`__ that
  98. meets the following criteria:
  99. - Exports one or more JupyterLab plugins as the default export in its
  100. main file.
  101. - Has a ``jupyterlab`` key in its ``package.json`` which has
  102. ``"extension"`` metadata. The value can be ``true`` to use the main
  103. module of the package, or a string path to a specific module (e.g.
  104. ``"lib/foo"``).
  105. - It is also recommended to include the keyword `jupyterlab-extension`
  106. in the package.json, to aid with discovery (e.g. by the extension
  107. manager).
  108. While authoring the extension, you can use the command:
  109. .. code:: bash
  110. npm install # install npm package dependencies
  111. npm run build # optional build step if using TypeScript, babel, etc.
  112. jupyter labextension install # install the current directory as an extension
  113. This causes the builder to re-install the source folder before building
  114. the application files. You can re-build at any time using
  115. ``jupyter lab build`` and it will reinstall these packages. You can also
  116. link other local npm packages that you are working on simultaneously
  117. using ``jupyter labextension link``; they will be re-installed but not
  118. considered as extensions. Local extensions and linked packages are
  119. included in ``jupyter labextension list``.
  120. When using local extensions and linked packages, you can run the command
  121. ::
  122. jupyter lab --watch
  123. This will cause the application to incrementally rebuild when one of the
  124. linked packages changes. Note that only compiled JavaScript files (and
  125. the CSS files) are watched by the WebPack process. This means that if
  126. your extension is in TypeScript you'll have to run a `jlpm run build`
  127. before the changes will be reflected in JupyterLab. To avoid this step
  128. you can also watch the TypeScript sources in your extension which is
  129. usually assigned to the `tsc -w` shortcut.
  130. Note that the application is built against **released** versions of the
  131. core JupyterLab extensions. If your extension depends on JupyterLab
  132. packages, it should be compatible with the dependencies in the
  133. ``jupyterlab/static/package.json`` file. Note that building will always use the latest JavaScript packages that meet the dependency requirements of JupyterLab itself and any installed extensions. If you wish to test against a
  134. specific patch release of one of the core JupyterLab packages you can
  135. temporarily pin that requirement to a specific version in your own
  136. dependencies.
  137. If you must install a extension into a development branch of JupyterLab, you have to graft it into the source tree of JupyterLab itself. This may be done using the command
  138. ::
  139. jlpm run add:sibling <path-or-url>
  140. in the JupyterLab root directory, where ``<path-or-url>`` refers either
  141. to an extension npm package on the local file system, or a URL to a git
  142. repository for an extension npm package. This operation may be
  143. subsequently reversed by running
  144. ::
  145. jlpm run remove:package <extension-dir-name>
  146. This will remove the package metadata from the source tree, but will
  147. **not** remove any files added by the ``addsibling`` script, which
  148. should be removed manually.
  149. The package should export EMCAScript 5 compatible JavaScript. It can
  150. import CSS using the syntax ``require('foo.css')``. The CSS files can
  151. also import CSS from other packages using the syntax
  152. ``@import url('~foo/index.css')``, where ``foo`` is the name of the
  153. package.
  154. The following file types are also supported (both in JavaScript and
  155. CSS): json, html, jpg, png, gif, svg, js.map, woff2, ttf, eot.
  156. If your package uses any other file type it must be converted to one of
  157. the above types. If your JavaScript is written in any other dialect than
  158. EMCAScript 5 it must be converted using an appropriate tool.
  159. If you publish your extension on npm.org, users will be able to install
  160. it as simply ``jupyter labextension install <foo>``, where ``<foo>`` is
  161. the name of the published npm package. You can alternatively provide a
  162. script that runs ``jupyter labextension install`` against a local folder
  163. path on the user's machine or a provided tarball. Any valid
  164. ``npm install`` specifier can be used in
  165. ``jupyter labextension install`` (e.g. ``foo@latest``, ``bar@3.0.0.0``,
  166. ``path/to/folder``, and ``path/to/tar.gz``).
  167. There are a number of helper functions in `testutils` in this repo (which is a public npm package called `@jupyterlab/testutils`) that can be used when writing
  168. tests for an extension. See `tests/test-application` for an example of the infrastructure needed to run tests. There is a `karma` config file that points
  169. to the parent directory's `karma` config, and a test runner, `run-test.py` that
  170. starts a Jupyter server.
  171. Mime Renderer Extensions
  172. ~~~~~~~~~~~~~~~~~~~~~~~~
  173. Mime Renderer extensions are a convenience for creating an extension
  174. that can render mime data and potentially render files of a given type.
  175. We provide cookiecutters for Mime render extensions in
  176. `JavaScript <https://github.com/jupyterlab/mimerender-cookiecutter>`__ and
  177. `TypeScript <https://github.com/jupyterlab/mimerender-cookiecutter-ts>`__.
  178. Mime renderer extensions are more declarative than standard extensions.
  179. The extension is treated the same from the command line perspective
  180. (``jupyter labextension install`` ), but it does not directly create
  181. JupyterLab plugins. Instead it exports an interface given in the
  182. `rendermime-interfaces <https://jupyterlab.github.io/jupyterlab/rendermime-interfaces/interfaces/irendermime.iextension.html>`__
  183. package.
  184. The JupyterLab repo has an example mime renderer extension for
  185. `pdf <https://github.com/jupyterlab/jupyterlab/tree/master/packages/pdf-extension>`__
  186. files. It provides a mime renderer for pdf data and registers itself as
  187. a document renderer for pdf file types.
  188. The ``rendermime-interfaces`` package is intended to be the only
  189. JupyterLab package needed to create a mime renderer extension (using the
  190. interfaces in TypeScript or as a form of documentation if using plain
  191. JavaScript).
  192. The only other difference from a standard extension is that has a
  193. ``jupyterlab`` key in its ``package.json`` with ``"mimeExtension"``
  194. metadata. The value can be ``true`` to use the main module of the
  195. package, or a string path to a specific module (e.g. ``"lib/foo"``).
  196. The mime renderer can update its data by calling ``.setData()`` on the
  197. model it is given to render. This can be used for example to add a
  198. ``png`` representation of a dynamic figure, which will be picked up by a
  199. notebook model and added to the notebook document. When using
  200. ``IDocumentWidgetFactoryOptions``, you can update the document model by
  201. calling ``.setData()`` with updated data for the rendered MIME type. The
  202. document can then be saved by the user in the usual manner.
  203. Themes
  204. ~~~~~~
  205. A theme is a JupyterLab extension that uses a ``ThemeManager`` and can
  206. be loaded and unloaded dynamically. The package must include all static
  207. assets that are referenced by ``url()`` in its CSS files. Local URLs can
  208. be used to reference files relative to the location of the referring sibling CSS files. For example ``url('images/foo.png')`` or
  209. ``url('../foo/bar.css')``\ can be used to refer local files in the
  210. theme. Absolute URLs (starting with a ``/``) or external URLs (e.g.
  211. ``https:``) can be used to refer to external assets. The path to the
  212. theme asset entry point is specified ``package.json`` under the ``"jupyterlab"``
  213. key as ``"themePath"``. See the `JupyterLab Light
  214. Theme <https://github.com/jupyterlab/jupyterlab/tree/master/packages/theme-light-extension>`__
  215. for an example. Ensure that the theme files are included in the
  216. ``"files"`` metadata in package.json. Note that if you want to use SCSS, SASS, or LESS files,
  217. you must compile them to CSS and point JupyterLab to the CSS files.
  218. To quickly create a theme based on the JupyterLab Light Theme, follow
  219. the instructions in the `contributing
  220. guide <https://github.com/jupyterlab/jupyterlab/blob/d9bbf0822be5309d063249da6776e640dba7984c/CONTRIBUTING.md#setting-up-a-development-environment>`__ and
  221. then run ``jlpm run create:theme`` from the repository root directory.
  222. Once you select a name, title and a description, a new theme folder will
  223. be created in the current directory. You can move that new folder to a
  224. location of your choice, and start making desired changes.
  225. The theme extension is installed in the same way as a regular extension (see
  226. `extension authoring <#extension-authoring>`__).
  227. Standard (General-Purpose) Extensions
  228. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  229. JupyterLab's modular architecture is based around the idea
  230. that all extensions are on equal footing, and that they interact
  231. with each other through typed interfaces that are provided by ``Token`` objects.
  232. An extension can provide a ``Token`` to the application,
  233. which other extensions can then request for their own use.
  234. Core Tokens
  235. ^^^^^^^^^^^
  236. The core packages of JupyterLab provide a set of tokens,
  237. which are listed here, along with short descriptions of when you
  238. might want to use them in your extensions.
  239. - ``@jupyterlab/application:ILayoutRestorer``: An interface to the application layout
  240. restoration functionality. Use this to have your activities restored across
  241. page loads.
  242. - ``@jupyterlab/application:IMimeDocumentTracker``: An instance tracker for documents
  243. rendered using a mime renderer extension. Use this if you want to list and interact
  244. with documents rendered by such extensions.
  245. - ``@jupyterlab/application:IRouter``: The URL router used by the application.
  246. Use this to add custom URL-routing for your extension (e.g., to invoke
  247. a command if the user navigates to a sub-path).
  248. - ``@jupyterlab/apputils:ICommandPalette``: An interface to the application command palette
  249. in the left panel. Use this to add commands to the palette.
  250. - ``@jupyterlab/apputils:ISplashScreen``: An interface to the splash screen for the application.
  251. Use this if you want to show the splash screen for your own purposes.
  252. - ``@jupyterlab/apputils:IThemeManager``: An interface to the theme manager for the application.
  253. Most extensions will not need to use this, as they can register a
  254. `theme extension <#themes>`__.
  255. - ``@jupyterlab/apputils:IWindowResolver``: An interface to a window resolver for the
  256. application. JupyterLab workspaces are given a name, which are determined using
  257. the window resolver. Require this if you want to use the name of the current workspace.
  258. - ``@jupyterlab/codeeditor:IEditorServices``: An interface to the text editor provider
  259. for the application. Use this to create new text editors and host them in your
  260. UI elements.
  261. - ``@jupyterlab/completer:ICompletionManager``: An interface to the completion manager
  262. for the application. Use this to allow your extension to invoke a completer.
  263. - ``@jupyterlab/console:IConsoleTracker``: An instance tracker for code consoles.
  264. Use this if you want to be able to iterate over and interact with code consoles
  265. created by the application.
  266. - ``@jupyterlab/console:IContentFactory``: A factory object that creates new code
  267. consoles. Use this if you want to create and host code consoles in your own UI elements.
  268. - ``@jupyterlab/coreutils:ISettingRegistry``: An interface to the JupyterLab settings system.
  269. Use this if you want to store settings for your application.
  270. See `extension settings <#extension-settings>`__ for more information.
  271. - ``@jupyterlab/coreutils:IStateDB``: An interface to the JupyterLab state database.
  272. Use this if you want to store data that will persist across page loads.
  273. See `state database <#state-database>`__ for more information.
  274. - ``@jupyterlab/docmanager:IDocumentManager``: An interface to the manager for all
  275. documents used by the application. Use this if you want to open and close documents,
  276. create and delete files, and otherwise interact with the file system.
  277. - ``@jupyterlab/filebrowser:IFileBrowserFactory``: A factory object that creates file browsers.
  278. Use this if you want to create your own file browser (e.g., for a custom storage backend),
  279. or to interact with other file browsers that have been created by extensions.
  280. - ``@jupyterlab/fileeditor:IEditorTracker``: An instance tracker for file editors.
  281. Use this if you want to be able to iterate over and interact with file editors
  282. created by the application.
  283. - ``@jupyterlab/imageviewer:IImageTracker``: An instance tracker for images.
  284. Use this if you want to be able to iterate over and interact with images
  285. viewed by the application.
  286. - ``@jupyterlab/inspector:IInspector``: An interface for adding variable inspectors to widgets.
  287. Use this to add the ability to hook into the variable inspector to your extension.
  288. - ``@jupyterlab/launcher:ILauncher``: An interface to the application activity launcher.
  289. Use this to add your extension activities to the launcher panel.
  290. - ``@jupyterlab/mainmenu:IMainMenu``: An interface to the main menu bar for the application.
  291. Use this if you want to add your own menu items.
  292. - ``@jupyterlab/notebook:ICellTools``: An interface to the ``Cell Tools`` panel in the
  293. application left area. Use this to add your own functionality to the panel.
  294. - ``@jupyterlab/notebook:IContentFactory``: A factory object that creates new notebooks.
  295. Use this if you want to create and host notebooks in your own UI elements.
  296. - ``@jupyterlab/notebook:INotebookTracker``: An instance tracker for code consoles.
  297. Use this if you want to be able to iterate over and interact with notebooks
  298. created by the application.
  299. - ``@jupyterlab/rendermime:IRenderMimeRegistry``: An interface to the rendermime registry
  300. for the application. Use this to create renderers for various mime-types in your extension.
  301. Most extensions will not need to use this, as they can register a
  302. `mime renderer extension <#mime-renderer-extensions>`__.
  303. - ``@jupyterlab/rendermime:ILatexTypesetter``: An interface to the LaTeX typesetter for the
  304. application. Use this if you want to typeset math in your extension.
  305. - ``@jupyterlab/settingeditor:ISettingEditorTracker``: An instance tracker for setting editors.
  306. Use this if you want to be able to iterate over and interact with setting editors
  307. created by the application.
  308. - ``@jupyterlab/terminal:ITerminalTracker``: An instance tracker for terminals.
  309. Use this if you want to be able to iterate over and interact with terminals
  310. created by the application.
  311. - ``@jupyterlab/tooltip:ITooltipManager``: An interface to the tooltip manager for the application.
  312. Use this to allow your extension to invoke a tooltip.
  313. Standard Extension Example
  314. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  315. For a concrete example of a standard extension, see :ref:`How to extend the Notebook plugin <extend-notebook-plugin>`.
  316. Notice that the mime renderer and themes extensions above use a limited,
  317. simplified interface to JupyterLab's extension system. Modifying the
  318. notebook plugin requires the full, general-purpose interface to the
  319. extension system.
  320. Storing Extension Data
  321. ^^^^^^^^^^^^^^^^^^^^^^
  322. In addition to the file system that is accessed by using the
  323. ``@jupyterlab/services`` package, JupyterLab offers two ways for
  324. extensions to store data: a client-side state database that is built on
  325. top of ``localStorage`` and a plugin settings system that provides for
  326. default setting values and user overrides.
  327. Extension Settings
  328. ``````````````````
  329. An extension can specify user settings using a JSON Schema. The schema
  330. definition should be in a file that resides in the ``schemaDir``
  331. directory that is specified in the ``package.json`` file of the
  332. extension. The actual file name should use is the part that follows the
  333. package name of extension. So for example, the JupyterLab
  334. ``apputils-extension`` package hosts several plugins:
  335. - ``'@jupyterlab/apputils-extension:menu'``
  336. - ``'@jupyterlab/apputils-extension:palette'``
  337. - ``'@jupyterlab/apputils-extension:settings'``
  338. - ``'@jupyterlab/apputils-extension:themes'``
  339. And in the ``package.json`` for ``@jupyterlab/apputils-extension``, the
  340. ``schemaDir`` field is a directory called ``schema``. Since the
  341. ``themes`` plugin requires a JSON schema, its schema file location is:
  342. ``schema/themes.json``. The plugin's name is used to automatically
  343. associate it with its settings file, so this naming convention is
  344. important. Ensure that the schema files are included in the ``"files"``
  345. metadata in ``package.json``.
  346. See the
  347. `fileeditor-extension <https://github.com/jupyterlab/jupyterlab/tree/master/packages/fileeditor-extension>`__
  348. for another example of an extension that uses settings.
  349. State Database
  350. ``````````````
  351. The state database can be accessed by importing ``IStateDB`` from
  352. ``@jupyterlab/coreutils`` and adding it to the list of ``requires`` for
  353. a plugin:
  354. .. code:: typescript
  355. const id = 'foo-extension:IFoo';
  356. const IFoo = new Token<IFoo>(id);
  357. interface IFoo {}
  358. class Foo implements IFoo {}
  359. const plugin: JupyterLabPlugin<IFoo> = {
  360. id,
  361. requires: [IStateDB],
  362. provides: IFoo,
  363. activate: (app: JupyterLab, state: IStateDB): IFoo => {
  364. const foo = new Foo();
  365. const key = `${id}:some-attribute`;
  366. // Load the saved plugin state and apply it once the app
  367. // has finished restoring its former layout.
  368. Promise.all([state.fetch(key), app.restored])
  369. .then(([saved]) => { /* Update `foo` with `saved`. */ });
  370. // Fulfill the plugin contract by returning an `IFoo`.
  371. return foo;
  372. },
  373. autoStart: true
  374. };
  375. Context Menus
  376. ^^^^^^^^^^^^^
  377. JupyterLab has an application-wide context menu available as
  378. ``app.contextMenu``. See the Phosphor
  379. `docs <https://phosphorjs.github.io/phosphor/api/widgets/interfaces/contextmenu.iitemoptions.html>`__
  380. for the item creation options. If you wish to preempt the
  381. application context menu, you can use a 'contextmenu' event listener and
  382. call ``event.stopPropagation`` to prevent the application context menu
  383. handler from being called (it is listening in the bubble phase on the
  384. ``document``). At this point you could show your own Phosphor
  385. `contextMenu <https://phosphorjs.github.io/phosphor/api/widgets/classes/contextmenu.html>`__,
  386. or simply stop propagation and let the system context menu be shown.
  387. This would look something like the following in a ``Widget`` subclass:
  388. .. code:: javascript
  389. // In `onAfterAttach()`
  390. this.node.addEventListener('contextmenu', this);
  391. // In `handleEvent()`
  392. case 'contextmenu':
  393. event.stopPropagation();
  394. .. |dependencies| image:: dependency-graph.svg
  395. .. _ext-author-companion-packages:
  396. Companion Packages
  397. ^^^^^^^^^^^^^^^^^^
  398. If your extensions depends on the presence of one or more packages in the
  399. kernel, or on a notebook server extension, you can add metadata to indicate
  400. this to the extension manager by adding metadata to your package.json file.
  401. The full options available are::
  402. "jupyterlab": {
  403. "discovery": {
  404. "kernel": [
  405. {
  406. "kernel_spec": {
  407. "language": "<regexp for matching kernel language>",
  408. "display_name": "<regexp for matching kernel display name>" // optional
  409. },
  410. "base": {
  411. "name": "<the name of the kernel package>"
  412. },
  413. "overrides": { // optional
  414. "<manager name, e.g. 'pip'>": {
  415. "name": "<name of kernel package on pip, if it differs from base name>"
  416. }
  417. },
  418. "managers": [ // list of package managers that have your kernel package
  419. "pip",
  420. "conda"
  421. ]
  422. }
  423. ],
  424. "server": {
  425. "base": {
  426. "name": "<the name of the server extension package>"
  427. },
  428. "overrides": { // optional
  429. "<manager name, e.g. 'pip'>": {
  430. "name": "<name of server extension package on pip, if it differs from base name>"
  431. }
  432. },
  433. "managers": [ // list of package managers that have your server extension package
  434. "pip",
  435. "conda"
  436. ]
  437. }
  438. }
  439. }
  440. A typical setup for e.g. a jupyter-widget based package will then be::
  441. "keywords": [
  442. "jupyterlab-extension",
  443. "jupyter",
  444. "widgets",
  445. "jupyterlab"
  446. ],
  447. "jupyterlab": {
  448. "extension": true,
  449. "discovery": {
  450. "kernel": [
  451. {
  452. "kernel_spec": {
  453. "language": "^python",
  454. },
  455. "base": {
  456. "name": "myipywidgetspackage"
  457. },
  458. "managers": [
  459. "pip",
  460. "conda"
  461. ]
  462. }
  463. ]
  464. }
  465. }
  466. Currently supported package managers are:
  467. - pip
  468. - conda