17
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2022

Day 3

「What's new in Livebook 0.7」YouTubeを楽しみました(Elixir)

Last updated at Posted at 2022-10-16

はじめに

What's new in Livebook 0.7」と題したYouTubeがあります。
José Valimさんが紹介していました。

このツイートのリンク先に、YouTubeの紹介があります。

What's new in Livebook 0.7

  1. Secret management
  2. Visual representations of the running system (supervision trees, inter-process messaging, and more)
  3. Interactive user interface to visualize and edit Elixir pipelines

上記3点です。
ひとつずつ見ていきます。
まず動画をご覧になってください。
以下、動画を見ている前提で、動画の中で使われているコードスニペットやポイントのみを記しておきます。
ただし、動画で使われたコードスニペットはすべて書き写せているわけではありません。

Livebookの起動

Dockerで動かします。

docker run -p 8080:8080 -p 8081:8081 --pull always livebook/livebook

Secret management

左端の :lock: アイコンから設定します。

スクリーンショット 2022-10-16 21.09.38.png

NAMEをAPI_USERNAMEとした場合、コードで読み出す場合は接頭辞LB_をつけて、LB_API_USERNAMEとしてSystem.fetch_env!/1で読み出します。

Reqのインストールが未でしたら、インストールします。

Mix.install([:req])
api_username = System.fetch_env!("LB_API_USERNAME")
api_password = System.fetch_env!("LB_API_PASSWORD")

Req.get!("https://postman-echo.com/basic-auth", auth: {api_username, api_password})

Visual representations of the running system (supervision trees, inter-process messaging, and more)

kinoのインストールが未でしたら、インストールします。

Mix.install([:kino])
f = fn ->
  parent = self()

  child = 
    spawn(fn ->
      receive do
        :ping -> send(parent, :pong)
      end
    end)

  send(child, :ping)

  receive do
    :pong -> :ponged!
  end
end

Kino.Process.render_seq_trace(fn ->
  f.()
end)

スクリーンショット 2022-10-16 21.23.52.png

Kino.Process.render_seq_trace(fn ->
  1..4
  |> Task.async_stream(fn i ->
    i
  end)
  |> Stream.run()
end)

スクリーンショット 2022-10-16 21.28.36.png

{:ok, supervisor_pid} =
  Supervisor.start_link(
    [
      {Task, fn -> Process.sleep(:infinity) end},
      {Agent, fn -> [] end}
    ],
    strategy: :one_for_one
  )
Kino.Process.render_sup_tree(supervisor_pid)
supervisor_pid

スクリーンショット 2022-10-16 21.33.17.png

Interactive user interface to visualize and edit Elixir pipelines

"Elixir is cool!"
|> String.trim_trailing("!")
|> String.split()
|> List.first()
|> dbg()

まずこのコードで、Kernel.dbg/2の説明がされました。

Elixir の dbg を Livebook で遊び倒す

@RyoWakabayashi さんの記事がまんま紹介されていました。
こちらを試すときは、いくつかミドルウェアが必要です。

docker run -p 8080:8080 -p 8081:8081 --pull always livebook/livebook

の実行環境下では、Mix.install/2のときに以下のエラーが発生します。

12:43:02.464 [warning] Failed to load nif: {:load_failed, 'Failed to load NIF library /home/livebook/.cache/mix/installs/elixir-1.14.0-erts-12.3.2.2/bfadb99b0851f0ef64f7e431eb2b2d46/_build/dev/lib/evision/priv/evision: \'libgtk-x11-2.0.so.0: cannot open shared object file: No such file or directory\''}

そこでこの記事では、macOSで動かしてみます。
参考: Dockerコンテナで動かす方法は、「Elixir の dbg を Livebook で遊び倒す ーー 画像処理をDockerで楽しむ」にまとめています。

brew install ffmpeg@4
echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> ~/.zshenv
source ~/.zshenv
brew link --overwrite ffmpeg@4

上記は私のmacOSで行った手順です。
お試しされるマシンの状態により、必要に応じて調整してください。
特に、brew link --overwrite ffmpeg@4 はよくよく意味をご理解した上で実施してください。
ちなみに私は説明できません。

ままよ、どうにでもなれ! という気持ちで実行しています。

踏み出せば
その一足が道となり
その一足が道となる
迷わず行けよ(エンター押せよ)
行けばわかるさ
ありがとうーーーーッ!
の気持ちで実行しています。

git clone https://github.com/livebook-dev/livebook.git
cd livebook
git checkout -b tag-v0.7.1 v0.7.1
mix deps.get --only prod
MIX_ENV=prod mix phx.server
Mix.install([
  :download, :evision, :kino, :nx
])

特にバージョンは指定せず実行しました。
2022-10-16現在、以下がインストールされました。
Application.loaded_applications()で調べました。

Hex バージョン
download 0.0.4
evision 0.1.12
kino 0.7.0
nx 0.3.0
alias Evision, as: OpenCV

defmodule Helper do
  def download!(url, save_as) do
    unless File.exists?(save_as) do
      Download.from(url, path: save_as)
    end

    save_as
  end

  def show_image(mat) do
    OpenCV.imencode(".png", mat)
    |> IO.iodata_to_binary()
    |> Kino.Image.new(:png)
  end

  def show_image_from_path(image_path) do
    image_path
    |> File.read!()
    |> Kino.Image.new(:jpeg)
  end
end

元記事とは使用しているEvisionのバージョンが異なります。
私は、0.1.12を使っています。
imencode!は存在しないと言われたので、カンで!を外しました。
Hexのドキュメントをチラ見しつつ、カンで適当に変更しました。
動きました。

image_path = "dog.jpg"

"https://raw.githubusercontent.com/pjreddie/darknet/master/data/dog.jpg"
|> Helper.download!(image_path)
|> Helper.show_image_from_path()
move = 
  [
    [1, 0, 100],
    [0, 1, 50]
  ]
  |> Nx.tensor(type: {:f, 32})
  |> OpenCV.Nx.to_mat()

rotation = OpenCV.getRotationMatrix2D({512 / 2, 512 / 2}, 90, 1)

image_path
|> OpenCV.imread()
|> OpenCV.blur({9, 9})
|> OpenCV.warpAffine(move, {512, 512})
|> OpenCV.warpAffine(rotation, {512, 512})
|> OpenCV.rectangle({50, 10}, {125, 60}, {255, 0, 0})
|> OpenCV.ellipse({300, 300}, {100, 200}, 30, 0, 360, {255, 255, 0}, thickness: 3)
|> Helper.show_image()
|> dbg()

繰り返します。
元記事とは使用しているEvisionのバージョンが異なります。
私は、0.1.12を使っています。
!付きのメソッドがなくなっていたり、関数の戻り値がタプルではなくなっていたり、引数がListではなくタプルで指定するようになっていたりしました。
Hexのドキュメントをチラ見しつつ、カンで適当に変更しました。
動きました:tada:

スクリーンショット 2022-10-16 23.00.52.png

猫たち

Mix.install([
  :kino
])
urls = [
  "https://images.unsplash.com/photo-1603203040743-24aced6793b4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&h=580&q=80",
  "https://images.unsplash.com/photo-1578339850459-76b0ac239aa2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&h=580&q=80",
  "https://images.unsplash.com/photo-1633479397973-4e69efa75df2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&h=580&q=80",
  "https://images.unsplash.com/photo-1597838816882-4435b1977fbe?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&h=580&q=80",
  "https://images.unsplash.com/photo-1629778712393-4f316eee143e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&h=580&q=80",
  "https://images.unsplash.com/photo-1638667168629-58c2516fbd22?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&h=580&q=80"
]


images = 
  for {url, i} <- Enum.with_index(urls, 1) do
    image = Kino.Markdown.new("![](#{url})")
    label = Kino.Markdown.new("**Image #{i}**")
    Kino.Layout.grid([image, label], boxed: true)
  end

Kino.Layout.grid(images, columns: 3)

スクリーンショット 2022-10-16 23.16.43.png

おわりに

What's new in Livebook 0.7」と題されたYouTubeを私は楽しみました。
見るだけではなくコードを書いたほうが楽しめますので私は書きました。
この記事では、そのコードスニペットを共有しました。

Livebook v0.7に追加された、3つの機能を紹介しました。

  1. Secret management
  2. Visual representations of the running system (supervision trees, inter-process messaging, and more)
  3. Interactive user interface to visualize and edit Elixir pipelines

Enjoy Elixir!!!


追伸

私は、動画をみながら文字起こししました。
よくよく元記事をよくみると、コードスニペットは載っていました :sweat_smile:
Evisionのバージョンアップに伴う関数IFの変更に追従したのがこの記事のレゾンデートルです。
私自身は、写すことを楽しみました。

17
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?