init commit

This commit is contained in:
2022-08-30 02:41:31 -04:00
commit 559f6f959f
85 changed files with 3583 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
defmodule Diffuser.Generator.PromptRequest do
use Ecto.Schema
use Waffle.Ecto.Schema
import Ecto.Changeset
alias Diffuser.Generator.PromptRequestResult
@primary_key {:id, Ecto.UUID, autogenerate: true}
schema "prompt_requests" do
field :prompt, :string
field :status, :string, default: "queued"
has_many :images, PromptRequestResult, on_delete: :delete_all
timestamps()
end
@doc false
def changeset(prompt_request, attrs) do
prompt_request
|> cast(attrs, [:prompt, :status])
|> validate_required([:prompt])
end
end

View File

@@ -0,0 +1,98 @@
defmodule Diffuser.Generator.PromptRequestGenserver do
use GenServer
alias Diffuser.Generator
alias Diffuser.Generator.PromptRequest
alias DiffuserWeb.Endpoint
alias Diffuser.PythonHelper, as: Helper
@path 'lib/diffuser/python'
def new(%{prompt_request: %PromptRequest{} = prompt_request}) do
GenServer.start_link(
__MODULE__,
%{prompt_request: prompt_request},
name: name_for(prompt_request)
)
end
def name_for(%PromptRequest{id: prompt_request_id}),
do: {:global, "prompt_request:#{prompt_request_id}"}
def init(%{prompt_request: %PromptRequest{} = prompt_request}) do
send(self(), :start_prompt)
{:ok,
%{
prompt_request: prompt_request
}}
end
def handle_info(:start_prompt, %{prompt_request: prompt_request} = state) do
with {:ok, %{prompt: prompt} = active_prompt} <-
update_and_broadcast_progress(prompt_request, "in_progress"),
:ok <- call_python(:test_script, :test_func, prompt),
%PromptRequest{} = prompt_request_with_results <- write_and_save_images(active_prompt),
{:ok, completed_prompt} <-
update_and_broadcast_progress(prompt_request_with_results, "finished") do
IO.inspect(completed_prompt)
{:noreply, state}
else
nil ->
raise("prompt not found")
{:error, message} ->
raise(message)
end
end
defp update_and_broadcast_progress(%PromptRequest{id: id} = prompt_request, new_status) do
{:ok, new_prompt} = Generator.update_prompt_request(prompt_request, %{status: new_status})
:ok = Endpoint.broadcast("request:#{id}", "request", %{prompt_request: new_prompt})
{:ok, new_prompt}
end
defp call_python(_module, _func, prompt) do
Port.open(
{:spawn, "python #{@path}/stable_diffusion.py --prompt #{prompt}"},
[:binary, {:packet, 4}]
)
# TODO: We will want to flush, and get the image data from the script
# then write it to PromptResult
# pid = Helper.py_instance(Path.absname(@path))
# :python.call(pid, module, func, args)
# pid
# |> :python.stop()
:ok
end
defp write_and_save_images(%PromptRequest{id: id, prompt: prompt}) do
height = :rand.uniform(512)
width = :rand.uniform(512)
IO.inspect(height)
{:ok, resp} =
:httpc.request(
:get,
{'http://placekitten.com/#{height}/#{width}', []},
[],
body_format: :binary
)
{{_, 200, 'OK'}, _headers, body} = resp
Generator.create_prompt_request_results(id, [
%{
file_name: "#{prompt}.jpg",
filename: "#{prompt}.jpg",
binary: body
}
])
Generator.get_prompt_request!(id)
end
end

View File

@@ -0,0 +1,22 @@
defmodule Diffuser.Generator.PromptRequestResult do
use Ecto.Schema
use Waffle.Ecto.Schema
import Ecto.Changeset
alias Diffuser.Generator.PromptRequest
@primary_key {:id, Ecto.UUID, autogenerate: true}
schema "prompt_request_results" do
field :image, Diffuser.Uploaders.Image.Type
belongs_to :prompt_request, PromptRequest, type: :binary_id
timestamps()
end
@doc false
def changeset(prompt_request, attrs) do
prompt_request
|> cast(attrs, [:prompt_request_id])
|> cast_attachments(attrs, [:image])
|> validate_required([:prompt_request_id, :image])
end
end

View File

@@ -0,0 +1,27 @@
defmodule Diffuser.Generator.PromptRequestSupervisor do
use DynamicSupervisor
alias Diffuser.Generator.PromptRequest
def start_link(init_arg) do
DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
@impl true
def init(_init_arg) do
DynamicSupervisor.init(strategy: :one_for_one)
end
def start_prompt_request(%PromptRequest{} = prompt_request) do
Task.Supervisor.start_child(
__MODULE__,
Diffuser.Generator.PromptRequestGenserver,
:new,
[
%{
prompt_request: prompt_request
}
],
restart: :transient
)
end
end