Skip to content

Commit 162e6b1

Browse files
authored
Add deployments (#18)
* deployment behavior * fix deployments * version not necessary * fix behavior for deployments * remove unused import * update tests * add readme explanation * update version to 1.1.1
1 parent 1cea0e9 commit 162e6b1

File tree

7 files changed

+138
-4
lines changed

7 files changed

+138
-4
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Install by adding `replicate` to your list of dependencies in `mix.exs`:
1010
```elixir
1111
def deps do
1212
[
13-
{:replicate, "~> 1.1.0"}
13+
{:replicate, "~> 1.1.1"}
1414
]
1515
end
1616
```
@@ -219,4 +219,15 @@ iex> {{_, 200, 'OK'}, _headers, body} = resp
219219
iex> File.write!("babadook_watercolor.jpg", body)
220220
```
221221

222+
## Create prediction from deployment
223+
224+
Deployments allow you to control the configuration of a model with a private, fixed API endpoint. You can control the version of the model, the hardware it runs on, and how it scales.
225+
226+
Once you create a deployment on Replicate, you can make predictions like this:
227+
228+
```elixir
229+
iex> {:ok, deployment} = Replicate.Deployments.get("test/model")
230+
iex> {:ok, prediction} = Replicate.Deployments.create_prediction(deployment, %{prompt: "a 19th century portrait of a wombat gentleman"})
231+
```
232+
222233
# replicate-elixir

lib/deployments.ex

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
defmodule Replicate.Deployments do
2+
@moduledoc """
3+
Documentation for `Predictions`.
4+
"""
5+
@behaviour Replicate.Deployments.Behaviour
6+
@replicate_client Application.compile_env(:replicate, :replicate_client, Replicate.Client)
7+
8+
alias Replicate.Deployments.Deployment
9+
alias Replicate.Predictions.Prediction
10+
11+
@doc """
12+
Gets a deployment by name, in the format `owner/model-name`.
13+
14+
## Examples
15+
16+
```
17+
iex> {:ok, deployment} = Replicate.Deployments.get("test/model")
18+
iex> deployment.username
19+
"test"
20+
21+
iex> Replicate.Predictions.get("not_a_real_id")
22+
{:error, "Not found"}
23+
```
24+
"""
25+
def get(name) do
26+
[owner, model_name] = String.split(name, "/")
27+
{:ok, %Deployment{username: owner, name: model_name}}
28+
end
29+
30+
@doc """
31+
Create a new prediction with the deployment. The input parameter should be a map of the model inputs.
32+
33+
## Examples
34+
35+
```
36+
iex> {:ok, deployment} = Replicate.Deployments.get("test/model")
37+
iex> {:ok, prediction} = Replicate.Deployments.create_prediction(deployment, %{prompt: "a 19th century portrait of a wombat gentleman"})
38+
iex> prediction.status
39+
"starting"
40+
```
41+
"""
42+
def create_prediction(
43+
%Deployment{username: username, name: name},
44+
input,
45+
webhook \\ nil,
46+
webhook_completed \\ nil,
47+
webhook_event_filter \\ nil,
48+
stream \\ nil
49+
) do
50+
webhook_parameters =
51+
%{
52+
"webhook" => webhook,
53+
"webhook_completed" => webhook_completed,
54+
"webhook_event_filter" => webhook_event_filter,
55+
"stream" => stream
56+
}
57+
|> Enum.filter(fn {_key, value} -> !is_nil(value) end)
58+
|> Enum.into(%{})
59+
60+
body =
61+
%{
62+
"input" => input |> Enum.into(%{})
63+
}
64+
|> Map.merge(webhook_parameters)
65+
|> Jason.encode!()
66+
67+
@replicate_client.request(:post, "/v1/deployments/#{username}/#{name}/predictions", body)
68+
|> parse_response()
69+
end
70+
71+
defp parse_response({:ok, json_body}) do
72+
body =
73+
json_body
74+
|> Jason.decode!()
75+
|> string_to_atom()
76+
77+
{:ok, struct(Prediction, body)}
78+
end
79+
80+
defp parse_response({:error, message}), do: {:error, message}
81+
82+
defp string_to_atom(body) do
83+
for {k, v} <- body, into: %{}, do: {String.to_atom(k), v}
84+
end
85+
end

lib/deployments/behaviour.ex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
defmodule Replicate.Deployments.Behaviour do
2+
@moduledoc """
3+
Documentation for the Deployment Behaviour.
4+
"""
5+
alias Replicate.Deployments.Deployment
6+
7+
@callback get(String.t()) :: {:ok, Deployment.t()} | {:error, String.t()}
8+
@callback create_prediction(
9+
Deployment.t(),
10+
input :: %{string: any},
11+
webhook :: list(String.t()),
12+
webhook_completed :: list(String.t()),
13+
webook_event_filter :: list(String.t()),
14+
stream :: boolean()
15+
) ::
16+
{:ok, Replicate.Predictions.Prediction.t()} | {:error, String.t()}
17+
end

lib/deployments/deployment.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
defmodule Replicate.Deployments.Deployment do
2+
@moduledoc """
3+
`Deployment` struct.
4+
"""
5+
defstruct [
6+
:username,
7+
:name
8+
]
9+
end

lib/mock_client.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ defmodule Replicate.MockClient do
1414
],
1515
urls: %{
1616
"get" => "https://api.replicate.com/v1/predictions/1234",
17-
"cancel" => "https://api.replicate.com/v1/predictions/1234/cancel",
17+
"cancel" => "https://api.replicate.com/v1/predictions/1234/cancel"
1818
}
1919
}
2020
@stub_prediction2 %{
@@ -27,7 +27,7 @@ defmodule Replicate.MockClient do
2727
],
2828
urls: %{
2929
"get" => "https://api.replicate.com/v1/predictions/1235",
30-
"cancel" => "https://api.replicate.com/v1/predictions/1235/cancel",
30+
"cancel" => "https://api.replicate.com/v1/predictions/1235/cancel"
3131
}
3232
}
3333

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Replicate.MixProject do
44
def project do
55
[
66
app: :replicate,
7-
version: "1.1.0",
7+
version: "1.1.1",
88
elixir: "~> 1.14",
99
start_permanent: Mix.env() == :prod,
1010
start_permanent: Mix.env() == :prod,

test/replicate_test.exs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule ReplicateTest do
66
doctest Replicate
77
doctest Replicate.Predictions
88
doctest Replicate.Models
9+
doctest Replicate.Deployments
910

1011
# Make sure mocks are verified when the test exits
1112
setup :verify_on_exit!
@@ -79,4 +80,15 @@ defmodule ReplicateTest do
7980
assert first_version.id == "v1"
8081
assert first_version.cog_version == "0.3.0"
8182
end
83+
84+
test "create a deployment prediction" do
85+
{:ok, deployment} = Replicate.Deployments.get("test/model")
86+
87+
{:ok, prediction} =
88+
Replicate.Deployments.create_prediction(deployment, %{
89+
prompt: "a 19th century portrait of a wombat gentleman"
90+
})
91+
92+
assert prediction.status == "starting"
93+
end
8294
end

0 commit comments

Comments
 (0)