defmodule Replicate.Deployments do
@moduledoc """
Documentation for `Predictions`.
"""
@behaviour Replicate.Deployments.Behaviour
@replicate_client Application.compile_env(:replicate, :replicate_client, Replicate.Client)
alias Replicate.Deployments.Deployment
alias Replicate.Predictions.Prediction
@doc """
Gets a deployment by name, in the format `owner/model-name`.
## Examples
```
iex> {:ok, deployment} = Replicate.Deployments.get("test/model")
iex> deployment.username
"test"
iex> Replicate.Predictions.get("not_a_real_id")
{:error, "Not found"}
```
"""
def get(name) do
[owner, model_name] = String.split(name, "/")
{:ok, %Deployment{username: owner, name: model_name}}
end
@doc """
Create a new prediction with the deployment. The input parameter should be a map of the model inputs.
## Examples
```
iex> {:ok, deployment} = Replicate.Deployments.get("test/model")
iex> {:ok, prediction} = Replicate.Deployments.create_prediction(deployment, %{prompt: "a 19th century portrait of a wombat gentleman"})
iex> prediction.status
"starting"
```
"""
def create_prediction(
%Deployment{username: username, name: name},
input,
webhook \\ nil,
webhook_completed \\ nil,
webhook_event_filter \\ nil,
stream \\ nil
) do
webhook_parameters =
%{
"webhook" => webhook,
"webhook_completed" => webhook_completed,
"webhook_event_filter" => webhook_event_filter,
"stream" => stream
}
|> Enum.filter(fn {_key, value} -> !is_nil(value) end)
|> Enum.into(%{})
body =
%{
"input" => input |> Enum.into(%{})
}
|> Map.merge(webhook_parameters)
|> Jason.encode!()
@replicate_client.request(:post, "/v1/deployments/#{username}/#{name}/predictions", body)
|> parse_response()
end
defp parse_response({:ok, json_body}) do
body =
json_body
|> Jason.decode!()
|> string_to_atom()
{:ok, struct(Prediction, body)}
end
defp parse_response({:error, message}), do: {:error, message}
defp string_to_atom(body) do
for {k, v} <- body, into: %{}, do: {String.to_atom(k), v}
end
end