Packages
livebook
0.13.2
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