Commit graph

86 commits

Author SHA1 Message Date
Yuri D. Lensky
9285480715 Update jupyter--encode for new Emacs JSON API.
The old Emacs JSON API (for versions <= 27.2 at time of commit) was
structured in a way that replacing the symbol-function of json-encode
worked to get custom encoding for certain object types used by
emacs-jupyter. In the later API, the function json--print plays the
recursive role of json-encode. The code here works in either version,
and is simplified so that future updates to the API are easier to
accomodate.
2021-04-02 21:04:13 -05:00
Nathaniel Nicandro
403c70c83c Bump version 2020-04-07 15:13:51 -05:00
conao3
fb8c2c75fd two spaces after a period 2020-03-12 18:20:15 -05:00
conao3
1546a72f57 clean header 2020-03-10 23:39:35 -05:00
Nathaniel Nicandro
aee4d39449 jupyter-decode-time: Remove fractional times before calling parse-iso8601-time-string
Emacs 27 seems not to be able to handle this case, maybe never has been able to
handle it properly.
2019-09-15 16:33:30 -05:00
Nathaniel Nicandro
e8edd4d5cc Promote time encoding/decoding functions to public
Also use `parse-iso8601-time-string` when decoding
2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
67831c08fa Support Jupyter kernel servers
* jupyter-client.el (jupyter-initialize-connection): Elevate NOTE to FIXME.
(jupyter-kernel-info): Extend timeout.

* jupyter-kernel-manager.el (jupyter-shutdown-kernel):
(jupyter-interrupt-kernel): Allow any number of arguments.

* jupyter-kernelspec.el (jupyter-find-kernelspecs): Optionally allow specs.

* jupyter-messages.el (jupyter-encode-raw-message): New function.

* jupyter-rest-api.el (jupyter-api-auth-headers): New function.

* jupyter-server-ioloop.el: New file.

* jupyter-server.el: New file.

* test/jupyter-test.el (jupyter-server):
(jupyter-server-kernel-manager):
(jupyter-server-start-new-kernel): New tests.
2019-07-24 16:59:04 -05:00
Nathaniel Nicandro
6650dd3588 Bump version 2019-07-24 16:03:22 -05:00
Nathaniel Nicandro
b40b7de837 Do not depend strongly on zmq
Having the `jupyter-comm-layer` abstraction means we do not need to do so.

* jupyter-base.el (zmq): Un-require.
(jupyter-socket-types): Move to `jupyter-channels.el`.
(jupyter-session): Don't mention zmq in doc string.
(jupyter-available-local-ports, jupyter-make-ssh-tunnel): New functions.
(jupyter-tunnel-connection): Use them.

* jupyter-channel-ioloop-comm.el: New file.

* jupyter-channels.el (jupyter-messages): Un-require.
(jupyter-comm-layer, zmq): New requires.
(jupyter-socket-types): Moved from `jupyter-base.el`.
(jupyter-send, jupyter-recv):
Implementations for `jupyter-session` moved from `jupyter-messages.el`.
(jupyter-sync-channel-comm): `jupyter-comm-layer` implementation for
`jupyter-sync-channel` objects moved from `jupyter-comm-layer.el`.

* jupyter-comm-layer.el (jupyter-channel-ioloop): Un-require.
(jupyter-sync-channel-comm): Move implementation to `jupyter-channels.el`.
(jupyter-ioloop-comm): Move implementation to new file `jupyter-ioloop-comm.el`.
(jupyter-channel-ioloop-comm):
Move implementation to new file `jupyter-channel-ioloop-comm.el`.

* jupyter-ioloop-comm.el: New file.

* jupyter-ioloop.el (zmq): Require.

* jupyter-kernel-manager.el
(jupyter-make-client): Ensure `jupyter-channel-ioloop-comm` is required.

* jupyter-messages.el (jupyter-send)
(jupyter-recv): Moved to `jupyter-channels.el`

* jupyter-repl.el
(jupyter-connect-repl): Ensure `jupyter-channel-ioloop-comm` is required.

* test/jupyter-test.el (jupyter-available-local-ports): New test.

* test/test-helper.el (jupyter-channel-ioloop-comm): New require.
2019-06-29 10:29:55 -05:00
Nathaniel Nicandro
9dd8e8d9ec Localize functions defined in jupyter-base.el to their call sites
Fixes #137

* jupyter-base.el (jupyter-kernelspec): Un-require.
(jupyter-command, jupyter-locate-python)
(jupyter-runtime-directory): Move to new file `jupyter-env.el`
(jupyter-include-other-output, jupyter-iopub-message-hook)
(jupyter-shell-message-hook)
(jupyter-stdin-message-hook): Move to `jupyter-client.el`
(jupyter-sha256, jupyter-hmac-sha256):
(jupytern-new-uuid): Move to `jupyter-messages.el`. Add declaration of
`jupyter-new-uuid` to account for its removal.
(jupyter-create-connection-info)
(jupyter-write-connection-file): Move to `jupyter-kernel-manager.el`
(jupyter-connect-endpoint, jupyter-connect-channel): Move to `jupyter-channels.el`

* jupyter-channels.el: Accept moved functions.

* jupyter-client.el: Accept moved variables.

* jupyter-kernel-manager.el: Accept moved functions.
(jupyter-env, jupyter-kernelspec): New requires.

* jupyter-kernelspec (jupyter-env): New require.
(jupyter-command): Remove declaration.
(jupyter-read-plist-from-string): New declaration.

* jupyter-messages.el: Accept moved functions.
(hmac-def, json): New requires.

* jupyter-org-extensions.el (jupyter-kernelspec): New require.

* jupyter-repl.el (jupyter-kernelspec): New require.

* jupyter-env.el: New file.

* ob-jupyter.el (jupyter-env, jupyter-kernelspec): New requires.

* test/jupyter-test.el (jupyter-env): New require.
2019-06-29 10:29:55 -05:00
Nathaniel Nicandro
5ea32a70f0 Change License to GPL3 2019-05-31 09:44:39 -05:00
Nathaniel Nicandro
112769e0c6
Bump version 2019-05-04 03:31:50 -05:00
Nathaniel Nicandro
b2294dceb2 Generalize communication with a kernel
The previous mechanism to communicate with a kernel was too low level from the
perspective of a client. The client interfaced directly with the subprocess
abstraction, `jupyter-ioloop`, and had to handle all "events" that occurred in
the `jupyter-ioloop`, e.g. when a channel was started or stopped. But in
reality such events should not be the concern of a client.

A client should only care about events that are directly related to kernel
messages and not events related to the implementation details of *how*
communication occurs.

This commit abstracts out the way in which a client communicates with its
kernel by introducing a new `jupyter-comm-layer` class. The
`jupyter-comm-layer` class takes care of managing the communication channel
between a kernel and its clients as well as sending events to all registered
clients. This way, clients operate solely at the level of events on the
communication layer. All a client does is register itself to receive events on
the communication layer and send events on the layer.

* jupyter-base.el (jupyter-session-endpoints): New function.

* jupyter-client.el (jupyter-kernel-client): Remove ioloop and channels slots.
  Add kcomm slot.
(initialize-instance): Unconditionally stop channels.
(jupyter-initialize-connection): Change into a method call.
Call `jupyter-initialize-connection` on the `kcomm` slot.
(jupyter-with-client-buffer): Remove stale comment.
(jupyter-send): Call `jupyter-send` on the `kcomm` slot.
(jupyter-ioloop-handler): Remove all method definitions, replace `sent` and
`message` methods with their `jupyter-event-handler` equivalents.
(jupyter-hb-pause, jupyter-hb-unpause, jupyter-hb-beating):
(jupyter-channel-alive-p, jupyter-start-channel, jupyter-stop-channel):
(jupyter-start-channels, jupyter-stop-channels):
Replace with calls to their equivalents using the `kcomm` slot.

* jupyter-comm-layer.el: New file.

* jupyter-kernel-manager (jupyter-make-client): Set a client's `kcomm` slot to
  `jupyter-channel-ioloop-comm`.

* jupyter-messages.el (jupyter-decode-message): Use `list` directly. There
  seemed to be issues when using the new `jupyter-sync-channel-comm` due to
  using quoted lists.

* test/jupyter-test.el: Add `jupyter-comm-layer` test. Update other tests.

* test/test-helper.el: Add `jupyter-comm-layer` mock objects. Update
  `jupyter-echo-client`.
2019-04-11 20:13:44 -05:00
Nathaniel Nicandro
83af335166
Bump version 2019-03-14 09:29:11 -05:00
Nathaniel Nicandro
662e983612
Don't require subr-x at runtime 2019-03-14 09:16:44 -05:00
Nathaniel Nicandro
d4969cbfcc CHANGELOG.org: Add function to change version numbers 2019-02-14 23:05:00 -06:00
Nathaniel Nicandro
63717b9e39
Bump version 2019-02-12 09:17:06 -06:00
Nathaniel Nicandro
4e2e8642ed
Update a few comments 2019-01-22 18:39:17 -06:00
Nathaniel Nicandro
d709b31a64
Add jupyter-message-lambda
This simplifies the writing of message callbacks.
2019-01-22 18:39:17 -06:00
Nathaniel Nicandro
9560af95b2
jupyter-with-message-data: Add debug spec 2019-01-19 15:27:19 -06:00
Nathaniel Nicandro
1c6a5e4363
jupyter--decode-message-part: Return nil when MSG is nil 2019-01-17 18:59:41 -06:00
Nathaniel Nicandro
916b2cf912 jupyter-with-message-content: Fix debug declaration 2018-11-26 12:37:37 -06:00
Nathaniel Nicandro
50ac28910a Remove usage of deprecated when-let
This was deprecated in Emacs 26.1
2018-11-16 04:59:09 -06:00
Nathaniel Nicandro
ca44a3922d Use universal time when encoding time values
* jupyter-messages.el (jupyter--encode-time): Do it.

* test/jupyter-test.el (jupyter-messages): Update test.
2018-11-16 04:49:43 -06:00
Nathaniel Nicandro
081f329da1 v0.6.0 2018-11-16 00:27:47 -06:00
Nathaniel Nicandro
a4e7fbf7ba Use defsubst for some message functions
* jupyter-messages.el (jupyter-message-id, jupyter-message-parent-id):
(jupyter-message-type, jupyter-message-session, jupyter-message-parent-type):
(jupyter-message-get, jupyter-message-data, jupyter-message-status-idle-p): Do it.
2018-11-15 23:04:27 -06:00
Nathaniel Nicandro
4dc229935b jupyter-messages.el: Update commentary 2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
1371947785 jupyter-message-type-as-keyword: Simplify loop
* jupyter-messages.el (jupyter-message-type-as-keyword): Do it.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
d3dc23d2b1 jupyter--decode: Simplify post processing of :msg_type key
* jupyter-messages.el (jupyter--decode): Do it.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
0fb39492e3 jupyter-encode-message: Refactor
* jupyter-messages.el (jupyter-encode-message): Do it.
(jupyter--message-header): Require MSG-ID argument. Given by
`jupyter-encode-message'.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
344e7b72ce jupyter--split-identities: Simplify loop
* jupyter-messages.el (jupyter--split-identities): Do it.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
d124ea2d64 jupyter-decode-message: Remove unnecessary quoting
* jupyter-messages.el (jupyter-decode-message): Do it.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
8c870cf592 jupyter-sign-message: Simplify loop
* jupyter-messages.el (jupyter-sign-message): Do it.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
7aa43f6464 Decode :date fields on demand
* jupyter-messages.el (jupyter--decode): Remove handling of :date field.
(jupyter-message-time): Decode :date field if necessary.
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
a93f38608c Allow a SIGNER argument to message encode, decode, and signing functions
* jupyter-messages.el: (jupyter--sign-message)
(jupyter--decode-message, jupyter--encode-message):
Promote to public functions. Update all callers.
(jupyter-sign-message): Add optional SIGNER argument.
(jupyter-decode-message, jupyter-encode-message): Add SIGNER key argument.
SIGNER argument defaults to `jupyter-hmac-sha256`
2018-11-13 17:46:07 -06:00
Nathaniel Nicandro
348541dfe7 Update documentation and commentary 2018-11-08 21:30:32 -06:00
Nathaniel Nicandro
becddfc9ea Fix requires
`jupyter-channels.el` depends on the `jupyter-send` method defined in
`jupyter-messages.el` whereas `jupyter-messages.el` does not depend on any
functions in `jupyter-channels.el`.

* jupyter-channel.el: Require `jupyter-messages`

* jupyter-messages.el: Remove `jupyter-channels` require
2018-11-08 21:30:32 -06:00
Nathaniel Nicandro
c30357badb jupyter-with-message-content: Allow debugging inside the macro 2018-10-31 18:49:37 -05:00
Nathaniel Nicandro
1697f44761 jupyter-with-message-content: Reword documentation 2018-10-27 22:16:54 -05:00
Nathaniel Nicandro
e06e61e9fd jupyter-messages.el: Small documentation changes 2018-10-25 23:17:27 -05:00
Nathaniel Nicandro
e43c6597ad Add convenience macros for working with messages 2018-10-25 23:17:27 -05:00
Nathaniel Nicandro
c070f2d04d Update documentation and comments 2018-10-25 22:57:23 -05:00
Nathaniel Nicandro
0bf30538e6 Refactor encoding/decoding of message-part lists for readability 2018-10-16 13:55:57 -05:00
Nathaniel Nicandro
7b3e4f9f84 Fix encoding/decoding time objects
* Handle the case of no time specification by defaulting to midnight when
  decoding time

* Properly handle fractions in `jupyter--decode-time`

* Implement `jupyter--encode-time`

* Consider a time object to be a length 4 list of integers and encode the
  object using `jupyter--encode-time` when encoding in `jupyter--encode`

* Add tests for time decoding/encoding
2018-10-16 13:55:30 -05:00
Nathaniel Nicandro
ce3d9a377c Refactor jupyter--sign-message 2018-05-30 12:54:55 -05:00
Nathaniel Nicandro
122748b25e Do not pass the signature when signing message parts 2018-05-30 12:54:55 -05:00
Nathaniel Nicandro
7c218b233c Ensure that parts of a message that need to be dictionaries are encoded as such 2018-05-30 12:54:55 -05:00
Nathaniel Nicandro
70be58129e Rename jupyter-message-parent-message-type -> jupyter-message-parent-type 2018-05-30 12:49:28 -05:00
Nathaniel Nicandro
f4c931d57d Avoid double encoding, document message functions, small fixes to message functions
This introduces a way of keeping track of both the encoded and decoded parts of
a message, only decoding the parts of a message when needed, and only encoding
the parts of a message when needed.

If the objects passed to `jupyter--encode` or `jupyter--decode` are lists with
the first element being the symbol `message-part`, then the second element of
the list is interpreted as being the encoded message and the third element
being the decoded part of the message. If either the encoded or the decoded
part are nil, then `jupyter--encode` or `jupyter--decode` will fill those
message parts in and on subsequent calls, passing in the same list, no work
will need to be performed.

This avoids double encoding messages when relaying messages between the channel
subprocess and the browser displaying widgets. This speeds up the communication
process. The cost is storing two representations of the same message, i.e.
speed vs memory.

Fixes:

- Use `eq` instead of `equal` in message status predicates
- Fix time string decoding
  - `parse-time-string` was returning all nil on Emacs 26
- Include validation for parent header in `jupyter--encode-message`
- Use `jupyter-message-header' to access the message header instead of `plist-get`
2018-05-28 01:25:33 -05:00
Nathaniel Nicandro
436089d08b Prefer defun over defsubst and other miscellaneous changes
- Add missing namespace to sha256 function

  - Any function defined should have a `jupyter-` prefix

- Remove `cl-lib` dependency in `jupyter-messages.el`

- Include `subr-x` in `jupyter-base.el`

- Use `tramp-file-name-user` instead of `tramp-file-name-real-user` since the
  latter is missing in Emacs 26
2018-05-28 01:25:33 -05:00