View Source Kino (Kino v0.5.2)

Client-driven interactive widgets for Livebook.

Kino is the library used by Livebook to render rich and interactive outputs directly from your Elixir code.

Built-in widgets

Kino renders any data structure that implements the Kino.Render protocol, falling back to the Kernel.inspect/2 representation whenever an implementation is not available. The data structures supported by Kino out of the box are:

VegaLite

VegaLite specifications are rendered as visualizations:

Vl.new(...)
|> Vl.data_from_series(...)
|> ...

Kino.VegaLite

Kino.VegaLite is an extension of VegaLite that allows data to be streamed:

widget =
  Vl.new(...)
  |> Vl.data_from_series(...)
  |> ...
  |> Kino.VegaLite.new()
  |> Kino.render()

Kino.VegaLite.push(widget, %{x: 1, y: 2})

Kino.ETS

Kino.ETS implements a data table output for ETS tables in the system:

tid = :ets.new(:users, [:set, :public])
Kino.ETS.new(tid)

Kino.DataTable

Kino.DataTable implements a data table output for user-provided tabular data:

data = [
  %{id: 1, name: "Elixir", website: "https://elixir-lang.org"},
  %{id: 2, name: "Erlang", website: "https://www.erlang.org"}
]

Kino.DataTable.new(data)

Kino.Image

Kino.Image wraps binary image content and can be used to render raw images of any given format:

content = File.read!("/path/to/image.jpeg")
Kino.Image.new(content, "image/jpeg")

Kino.Markdown

Kino.Markdown wraps Markdown content for richer text rendering.

Kino.Markdown.new("""
# Example

A regular Markdown file.

## Code

```elixir
"Elixir" |> String.graphemes() |> Enum.frequencies()
```

## Table

| ID | Name   | Website                 |
| -- | ------ | ----------------------- |
| 1  | Elixir | https://elixir-lang.org |
| 2  | Erlang | https://www.erlang.org  |
""")

Kino.Ecto

Kino.Ecto implements a data table output for arbitrary Ecto queries:

Kino.Ecto.new(Weather, Repo)

Kino.Frame

Kino.Frame is a placeholder for static outputs that can be dynamically updated.

widget = Kino.Frame.new() |> Kino.render()

for i <- 1..100 do
  Kino.Frame.render(widget, i)
  Process.sleep(50)
end

Also see Kino.animate/3.

User interactions

Kino.Input and Kino.Control provide a set of widgets for entering data and capturing user events. See the respective module documentation for examples.

All others

All other data structures are rendered as text using Elixir's Kernel.inspect/2.

Custom widgets

Kino makes it possible to define custom JavaScript powered widgets, see Kino.JS and Kino.JS.Live for more details.

Link to this section Summary

Functions

Returns a widget that periodically calls the given function to render a new result.

Configures Kino.

Inspects the given term as cell output.

Returns a special value that results in no visible output.

Renders the given term as cell output.

Starts a process under the Kino supervisor.

Link to this section Types

Specs

nothing() :: :"do not show this result in output"

Link to this section Functions

Link to this function

animate(interval_ms, acc, fun)

View Source

Specs

animate(
  pos_integer(),
  term(),
  (term() -> {:cont, term(), acc :: term()} | :halt)
) :: nothing()

Returns a widget that periodically calls the given function to render a new result.

The callback is run every interval_ms milliseconds and receives the accumulated value. The callback should return either of:

  • {:cont, term_to_render, acc} - the continue

  • :halt - to no longer schedule callback evaluation

This function uses Kino.Frame as the underlying widget.

Examples

# Render new Markdown every 100ms
Kino.animate(100, 0, fn i ->
  md = Kino.Markdown.new("**Iteration: `#{i}`**")
  {:cont, md, i + 1}
end)

Specs

configure(keyword()) :: :ok

Configures Kino.

The supported options are:

  • :inspect

They are discussed individually in the sections below.

Inspect

A keyword list containing inspect options used for printing usual evaluation results. Defaults to pretty formatting with a limit of 50 entries.

To show more entries, you configure a higher limit:

Kino.configure(inspect: [limit: 200])

You can also show all entries by setting the limit to :infinity, but keep in mind that for large data structures it is memory-expensive and is not an advised configuration in this case. Instead prefer the use of IO.inspect/2 with :infinity limit when needed.

See Inspect.Opts for the full list of options.

Link to this function

inspect(term, opts \\ [])

View Source

Specs

inspect(
  term(),
  keyword()
) :: term()

Inspects the given term as cell output.

This works essentially the same as IO.inspect/2, except it always produces colored text and respects the configuration set with configure/1.

Opposite to render/1, it does not attempt to render the given term as a widget.

Specs

nothing() :: nothing()

Returns a special value that results in no visible output.

Specs

render(term()) :: term()

Renders the given term as cell output.

This effectively allows any Livebook cell to have multiple evaluation results.

Specs

Starts a process under the Kino supervisor.

The process is automatically terminated when the current process terminates or the current cell reevaluates.