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