Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various things #353

Merged
merged 25 commits into from
Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e7fc81a
Tweak .travis.yml
alexarchambault Apr 9, 2019
9000eaf
Rework API / helpers to display stuff
alexarchambault Apr 9, 2019
fd29d93
Deprecate former almond.api.helpers.Display
alexarchambault Apr 9, 2019
9253763
Tweak updatable results API
alexarchambault Apr 10, 2019
c17cd72
Move access instances pages last
alexarchambault Apr 11, 2019
7c4ce3e
Add fade-in effect when updating pretty-printed values
alexarchambault Apr 11, 2019
e1520b0
Add almond.display.PrettyPrint
alexarchambault Apr 11, 2019
162a34e
Tweak auto-updated future message
alexarchambault Apr 11, 2019
da5cd5d
Auto-update var-s on change
alexarchambault Apr 11, 2019
02a9ba0
Move execution-related stuff to separate class
alexarchambault Apr 11, 2019
cd8a371
Split / refactor ScalaInterpreter
alexarchambault Apr 11, 2019
2827260
Tweak var-s auto update
alexarchambault Apr 11, 2019
2ccc191
Auto-update lazy val-s too
alexarchambault Apr 11, 2019
3a4ab44
More deterministic check in test
alexarchambault Apr 11, 2019
d146707
Implement ammonite.repl.ReplAPI.lastException
alexarchambault Apr 12, 2019
0da728d
Add missing imports in completion
alexarchambault Apr 12, 2019
88dc15e
Call shutdown hooks before exit
alexarchambault Apr 12, 2019
9b4c9b4
Fill some gaps in Ammonite API doc page
alexarchambault Apr 12, 2019
91a053f
Implement ReplAPI.history
alexarchambault Apr 12, 2019
58f7e27
Fill gaps in Ammonite API page
alexarchambault Apr 12, 2019
ef1ef10
Add high level API for input
alexarchambault Apr 12, 2019
f77b654
Update jupyter API page
alexarchambault Apr 12, 2019
22abad2
Don't use colors if these seems to be disabled
alexarchambault Apr 12, 2019
001b530
Clean-up
alexarchambault Apr 12, 2019
ca62c85
Allow to disable auto-updates via CLI flags
alexarchambault Apr 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ stages:
if: (branch = master AND type = push) OR (tag IS present)
jobs:
include:
- env: VALIDATE_EXAMPLES=1 # unused from the script, just to know what the job does from the Travis UI
- name: "Validate examples"
addons:
apt:
sources:
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ lazy val `scala-interpreter` = project
Nil
}
},
libraryDependencies += "org.fusesource.jansi" % "jansi" % "1.18",
crossVersion := CrossVersion.full,
testSettings
)
Expand Down
120 changes: 108 additions & 12 deletions docs/pages/api-ammonite.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,90 @@ The following instances are available:

### Load dependencies

???
`interp.load.ivy` accepts one or several
[`coursier.Dependency`](https://github.com/coursier/coursier/blob/ac5a6efa3e13925f0fb1409ea45d6b9a29865deb/modules/coursier/shared/src/main/scala/coursier/package.scala#L19).

Load simple dependencies
```scala
interp.load.ivy("org.platanios" %% "tensorflow-data" % "0.4.1")
```

Load dependencies while adjusting some parameters
```scala
interp.load.ivy(
coursier.Dependency(
module = coursier.Module("org.platanios", "tensorflow_2.12"),
version = "0.4.1",
// replace with linux-gpu-x86_64 on linux with nvidia gpu or with darwin-cpu-x86_64 on macOS
attributes = coursier.Attributes("", "linux-cpu-x86_64")
)
)
```

The dependencies can then be used in the cell right _after_ the one calling
`interp.load.ivy`.

Note that in the case of simple dependencies, when directly entering code
in a notebook,
the following syntax is preferred
and allows to use the dependency in the current cell rather than the next one:
```scala
import $ivy.`org.platanios::tensorflow-data:0.4.1`
```

### Load compiler plugins

???
`interp.load.plugin.ivy` accepts one or several
[`coursier.Dependency`](https://github.com/coursier/coursier/blob/ac5a6efa3e13925f0fb1409ea45d6b9a29865deb/modules/coursier/shared/src/main/scala/coursier/package.scala#L19).

```scala
interp.load.plugin.ivy("org.spire-math" %% "kind-projector" % "0.9.9")
```
The plugins can then be used in the cell right _after_ the one calling
`interp.load.plugin.ivy`.


Note that when directly entering code in a notebook, the following syntax
is more concise, and allows to use the compiler plugin in the current cell:
```scala
import $plugin.$ivy.`org.spire-math::kind-projector:0.9.9`

// example of use
trait T[F[_]]
type T2 = T[Either[String, ?]]
```

### Add repositories

???
One can add extra
[`coursier.Repository`](https://github.com/coursier/coursier/blob/ac5a6efa3e13925f0fb1409ea45d6b9a29865deb/modules/coursier/shared/src/main/scala/coursier/package.scala#L69) via

```scala
interp.repositories() ++= Seq(MavenRepository(
"https://nexus.corp.com/content/repositories/releases",
authentication = Some(Authentication("user", "pass"))
))
```

### Add exit hooks

???
```scala
interp.beforeExitHooks += { _ =>
// called before the kernel exits
}
```

### Configure compiler options

???
```scala
// enable warnings
interp.configureCompiler(_.settings.nowarn.value = false)
```

## `ReplAPI`

[`ReplAPI`](https://github.com/lihaoyi/Ammonite/blob/master/amm/repl/src/main/scala/ammonite/repl/ReplAPI.scala) allows to
- [access the pretty-printer and customize its behavior](#pretty-printer),
- [access the latest thrown exception](#latest-thrown-exception),
- [access the command history](#command-history),
- [request the compiler instance to be re-created](#refresh-compiler-instance),
Expand All @@ -51,30 +114,63 @@ The following instances are available:
- [get the class names and byte code](#byte-code-of-repl-inputs) of the code entered during the current
session.

### Pretty-printer

```scala
class Foo(val x: Int)

repl.pprinter() = {
val p = repl.pprinter()
p.copy(
additionalHandlers = p.additionalHandlers.orElse {
case f: Foo =>
pprint.Tree.Lazy(_ => Iterator(fansi.Color.Yellow(s"foo: ${f.x}").render))
}
)
}
```

### Latest thrown exception

???
```scala
repl.lastException // last thrown exception, or null if none were thrown
```

### Command history

???
```scala
repl.history // current session history
repl.fullHistory // shared history
```

### Refresh compiler instance

???
```scala
repl.newCompiler()
```

### Get compiler instance

???
```scala
repl.compiler // has type scala.tools.nsc.Global
```

### Get current imports

???
```scala
repl.imports
```

### Evaluate code

???
```scala
repl.load("val a = 2")
```

### Byte code of REPL inputs

???
```scala
repl.sess.frames.flatMap(_.classloader.newFileDict).toMap
// Map[String, Array[Byte]], keys: class names, values: byte code
```

105 changes: 80 additions & 25 deletions docs/pages/api-jupyter.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,68 @@ The Almond Jupyter API can be accessed via an instance of [`almond.api.JupyterAP
instance is created by almond upon start-up. This instance accessible via the `kernel` variable and in the
implicit scope via e.g. `implicitly[almond.api.JupyterAPI]`.

A number of higher level helpers rely on it, and provide [a more convenient API to display objects](#display).

## High level API

### Display

A number of classes under [`almond.display`](https://github.com/almond-sh/almond/tree/master/modules/scala/jupyter-api/src/main/scala/almond/display)
provide an API similar to the
[IPython display module](https://ipython.readthedocs.io/en/7.4.0/api/generated/IPython.display.html).

Examples:
```scala
// These can be used to display things straightaway
Html("<b>Bold</b>")
```

```scala
// A handle can also be retained, to later update or clear things
val handle = Markdown("""
# title
## section
text
""")

// can be updated in later cells
// (this updates the previous display)
handle.withContent("""
# updated title
## new section
_content_
""").update()

// can be later cleared
handle.clear()
```

### Input

```scala
// Request input from user
val result = Input().request()
```

```scala
val result = Input().withPrompt(">>> ").request()
```

```scala
// Request input via password field
val result = Input().withPassword().request()
```


## `JupyterAPI`

`almond.api.JupyterAPI` allows to
- [request input](#request-input) (password input in particular),
- [exchange comm messages](#comm-messages) with the front-end.
- [display data](#display-data) (HTML, text, images, …) in the front-end while a cell is running,
- [update a previous display](#updatable-display-data) in the background (while the initial cell is running or not),
- [exchange comm messages](#comm-messages) with the front-end.

Note that most of its capabilities have more convenient alternatives, see [High level API](#high-level-api).

### Request input

Expand All @@ -24,6 +79,30 @@ kernel.stdin(prompt = ">> ", password = true) // password input, with custom pro

![](/demo/stdin.gif)

### Comm messages

[Comm messages](https://jupyter-notebook.readthedocs.io/en/5.7.2/comms.html) are part of the
[Jupyter messaging protocol](https://jupyter-client.readthedocs.io/en/5.2.3/messaging.html). They
allow the exchange of arbitrary messages between code running in the front-end (typically JavaScript code)
and kernels.

The comm API can be used to receive messages, or send them.

`kernel.comm.receiver` allows to register a target to receive messages from the front-end, like
```scala
val id = java.util.UUID.randomUUID().toString
kernel.publish.html("Waiting", id)

kernel.comm.receiver("A") { data =>
// received message `data` from front-end
kernel.publish.updateHtml(s"<code>$data</code>", id)
}
```

![](/demo/comm-receive.gif)

TODO Send to client

### Display data

The `publish` field, of type [`almond.interpreter.api.OutputHandler`](https://github.com/almond-sh/almond/blob/master/modules/shared/interpreter-api/src/main/scala/almond/interpreter/api/OutputHandler.scala), has numerous methods to push display data to the front-end.
Expand Down Expand Up @@ -74,27 +153,3 @@ kernel.publish.updateHtml("Got all items", id)
```

![](/demo/updatable.gif)

### Comm messages

[Comm messages](https://jupyter-notebook.readthedocs.io/en/5.7.2/comms.html) are part of the
[Jupyter messaging protocol](https://jupyter-client.readthedocs.io/en/5.2.3/messaging.html). They
allow the exchange of arbitrary messages between code running in the front-end (typically JavaScript code)
and kernels.

The comm API can be used to receive messages, or send them.

`kernel.comm.receiver` allows to register a target to receive messages from the front-end, like
```scala
val id = java.util.UUID.randomUUID().toString
kernel.publish.html("Waiting", id)

kernel.comm.receiver("A") { data =>
// received message `data` from front-end
kernel.publish.updateHtml(s"<code>$data</code>", id)
}
```

![](/demo/comm-receive.gif)

TODO Send to client
2 changes: 1 addition & 1 deletion docs/website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Try it": ["try-mybinder", "try-docker"],
"Installation": ["quick-start-install", "install-options", "install-multiple", "install-versions", "install-other"],
"Usage": ["usage-plotting", "usage-spark"],
"User API": ["api", "api-access-instances", "api-ammonite", "api-jupyter"],
"User API": ["api", "api-ammonite", "api-jupyter", "api-access-instances"],
"Development": ["dev-from-sources", "dev-custom-kernel", "dev-libraries", "dev-website"]
}
}
Loading