Packages
livebook
0.14.0-rc.1
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook/apps/teams_app_spec.ex
defmodule Livebook.Apps.TeamsAppSpec do
# App spec for organization apps fetched from Livebook Teams.
@enforce_keys [:slug, :version, :hub_id, :app_deployment_id]
defstruct [:slug, :version, :hub_id, :app_deployment_id]
end
defimpl Livebook.Apps.AppSpec, for: Livebook.Apps.TeamsAppSpec do
alias Livebook.Hubs
def load(app_spec, files_tmp_path) do
with {:ok, hub} <- fetch_hub(app_spec.hub_id),
{:ok, app_deployment, derived_key} <-
fetch_download_info(hub.id, app_spec.app_deployment_id),
{:ok, encrypted_binary} <- download(hub, app_deployment),
{:ok, archive_binary} <- decrypt(encrypted_binary, derived_key),
{:ok, notebook_source} <- unzip(archive_binary, files_tmp_path) do
{notebook, %{warnings: warnings}} =
Livebook.LiveMarkdown.notebook_from_livemd(notebook_source)
{:ok, %{notebook: notebook, warnings: warnings}}
end
end
defp fetch_hub(hub_id) do
with :error <- Hubs.fetch_hub(hub_id) do
{:error, "the hub no longer exists"}
end
end
defp fetch_download_info(hub_id, app_deployment_id) do
with :error <- Hubs.TeamClient.get_app_deployment_download_info(hub_id, app_deployment_id) do
{:error, "the app deployment no longer exists"}
end
end
defp download(hub, app_deployment) do
case Livebook.Teams.Requests.download_revision(hub, app_deployment) do
{:ok, body} ->
{:ok, body}
{:error, %{} = error} ->
{:error, "downloading app archive failed, reason: #{inspect(error)}"}
{:error, message} ->
{:error, "downloading app archive failed, reason: #{message}"}
{:transport_error, message} ->
{:error, "downloading app archive failed, reason: #{message}"}
end
end
defp decrypt(binary, derived_key) do
with :error <- Livebook.Teams.decrypt(binary, derived_key) do
{:error, "failed to decrypt app archive"}
end
end
defp unzip(archive_binary, files_tmp_path) do
case :zip.extract(archive_binary, [:memory]) do
{:ok, entries} ->
Enum.reduce_while(entries, {:error, "notebook file missing in the app archive"}, fn
{~c"notebook.livemd", binary}, _acc ->
{:cont, {:ok, binary}}
{~c"files/" ++ name, binary}, acc ->
name = List.to_string(name)
destination = Path.join(files_tmp_path, name)
case File.write(destination, binary) do
:ok ->
{:cont, acc}
{:error, reason} ->
message =
"failed to write a notebook file #{destination}, reason: #{:file.format_error(reason)}"
{:halt, {:error, message}}
end
end)
{:error, {name, reason}} ->
{:error,
"failed to unzip app archive, entry #{name} failed with reason: #{inspect(reason)}"}
{:error, reason} ->
{:error, "failed to unzip app archive, reason: #{inspect(reason)}"}
end
end
def should_warmup?(_app_spec) do
true
end
end