
Newly created notebooks no longer error on saving - bug in how kernelspec metadata was being filled in. Also a number of miscellaneous fixes to indentation that have inexplicably appeared in the code. Some small fixes for typos and catching up on version info.
8.2 KiB
- Overview
- Design
- Enhancements/Fixes
- Errors on saving new notebook
- Support company-mode
- Inline latex
- Interactive Widgets
- Working with jupyterhub
- Imenu/Speedbar Cooperation
- Live links to other notebooks
- Use polymode
- Use dash?
- Access password protected notebooks (issue #57)
- Connect to non-python kernels
- Synergies with pymacs?
- Detect system path of opened notebook
- Jump to notebook code in traceback (issue #42)
- The Return of Worksheets
- Fixing Tests
Overview
Design
Notebook Format
Version 4.0 documented.
Earlier versions might be documented less formally on the wiki. Can also look at the IPython source in the json viles.
Notebook Buffer
Notebook information is stored as a struct. Always associated with a buffer, ein:notebook-buffer is used to find buffer associated with a notebook.
Notebook does not hold cells, that is delegated to instances of the worksheet class. Instances are stored as a list in the `ein:$notebook-worksheets` slot.
Opened notebooks are kept in the ein:notebook--opened-map
hash
table. Keys are cons cells of url-or-port
and path
.
There are a number of helper functions for returning the struct for an opened notebook:
-
[[file:lisp/ein-notebook.el::(defun%20ein:notebook-get-opened-notebook%20(url-or-port%20path)][ein:notebook-get-opened-notebook]]
-
[[file:lisp/ein-notebook.el::(defun%20ein:notebook-get-opened-buffer%20(url-or-port%20path)][ein:notebook-get-opened-buffer]]
Notebooklist Buffer
Kernel communication
Contents API
Connecting to a running Kernel
Entry point is [[file:lisp/ein-notebook.el::ein:notebook-start-kernel][ein:notebook-start-kernel]]
which is called from
ein:notebook-request-open-callback
after successful call to the notebook
server requesting the contents of a given notebook.
[[file:lisp/ein-kernel.el::ein:kernel-start][ein:kernel-start]]
starts/gets a session with a running kernel using the REST API.
On a successful return ein creates a websocket channel (channels for
IPython 2.x) via a call to websocket-open
in the emacs-websocket
package. The URL request is of the form:
ws://{server_address}:{port}/api/kernels/{kernel id from previous REST query}/channels?session_id={session id}
Enhancements/Fixes
Errors on saving new notebook
Happening because metadata slot is borked when creating new notebooks.
Support company-mode
Inline latex
See issue #88.
Interactive Widgets
For the most part this is a non-starter since in Jupyter this is built on web and javascript, but maybe with emacs 25's coming integration with xwidgets there is hope?
Working with jupyterhub
Jupyterhub requires authentication using username/password, as opposed to just providing a secret when logging into ipython 3.x and earlier.
On logging in a cookie of form "jupyter-hub-token-<username>" is generated and propogated with all calls to server. Emacs request should automatically handle this.
The REST API for this looks like POST http://{host}:{port}/hub/login, username and password parameters in the POST.
Also looks like the content REST API has been modified so that querys are of the form: /user/<username>/<command>.
Imenu/Speedbar Cooperation
Seems to be a couple ways of doing this:
- Configuring `imenu-generic-expression` regex's.
- Redefining imenu-create-index ala python.el.
(2) seems to be the more elegant solution.
EIN currently has minimal support for imenu through `ein:worksheet-imenu-create-index`, but all it does is look for headings. Somehow this fails to work with speedbar and also does not handle indexing Python code (i.e. variables, function, classes, etc.).
To get the speedbar working we will need to define a minor mode per the following instructions.
For /name/~-speedbar-menu-items~ can I just use imenu-generic-expression
?
Maybe the way to do this is for each [[file:lisp/ein-cell.el::ein:codecell][codecell]]
create a temp buffer with the text
of that cell and call ein:imenu-create-index
.
(let ((text (ein:cell-get-text cell)))
(with-temp-buffer
(insert text)
(ein:imenu-create-index)))
Still will need way to map temp buffer positions to actual positions in the
notebook buffer (ein:cell-input-pos-min
and ein:cell-input-pos-max
)
Live links to other notebooks
- Understand how org-mode does it.
- Steal???
- Profit!!!
Use polymode
Polymode uses indirect buffers, which may or may not be a good solution for ein notebooks. I think this is what nxhtml is doing…
Access password protected notebooks (issue #57)
This is what I have found out so far:
You can authenticate with the IPython/Jupyter notebook server using ein:notebooklist-login. After calling this a cookie is generated (very easy to see if you are using curl as the backend for emacs-request) and you can then use the REST API to list and get notebook data.
Once authenticated REST calls to get notebook json data and create sessions work fine. After EIN starts a session one can see the kernel is running from the web interface. The problem starts when ein tries to open a websocket connection to the kernel. The notebook server generates a 403 forbidden response. I think because emacs-websocket doesn't know anything about the security cookie generated during the curl request.
Not sure if that makes sense, but for the moment that is my theory on what's happening. Somehow we need to provide the security cookie with the websocket connect request.
<2015-06-09 Tue> SOLVED(?) - issue is that emacs-websocket needs to provide more info with the connection header:
- Specify the port along with the url.
- Pass along a security cookie.
Connect to non-python kernels
Synergies with pymacs?
Detect system path of opened notebook
Jump to notebook code in traceback (issue #42)
What needs to be done:
- Carry notebook reference in the
[[file:lisp/ein-traceback.el::ein:traceback][ein:traceback]]
structure. - Look for
<ipython-input-3-05c9758a9c21> in <module>()
. The number 3 means input #3 in the notebook. - Find cell based on input number. Can iterate through list of cells () and look for matching
input-prompt-number
. - Call
ein:cell-goto
on that cell. May need to swap buffers first.
The Return of Worksheets
tkf/ein and IPython 2.x allowed for multiple worksheets within an individual notebook. This feature was removed in 3.0 since multiple worksheets do not make much sense in the context of a tabbed web browser interface. EIN's legacy code still supports worksheets, though at the moment that information is lost upon saving a notebook.
Having multiple worksheet support makes some sense for ein; below is thinking on how to reimplement this feature.
IPython nbformat 4 specifies a metadata key which can be used to store general information. Cell metadad has a tag key which is a "A list of string tags on the cell. Commas are not allowed in a tag."
Best place to set the tag key is when generating /hiro/emacs-ipython-notebook/src/commit/c5cf44a7959c5b1fbb0034c93420d79e62ff339b/content for saving a notebook.
Fixing Tests
- Insert output tests are failing - probably due to how we are making the test cell. JSON is per nbformat4, but are we correctly parsing mimetypes (i.e. there is an additional call to do this, are we making it?). Is ein:cell-insert-output getting called?