Programming Phoenix retriving texst from processes (Wolfram)

Hi, I am new to Phoenix and I am following Programming Phoenix book. I am trying to retrieve text from a process which is an answer of Wolfram to my question. However, I am not able to do so. It seems my process is not alive.

CONSOLE:

iex(20)> Rumbl.InfoSys.compute("what is firebird?")      
[
  %Task{
    owner: #PID<0.399.0>,
    pid: #PID<0.477.0>,
    ref: #Reference<0.4114193905.3572760578.72489>
  }
]
iex(21)> flush()
{#Reference<0.4114193905.3572760578.72368>, []}
{:DOWN, #Reference<0.4114193905.3572760578.72368>, :process, #PID<0.438.0>,
 :normal}
{#Reference<0.4114193905.3572760578.72391>, []}
{:DOWN, #Reference<0.4114193905.3572760578.72391>, :process, #PID<0.451.0>,
 :normal}
{#Reference<0.4114193905.3572760578.72489>, []}
{:DOWN, #Reference<0.4114193905.3572760578.72489>, :process, #PID<0.477.0>,
 :normal}
:ok

wolfram.ex

defmodule Rumbl.Wolfram do
  import SweetXml
  alias Rumbl.InfoSys.Result

  @behaviour Rumbl.Backend

  @base "http://wolframalpha.com/v2/query"

  @impl true
  def name, do: "wolfram"

  @impl true
  def compute(query_str, _opts) do
    query_str
    |> fetch_xml()
    |> xpath(~x"/queryresult/pod[contains(@title, 'Result') or
                                contains(@title, 'Definitions')]
                            /subpod/plaintext/text()")
    |> build_results()
  end

  defp build_results(nil), do: []

  defp build_results(answer) do
    [%Result{backend: __MODULE__, score: 95, text: to_string(answer)}]
  end

  defp fetch_xml(query) do
    {:ok, {_, _, body}} = :httpc.request(String.to_charlist(url(query)))

    body
  end

  defp url(input) do
    "#{@base}?" <>
    URI.encode_query(appid: id(), input: input, format: "plaintext")
  end

  defp id, do: Application.fetch_env!(:rumbl, :wolfram)[:app_id]
end

backend.ex

defmodule Rumbl.Backend do
  @callback name() :: String.t()
  @callback compute(query :: String.t(), opts :: Keyword.t()) ::
  [%Rumbl.InfoSys.Result{}]
  end

info_sys.ex

defmodule Rumbl.InfoSys do

  @backends [Rumbl.Wolfram]

  defmodule Result do
    defstruct score: 0, text: nil, backend: nil
  end

  def compute(query, opts \\ []) do
    opts = Keyword.put_new(opts, :limit, 10)
    backends = opts[:backends] || @backends

    backends
    |> Enum.map(&async_query(&1, query, opts))
  end

  defp async_query(backend, query, opts) do
    Task.Supervisor.async_nolink(Rumbl.TaskSupervisor,
      backend, :compute, [query, opts], shutdown: :brutal_kill
      )
  end
end

What am I doing wrong?

1 Like

These are the messages I’d expect to see if the Task ran successfully and gave a result of []. Does the Wolfram query return results if you call compute directly?

I am not sure if I understand the question (sorry for my lack of knowledge). However, if you ask if I get an answer after typing a query ("what is firebird? ")by hand in ‘wolframalpha.com’ then yes, I do get a result - “1 | noun | the male is bright red with black wings and tail”.

To be more specific, what does running Rumbl.Wolfram.compute("what is firebird?") return?

Thank you for helping!
Well, I did run this command - Rumbl.Wolfram.compute(“what is firebird?”). In response I got:

(UndefinedFunctionError) function Rumbl.Wolfram.compute/1 is undefined or private. Did you mean one of:

      * compute/2

I thought that I did defined it and it’s not private. What does it mean?

In Elixir, a function is defined by its name and its arity (number of arguments). The message is saying that you called compute with 1 argument and no such function exists. But there is a function called compute with 2 arguments. Suggesting that maybe thats the function you intended.

Indeed your function head is def compute(query_str, _opts) so perhaps you meant def compute(query_str, _opts \\ [])?

I understand, it did help! It did return an empty list! Thank you!

However, I am still having trouble with getting an answer for my query. When I type Rumbl.InfoSys,compute("what is firebird?") and then flush() I only get: {#Reference<0.3628089549.2167668739.78064>, []} {:DOWN, #Reference<0.3628089549.2167668739.78064>, :process, #PID<0.427.0>, :normal} :ok