contributing.rst 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. Contributing to JupyterLab
  2. ==========================
  3. If you're reading this section, you're probably interested in
  4. contributing to JupyterLab. Welcome and thanks for your interest in
  5. contributing!
  6. Please take a look at the Contributor documentation, familiarize
  7. yourself with using JupyterLab, and introduce yourself to the community
  8. (on the mailing list or discourse) and share what area of the project
  9. you are interested in working on. Please also see the Jupyter `Community
  10. Guides <https://jupyter.readthedocs.io/en/latest/community/content-community.html>`__.
  11. We have labeled some issues as `good first
  12. issue <https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`__
  13. or `help
  14. wanted <https://github.com/jupyterlab/jupyterlab/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22>`__
  15. that we believe are good examples of small, self-contained changes. We
  16. encourage those that are new to the code base to implement and/or ask
  17. questions about these issues.
  18. If you believe you’ve found a security vulnerability in JupyterLab or
  19. any Jupyter project, please report it to security@ipython.org. If you
  20. prefer to encrypt your security reports, you can use `this PGP public
  21. key <https://raw.githubusercontent.com/jupyter/notebook/master/docs/source/ipython_security.asc>`__.
  22. .. contents:: Table of contents
  23. :local:
  24. :depth: 1
  25. General Guidelines for Contributing
  26. ------------------------------------
  27. For general documentation about contributing to Jupyter projects, see
  28. the `Project Jupyter Contributor
  29. Documentation <https://jupyter.readthedocs.io/en/latest/contributing/content-contributor.html>`__
  30. and `Code of
  31. Conduct <https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md>`__.
  32. All source code is written in
  33. `TypeScript <http://www.typescriptlang.org/Handbook>`__. See the `Style
  34. Guide <https://github.com/jupyterlab/jupyterlab/wiki/TypeScript-Style-Guide>`__.
  35. All source code is formatted using `prettier <https://prettier.io>`__.
  36. When code is modified and committed, all staged files will be
  37. automatically formatted using pre-commit git hooks (with help from the
  38. `lint-staged <https://github.com/okonet/lint-staged>`__ and
  39. `husky <https://github.com/typicode/husky>`__ libraries). The benefit of
  40. using a code formatter like prettier is that it removes the topic of
  41. code style from the conversation when reviewing pull requests, thereby
  42. speeding up the review process.
  43. You may also use the prettier npm script (e.g. ``npm run prettier`` or
  44. ``yarn prettier`` or ``jlpm prettier``) to format the entire code base.
  45. We recommend installing a prettier extension for your code editor and
  46. configuring it to format your code with a keyboard shortcut or
  47. automatically on save.
  48. Submitting a Pull Request Contribution
  49. --------------------------------------
  50. Generally, an issue should be opened describing a piece of proposed work
  51. and the issues it solves before a pull request is opened.
  52. Issue Management
  53. ^^^^^^^^^^^^^^^^
  54. Opening an issue lets community members participate in the design
  55. discussion, makes others aware of work being done, and sets the stage
  56. for a fruitful community interaction. A pull request should reference
  57. the issue it is addressing. Once the pull request is merged, the issue
  58. related to it will also be closed. If there is additional discussion
  59. around implemementation the issue may be re-opened. Once 30 days have
  60. passed with no additional discussion, the `lock
  61. bot <https://github.com/apps/lock>`__ will lock the issue. If additional
  62. discussion is desired, or if the pull request doesn't fully address the
  63. locked issue, please open a new issue referencing the locked issue.
  64. Tag Issues with Labels
  65. ^^^^^^^^^^^^^^^^^^^^^^
  66. Users without the commit rights to the JupyterLab repository can tag
  67. issues with labels using the ``@meeseeksdev`` bot. For example: To apply
  68. the label ``foo`` and ``bar baz`` to an issue, comment
  69. ``@meeseeksdev tag foo "bar baz"`` on the issue.
  70. Contributing from within the browser
  71. ------------------------------------
  72. Using the https://github.com web interface - documented
  73. `here <https://docs.github.com/en/free-pro-team@latest/github>`__ - you
  74. can create and propose a change purely within your browser.
  75. Using `Binder <https://mybinder.org>`__, you can test the current master branch and your
  76. changes within the browser as well. We recommend you have at least 8 GB of RAM for this.
  77. To build and launch an instance of the latest JupyterLab master, open
  78. `this link <https://mybinder.org/v2/gh/jupyterlab/jupyterlab/master?urlpath=lab-dev/>`__
  79. in a new tab. The build takes about 7 minutes to complete.
  80. To test your own branch hosted on GitHub, enter it on https://mybinder.org.
  81. If everything goes right, filling out the form takes about 2 minutes, and the build should take
  82. about 7 minutes again.
  83. Setting up a local development environment
  84. ------------------------------------------
  85. This section explains how to set up a local development environment. We assume you use GNU/Linux,
  86. Mac OS X, or Windows Subsystem for Linux.
  87. Installing Node.js and jlpm
  88. ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  89. Building JupyterLab from its GitHub source code requires Node.js. The
  90. development version requires Node.js version 12+, as defined in the
  91. ``engines`` specification in
  92. `dev_mode/package.json <https://github.com/jupyterlab/jupyterlab/blob/master/dev_mode/package.json>`__.
  93. If you use ``conda``, you can get it with:
  94. .. code:: bash
  95. conda install -c conda-forge 'nodejs'
  96. If you use `Homebrew <http://brew.sh>`__ on Mac OS X:
  97. .. code:: bash
  98. brew install node
  99. You can also use the installer from the `Node.js <https://nodejs.org>`__
  100. website.
  101. To check which version of Node.js is installed:
  102. .. code:: bash
  103. node -v
  104. Installing JupyterLab
  105. ---------------------
  106. JupyterLab requires Jupyter Notebook version 4.3 or later.
  107. If you use ``conda``, you can install notebook using:
  108. .. code:: bash
  109. conda install -c conda-forge notebook
  110. You may also want to install ``nb_conda_kernels`` to have a kernel
  111. option for different `conda
  112. environments <https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html>`__
  113. .. code:: bash
  114. conda install -c conda-forge nb_conda_kernels
  115. If you use ``pip``, you can install notebook using:
  116. .. code:: bash
  117. pip install notebook
  118. Fork the JupyterLab
  119. `repository <https://github.com/jupyterlab/jupyterlab>`__.
  120. Once you have installed the dependencies mentioned above, use the
  121. following steps:
  122. .. code:: bash
  123. git clone https://github.com/<your-github-username>/jupyterlab.git
  124. cd jupyterlab
  125. pip install -e .
  126. jlpm install
  127. jlpm run build # Build the dev mode assets (optional)
  128. jlpm run build:core # Build the core mode assets (optional)
  129. jupyter lab build # Build the app dir assets (optional)
  130. Notes:
  131. - A few of the scripts will run "python". If your target python is
  132. called something else (such as "python3") then parts of the build
  133. will fail. You may wish to build in a conda environment, or make an
  134. alias.
  135. - Some of the packages used in the development environment require
  136. Python 3.0 or higher. If you encounter an ImportError during the
  137. installation, make sure Python 3.0+ is installed. Also, try using the
  138. Python 3.0+ version of ``pip`` or ``pip3 install -e .`` command to
  139. install JupyterLab from the forked repository.
  140. - The ``jlpm`` command is a JupyterLab-provided, locked version of the
  141. `yarn <https://yarnpkg.com/en>`__ package manager. If you have
  142. ``yarn`` installed already, you can use the ``yarn`` command when
  143. developing, and it will use the local version of ``yarn`` in
  144. ``jupyterlab/yarn.js`` when run in the repository or a built
  145. application directory.
  146. - If you decide to use the ``jlpm`` command and encounter the
  147. ``jlpm: command not found`` error, try adding the user-level bin
  148. directory to your ``PATH`` environment variable. You already
  149. installed ``jlpm`` along with JupyterLab in the previous command, but
  150. ``jlpm`` might not be accessible due to ``PATH`` environment variable
  151. related issues. If you are using a Unix derivative (FreeBSD, GNU /
  152. Linux, OS X), you can achieve this by using
  153. ``export PATH="$HOME/.local/bin:$PATH"`` command.
  154. - At times, it may be necessary to clean your local repo with the
  155. command ``npm run clean:slate``. This will clean the repository, and
  156. re-install and rebuild.
  157. - If ``pip`` gives a ``VersionConflict`` error, it usually means that
  158. the installed version of ``jupyterlab_server`` is out of date. Run
  159. ``pip install --upgrade jupyterlab_server`` to get the latest
  160. version.
  161. - To install JupyterLab in isolation for a single conda/virtual
  162. environment, you can add the ``--sys-prefix`` flag to the extension
  163. activation above; this will tie the installation to the
  164. ``sys.prefix`` location of your environment, without writing anything
  165. in your user-wide settings area (which are visible to all your envs):
  166. - You can run ``jlpm run build:dev:prod`` to build more accurate
  167. sourcemaps that show the original Typescript code when debugging.
  168. However, it takes a bit longer to build the sources, so is used only
  169. to build for production by default.
  170. If you are using a version of Jupyter Notebook earlier than 5.3, then
  171. you must also run the following command to enable the JupyterLab server
  172. extension:
  173. .. code:: bash
  174. jupyter serverextension enable --py --sys-prefix jupyterlab
  175. For installation instructions to write documentation, please see
  176. `Writing Documentation <#writing-documentation>`__
  177. Run JupyterLab
  178. ^^^^^^^^^^^^^^
  179. Start JupyterLab in development mode:
  180. .. code:: bash
  181. jupyter lab --dev-mode
  182. Development mode ensures that you are running the JavaScript assets that
  183. are built in the dev-installed Python package. Note that when running in
  184. dev mode, extensions will not be activated by default.
  185. When running in dev mode, a red stripe will appear at the top of the
  186. page; this is to indicate running an unreleased version.
  187. Build and Run the Tests
  188. ^^^^^^^^^^^^^^^^^^^^^^^
  189. .. code:: bash
  190. jlpm run build:testutils
  191. jlpm test
  192. You can run tests for an individual package by changing to the
  193. appropriate package folder:
  194. .. code:: bash
  195. cd packages/notebook
  196. jlpm run build:test
  197. jlpm test
  198. We use ``jest`` for all tests, so standard ``jest`` workflows apply.
  199. Tests can be debugged in either VSCode or Chrome. It can help to add an
  200. ``it.only`` to a specific test when debugging. All of the ``test*``
  201. scripts in each package accept ``jest`` `cli
  202. options <https://jestjs.io/docs/en/cli.html>`__.
  203. VSCode Debugging
  204. """"""""""""""""
  205. To debug in VSCode, open a package folder in VSCode. We provide a launch
  206. configuration in each package folder. In a terminal, run
  207. ``jlpm test:debug:watch``. In VSCode, select "Attach to Jest" from the
  208. "Run" sidebar to begin debugging. See `VSCode docs on
  209. debugging <https://code.visualstudio.com/docs/editor/debugging>`__ for
  210. more details.
  211. Chrome Debugging
  212. """"""""""""""""
  213. To debug in Chrome, run ``jlpm test:debug:watch`` in the terminal. Open
  214. Chrome and go to ``chrome://inspect/``. Select the remote device and
  215. begin debugging.
  216. Testing Utilities
  217. """""""""""""""""
  218. There are some helper functions in ``testutils`` (which is a public npm
  219. package called ``@jupyterlab/testutils``) that are used by many of the
  220. tests.
  221. For tests that rely on ``@jupyterlab/services`` (starting kernels,
  222. interacting with files, etc.), there are two options. If a simple
  223. interaction is needed, the ``Mock`` namespace exposed by ``testutils``
  224. has a number of mock implmentations (see ``testutils/src/mock.ts``). If
  225. a full server interaction is required, use the ``JupyterServer`` class.
  226. We have a helper function called ``testEmission`` to help with writing
  227. tests that use ``Lumino`` signals, as well as a ``framePromise``
  228. function to get a ``Promise`` for a ``requestAnimationFrame``. We
  229. sometimes have to set a sentinel value inside a ``Promise`` and then
  230. check that the sentinel was set if we need a promise to run without
  231. blocking.
  232. Performance Testing
  233. -------------------
  234. If you are making a change that might affect how long it takes to load
  235. JupyterLab in the browser, we recommend doing some performance testing
  236. using `Lighthouse <https://github.com/GoogleChrome/lighthouse>`__. It
  237. let's you easily compute a number of metrics, like page load time, for
  238. the site.
  239. To use it, first build JupyterLab in dev mode:
  240. .. code:: bash
  241. jlpm run build:dev
  242. Then, start JupyterLab using the dev build:
  243. .. code:: bash
  244. jupyter lab --dev --NotebookApp.token='' --no-browser
  245. Now run Lighthouse against this local server and show the results:
  246. .. code:: bash
  247. jlpm run lighthouse --view
  248. .. image:: /images/lighthouse.png
  249. Using throttling
  250. ^^^^^^^^^^^^^^^^
  251. Lighthouse recommends using the system level
  252. `comcast <https://github.com/tylertreat/comcast>`__ tool to throttle
  253. your network connection and emulate different scenarios. To use it,
  254. first install that tool using ``go``:
  255. .. code:: bash
  256. go get github.com/tylertreat/comcast
  257. Then, before you run Lighthouse, enable the throttling (this requires
  258. sudo):
  259. .. code:: bash
  260. run lighthouse:throttling:start
  261. This enables the "WIFI (good)" preset of comcast, which should emulate
  262. loading JupyterLab over a local network.
  263. Then run the lighthouse tests:
  264. .. code:: bash
  265. jlpm run lighthouse [...]
  266. Then disable the throttling after you are done:
  267. .. code:: bash
  268. jlpm run lighthouse:throttling:stop
  269. Comparing results
  270. ^^^^^^^^^^^^^^^^^
  271. Performance results are usually only useful in comparison to other
  272. results. For that reason, we have included a comparison script that can
  273. take two lighthouse results and show the changes between them.
  274. Let's say we want to compare the results of the production build of
  275. JupyterLab with the normal build. The production build minifies all the
  276. JavaScript, so should load a bit faster.
  277. First, we build JupyterLab normally, start it up, profile it and save
  278. the results:
  279. .. code:: bash
  280. jlpm build:dev
  281. jupyter lab --dev --NotebookApp.token='' --no-browser
  282. # in new window
  283. jlpm run lighthouse --output json --output-path normal.json
  284. Then rebuild with the production build and retest:
  285. .. code:: bash
  286. jlpm run build:dev:prod
  287. jupyter lab --dev --NotebookApp.token='' --no-browser
  288. # in new window
  289. jlpm run lighthouse --output json --output-path prod.json
  290. Now we can use compare the two outputs:
  291. .. code:: bash
  292. jlpm run lighthouse:compare normal.json prod.json
  293. This gives us a report of the relative differences between the audits in
  294. the two reports:
  295. .. admonition:: Resulting Output
  296. ``normal.json`` -> ``prod.json``
  297. | **First Contentful Paint**
  298. | - -62% Δ
  299. | - 1.9 s -> 0.7 s
  300. | - First Contentful Paint marks the time at which the first text or
  301. image is painted. `Learn
  302. more <https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint>`__.
  303. | **First Meaningful Paint**
  304. | - -50% Δ
  305. | - 2.5 s -> 1.3 s
  306. | - First Meaningful Paint measures when the primary content of a
  307. page is visible. `Learn
  308. more <https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint>`__.
  309. | **Speed Index**
  310. | - -48% Δ
  311. | - 2.6 s -> 1.3 s
  312. | - Speed Index shows how quickly the contents of a page are visibly
  313. populated. `Learn
  314. more <https://developers.google.com/web/tools/lighthouse/audits/speed-index>`__.
  315. | **Estimated Input Latency**
  316. | - 0% Δ
  317. | - 20 ms -> 20 ms
  318. | - Estimated Input Latency is an estimate of how long your app takes
  319. to respond to user input, in milliseconds, during the busiest 5s
  320. window of page load. If your latency is higher than 50 ms, users
  321. may perceive your app as laggy. `Learn
  322. more <https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency>`__.
  323. | **Max Potential First Input Delay**
  324. | - 9% Δ
  325. | - 200 ms -> 210 ms
  326. | - The maximum potential First Input Delay that your users could
  327. experience is the duration, in milliseconds, of the longest task.
  328. `Learn
  329. more <https://developers.google.com/web/updates/2018/05/first-input-delay>`__.
  330. | **First CPU Idle**
  331. | - -50% Δ
  332. | - 2.5 s -> 1.3 s
  333. | - First CPU Idle marks the first time at which the page's main
  334. thread is quiet enough to handle input. `Learn
  335. more <https://developers.google.com/web/tools/lighthouse/audits/first-interactive>`__.
  336. | **Time to Interactive**
  337. | - -52% Δ
  338. | - 2.5 s -> 1.2 s
  339. | - Time to interactive is the amount of time it takes for the page
  340. to become fully interactive. `Learn
  341. more <https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive>`__.
  342. | **Avoid multiple page redirects**
  343. | - -2% Δ
  344. | - Potential savings of 10 ms -> Potential savings of 10 ms
  345. | - Redirects introduce additional delays before the page can be
  346. loaded. `Learn
  347. more <https://developers.google.com/web/tools/lighthouse/audits/redirects>`__.
  348. | **Minimize main-thread work**
  349. | - -54% Δ
  350. | - 2.1 s -> 1.0 s
  351. | - Consider reducing the time spent parsing, compiling and executing
  352. JS. You may find delivering smaller JS payloads helps with this.
  353. | **JavaScript execution time**
  354. | - -49% Δ
  355. | - 1.1 s -> 0.6 s
  356. | - Consider reducing the time spent parsing, compiling, and
  357. executing JS. You may find delivering smaller JS payloads helps
  358. with this. `Learn
  359. more <https://developers.google.com/web/tools/lighthouse/audits/bootup>`__.
  360. | **Preload key requests**
  361. | - -100% Δ
  362. | - Potential savings of 240 ms ->
  363. | - Consider using <link rel=preload> to prioritize fetching
  364. resources that are currently requested later in page load. `Learn
  365. more <https://developers.google.com/web/tools/lighthouse/audits/preload>`__.
  366. | **Uses efficient cache policy on static assets**
  367. | - 0% Δ
  368. | - 1 resource found -> 1 resource found
  369. | - A long cache lifetime can speed up repeat visits to your page.
  370. `Learn
  371. more <https://developers.google.com/web/tools/lighthouse/audits/cache-policy>`__.
  372. | **Avoid enormous network payloads**
  373. | - -86% Δ
  374. | - Total size was 30,131 KB -> Total size was 4,294 KB
  375. | - Large network payloads cost users real money and are highly
  376. correlated with long load times. `Learn
  377. more <https://developers.google.com/web/tools/lighthouse/audits/network-payloads>`__.
  378. | **Minify JavaScript**
  379. | - -100% Δ
  380. | - Potential savings of 23,041 KB ->
  381. | - Minifying JavaScript files can reduce payload sizes and script
  382. parse time. `Learn
  383. more <https://developers.google.com/speed/docs/insights/MinifyResources>`__.
  384. | **Enable text compression**
  385. | - -86% Δ
  386. | - Potential savings of 23,088 KB -> Potential savings of 3,112 KB
  387. | - Text-based resources should be served with compression (gzip,
  388. deflate or brotli) to minimize total network bytes. `Learn
  389. more <https://developers.google.com/web/tools/lighthouse/audits/text-compression>`__.
  390. | **Avoid an excessive DOM size**
  391. | - 0% Δ
  392. | - 1,268 elements -> 1,268 elements
  393. | - Browser engineers recommend pages contain fewer than ~1,500 DOM
  394. elements. The sweet spot is a tree depth < 32 elements and fewer
  395. than 60 children/parent element. A large DOM can increase memory
  396. usage, cause longer `style
  397. calculations <https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations>`__,
  398. and produce costly `layout
  399. reflows <https://developers.google.com/speed/articles/reflow>`__.
  400. `Learn
  401. more <https://developers.google.com/web/tools/lighthouse/audits/dom-size>`__.
  402. Contributing to the debugger front-end
  403. --------------------------------------
  404. To make changes to the debugger extension, a kernel with support for debugging is required.
  405. Check out the user documentation to learn how to install such kernel: :ref:`debugger`.
  406. Then refresh the page and the debugger sidebar should appear in the right area.
  407. The Debugger Adapter Protocol
  408. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  409. The following diagram illustrates the types of messages sent between the JupyterLab extension and the kernel.
  410. .. image:: ./debugger_protocol_diagram.png
  411. Inspecting Debug Messages in VS Code
  412. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  413. Inspecting the debug messages in VS Code can be useful to understand when debug requests are made (for example triggered by a UI action), and to compare the behavior of the JupyterLab debugger with the Python debugger in VS Code.
  414. The first step is to create a test file and a debug configuration (``launch.json``):
  415. .. image:: ./debugger_launch_configuration.png
  416. .. code:: json
  417. {
  418. "version": "0.2.0",
  419. "configurations": [
  420. {
  421. "name": "Python: Current File",
  422. "type": "python",
  423. "request": "launch",
  424. "program": "${file}",
  425. "console": "integratedTerminal",
  426. "env": { "DEBUGPY_LOG_DIR": "/path/to/logs/folder" }
  427. }
  428. ]
  429. }
  430. Then start the debugger:
  431. .. image:: ./debugger_vscode_start.png
  432. The content of the log file looks like this:
  433. .. code:: bash
  434. ...
  435. D00000.032: IDE --> {
  436. "command": "initialize",
  437. "arguments": {
  438. "clientID": "vscode",
  439. "clientName": "Visual Studio Code",
  440. "adapterID": "python",
  441. "pathFormat": "path",
  442. "linesStartAt1": true,
  443. "columnsStartAt1": true,
  444. "supportsVariableType": true,
  445. "supportsVariablePaging": true,
  446. "supportsRunInTerminalRequest": true,
  447. "locale": "en-us"
  448. },
  449. "type": "request",
  450. "seq": 1
  451. }
  452. ...
  453. With:
  454. - ``IDE`` = VS Code
  455. - ``PYD`` = pydev debugger
  456. - Messages follow the `DAP <https://microsoft.github.io/debug-adapter-protocol/specification>`_
  457. References
  458. ^^^^^^^^^^
  459. - Dump cell and state restoration: https://github.com/jupyterlab/debugger/issues/52
  460. - Protocol Overview: https://microsoft.github.io/debug-adapter-protocol/overview
  461. - Specification: https://microsoft.github.io/debug-adapter-protocol/specification
  462. Build and run the stand-alone examples
  463. --------------------------------------
  464. To install and build the examples in the ``examples`` directory:
  465. .. code:: bash
  466. jlpm run build:examples
  467. To run a specific example, change to the examples directory (i.e.
  468. ``examples/filebrowser``) and enter:
  469. .. code:: bash
  470. python main.py
  471. Debugging in the Browser
  472. ------------------------
  473. All methods of building JupyterLab produce source maps. The source maps
  474. should be available in the source files view of your browser's
  475. development tools under the ``webpack://`` header.
  476. When running JupyterLab normally, expand the ``~`` header to see the
  477. source maps for individual packages.
  478. When running in ``--dev-mode``, the core packages are available under
  479. ``packages/``, while the third party libraries are available under
  480. ``~``. Note: it is recommended to use ``jupyter lab --watch --dev-mode``
  481. while debugging.
  482. When running a test, the packages will be available at the top level
  483. (e.g. ``application/src``), and the current set of test files available
  484. under ``/src``. Note: it is recommended to use ``jlpm run watch`` in the
  485. test folder while debugging test options. See
  486. `above <#build-and-run-the-tests>`__ for more info.
  487. --------------
  488. High level Architecture
  489. -----------------------
  490. The JupyterLab application is made up of two major parts:
  491. - an npm package
  492. - a Jupyter server extension (Python package)
  493. Each part is named ``jupyterlab``. The :ref:`developer tutorial
  494. documentation <developer-guide>`
  495. provides additional architecture information.
  496. The NPM Packages
  497. ----------------
  498. The repository consists of many npm packages that are managed using the
  499. lerna build tool. The npm package source files are in the ``packages/``
  500. subdirectory.
  501. Build the NPM Packages from Source
  502. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  503. .. code:: bash
  504. git clone https://github.com/jupyterlab/jupyterlab.git
  505. cd jupyterlab
  506. pip install -e .
  507. jlpm
  508. jlpm run build:packages
  509. **Rebuild**
  510. .. code:: bash
  511. jlpm run clean
  512. jlpm run build:packages
  513. Writing Documentation
  514. ---------------------
  515. Documentation is written in Markdown and reStructuredText. In
  516. particular, the documentation on our Read the Docs page is written in
  517. reStructuredText. To ensure that the Read the Docs page builds, you'll
  518. need to install the documentation dependencies with ``pip``:
  519. .. code:: bash
  520. pip install -r docs/requirements.txt
  521. To test the docs run:
  522. .. code:: bash
  523. py.test --check-links -k .md . || py.test --check-links -k .md --lf .
  524. The Read the Docs pages can be built using ``make``:
  525. .. code:: bash
  526. cd docs
  527. make html
  528. Or with ``jlpm``:
  529. .. code:: bash
  530. jlpm run docs
  531. Writing Style
  532. ^^^^^^^^^^^^^
  533. - The documentation should be written in the second person, referring
  534. to the reader as "you" and not using the first person plural "we."
  535. The author of the documentation is not sitting next to the user, so
  536. using "we" can lead to frustration when things don't work as
  537. expected.
  538. - Avoid words that trivialize using JupyterLab such as "simply" or
  539. "just." Tasks that developers find simple or easy may not be for
  540. users.
  541. - Write in the active tense, so "drag the notebook cells..." rather
  542. than "notebook cells can be dragged..."
  543. - The beginning of each section should begin with a short (1-2
  544. sentence) high-level description of the topic, feature or component.
  545. - Use "enable" rather than "allow" to indicate what JupyterLab makes
  546. possible for users. Using "allow" connotes that we are giving them
  547. permission, whereas "enable" connotes empowerment.
  548. User Interface Naming Conventions
  549. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  550. Documents, Files, and Activities
  551. """"""""""""""""""""""""""""""""
  552. Files are referrred to as either files or documents, depending on the
  553. context.
  554. Documents are more human centered. If human viewing, interpretation,
  555. interaction is an important part of the experience, it is a document in
  556. that context. For example, notebooks and markdown files will often be
  557. referring to as documents unless referring to the file-ness aspect of it
  558. (e.g., the notebook filename).
  559. Files are used in a less human-focused context. For example, we refer to
  560. files in relation to a file system or file name.
  561. Activities can be either a document or another UI panel that is not file
  562. backed, such as terminals, consoles or the inspector. An open document
  563. or file is an activity in that it is represented by a panel that you can
  564. interact with.
  565. Element Names
  566. """""""""""""
  567. - The generic content area of a tabbed UI is a panel, but prefer to
  568. refer to the more specific name, such as “File browser.” Tab bars
  569. have tabs which toggle panels.
  570. - The menu bar contains menu items, which have their own submenus.
  571. - The main work area can be referred to as the work area when the name
  572. is unambiguous.
  573. - When describing elements in the UI, colloquial names are preferred
  574. (e.g., “File browser” instead of “Files panel”).
  575. The majority of names are written in lower case. These names include:
  576. - tab
  577. - panel
  578. - menu bar
  579. - sidebar
  580. - file
  581. - document
  582. - activity
  583. - tab bar
  584. - main work area
  585. - file browser
  586. - command palette
  587. - cell inspector
  588. - code console
  589. The following sections of the user interface should be in title case,
  590. directly quoting a word in the UI:
  591. - File menu
  592. - Files tab
  593. - Running panel
  594. - Tabs panel
  595. - Simple Interface mode
  596. The capitalized words match the label of the UI element the user is
  597. clicking on because there does not exist a good colloquial name for the
  598. tool, such as “file browser” or “command palette”.
  599. See :ref:`interface` for descriptions of elements in the UI.
  600. The Jupyter Server Extension
  601. ----------------------------
  602. The Jupyter server extension source files are in the jupyterlab/
  603. subdirectory. To use this extension, make sure the Jupyter Notebook
  604. server version 4.3 or later is installed.
  605. Build the JupyterLab server extension
  606. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  607. When you make a change to JupyterLab npm package source files, run:
  608. .. code:: bash
  609. jlpm run build
  610. to build the changes, and then refresh your browser to see the changes.
  611. To have the system build after each source file change, run:
  612. .. code:: bash
  613. jupyter lab --dev-mode --watch
  614. Build Utilities
  615. ---------------
  616. There is a range of build utilities for maintaining the repository. To
  617. get a suggested version for a library use
  618. ``jlpm run get:dependency foo``. To update the version of a library
  619. across the repo use ``jlpm run update:dependency foo ^latest``. To
  620. remove an unwanted dependency use ``jlpm run remove:dependency foo``.
  621. The key utility is ``jlpm run integrity``, which ensures the integrity
  622. of the packages in the repo. It will:
  623. - Ensure the core package version dependencies match everywhere.
  624. - Ensure imported packages match dependencies.
  625. - Ensure a consistent version of all packages.
  626. - Manage the meta package.
  627. The ``packages/metapackage`` package is used to build all of the
  628. TypeScript in the repository at once, instead of 50+ individual builds.
  629. The integrity script also allows you to automatically add a dependency
  630. for a package by importing from it in the TypeScript file, and then
  631. running: ``jlpm run integrity`` from the repo root.
  632. We also have scripts for creating and removing packages in
  633. ``packages/``, ``jlpm run create:package`` and
  634. ``jlpm run remove:package``. When creating a package, if it is meant to
  635. be included in the core bundle, add the
  636. ``jupyterlab: { coreDependency: true }`` metadata to the
  637. ``package.json``. Packages with ``extension`` or ``mimeExtension``
  638. metadata are considered to be a core dependency unless they are
  639. explicitly marked otherwise.
  640. Testing Changes to External Packages
  641. ------------------------------------
  642. Linking/Unlinking Packages to JupyterLab
  643. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  644. If you want to make changes to one of JupyterLab's external packages
  645. (for example, `Lumino <https://github.com/jupyterlab/lumino>`__ and test
  646. them out against your copy of JupyterLab, you can easily do so using the
  647. ``link`` command:
  648. 1. Make your changes and then build the external package
  649. 2. Register a link to the modified external package
  650. - navigate to the external package dir and run ``jlpm link``
  651. 3. Link JupyterLab to modded package
  652. - navigate to top level of your JupyterLab repo, then run
  653. ``jlpm link "<package-of-interest>"``
  654. You can then (re)build JupyterLab (eg ``jlpm run build``) and your
  655. changes should be picked up by the build.
  656. To restore JupyterLab to its original state, you use the ``unlink``
  657. command:
  658. 1. Unlink JupyterLab and modded package
  659. - navigate to top level of your JupyterLab repo, then run
  660. ``jlpm unlink "<package-of-interest>"``
  661. 2. Reinstall original version of the external package in JupyterLab
  662. - run ``jlpm install --check-files``
  663. You can then (re)build JupyterLab and everything should be back to
  664. default.
  665. Possible Linking Pitfalls
  666. ^^^^^^^^^^^^^^^^^^^^^^^^^
  667. If you're working on an external project with more than one package,
  668. you'll probably have to link in your copies of every package in the
  669. project, including those you made no changes to. Failing to do so may
  670. cause issues relating to duplication of shared state.
  671. Specifically, when working with Lumino, you'll probably have to link
  672. your copy of the ``"@lumino/messaging"`` package (in addition to
  673. whatever packages you actually made changes to). This is due to
  674. potential duplication of objects contained in the ``MessageLoop``
  675. namespace provided by the ``messaging`` package.
  676. Keyboard Shortcuts
  677. ------------------
  678. Typeset keyboard shortcuts as follows:
  679. - Monospace typeface, with spaces between individual keys:
  680. ``Shift Enter``.
  681. - For modifiers, use the platform independent word describing key:
  682. ``Shift``.
  683. - For the ``Accel`` key use the phrase: ``Command/Ctrl``.
  684. - Don’t use platform specific icons for modifier keys, as they are
  685. difficult to display in a platform specific way on Sphinx/RTD.
  686. Screenshots and Animations
  687. --------------------------
  688. Our documentation should contain screenshots and animations that
  689. illustrate and demonstrate the software. Here are some guidelines for
  690. preparing them:
  691. - Make sure the screenshot does not contain copyrighted material
  692. (preferable), or the license is allowed in our documentation and
  693. clearly stated.
  694. - If taking a png screenshot, use the Firefox or Chrome developer tools
  695. to do the following:
  696. - set the browser viewport to 1280x720 pixels
  697. - set the device pixel ratio to 1:1 (i.e., non-hidpi, non-retina)
  698. - screenshot the entire *viewport* using the browser developer
  699. tools. Screenshots should not include any browser elements such as
  700. the browser address bar, browser title bar, etc., and should not
  701. contain any desktop background.
  702. - If creating a movie, adjust the settings as above (1280x720 viewport
  703. resolution, non-hidpi) and use a screen capture utility of your
  704. choice to capture just the browser viewport.
  705. - For PNGs, reduce their size using ``pngquant --speed 1 <filename>``.
  706. The resulting filename will have ``-fs8`` appended, so make sure to
  707. rename it and use the resulting file. Commit the optimized png file
  708. to the main repository. Each png file should be no more than a few
  709. hundred kilobytes.
  710. - For movies, upload them to the IPython/Jupyter YouTube channel and
  711. add them to the
  712. `jupyterlab-media <https://github.com/jupyterlab/jupyterlab-media>`__
  713. repository. To embed a movie in the documentation, use the
  714. ``www.youtube-nocookie.com`` website, which can be found by clicking
  715. on the 'privacy-enhanced' embedding option in the Share dialog on
  716. YouTube. Add the following parameters the end of the URL
  717. ``?rel=0&amp;showinfo=0``. This disables the video title and related
  718. video suggestions.
  719. - Screenshots or animations should be preceded by a sentence describing
  720. the content, such as "To open a file, double-click on its name in the
  721. File Browser:".
  722. - We have custom CSS that will add box shadows, and proper sizing of
  723. screenshots and embedded YouTube videos. See examples in the
  724. documentation for how to embed these assets.
  725. To help us organize screenshots and animations, please name the files
  726. with a prefix that matches the names of the source file in which they
  727. are used:
  728. ::
  729. sourcefile.rst
  730. sourcefile_filebrowser.png
  731. sourcefile_editmenu.png
  732. This will help us to keep track of the images as documentation content
  733. evolves.
  734. Notes
  735. -----
  736. - By default, the application will load from the JupyterLab staging
  737. directory (default is ``<sys-prefix>/share/jupyter/lab/build``. If
  738. you wish to run the core application in
  739. ``<git root>/jupyterlab/build``, run ``jupyter lab --core-mode``.
  740. This is the core application that will be shipped.
  741. - If working with extensions, see the :ref:`extension documentation <developer_extensions>`.
  742. - The npm modules are fully compatible with Node/Babel/ES6/ES5. Simply
  743. omit the type declarations when using a language other than
  744. TypeScript.