(RuntimeError) environment variable WOLFRAM_APP_ID is missing

I’m reading the ebook Programming Phoenix 1.4 and in the page 268 when I try to execute the iex it complains for this:

** (RuntimeError) environment variable WOLFRAM_APP_ID is missing.

    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    (stdlib) erl_eval.erl:449: :erl_eval.expr/5
    (stdlib) erl_eval.erl:126: :erl_eval.exprs/5
    (elixir) lib/code.ex:240: Code.eval_string/3
    (mix) lib/mix/config.ex:158: anonymous fn/2 in Mix.Config.__import__!/2
    (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
    (mix) lib/mix/config.ex:157: Mix.Config.__import__!/2

So I add the API key in both config/dev.exs and config/prod.secret.exs files:

wolfram_app_id = 
  System.get_env("XXXXXX-XXXXXXXXXX") || 
  raise """
  environment variable WOLFRAM_APP_ID is missing.
  """
config :info_sys, :wolfram, app_id: wolfram_app_id

I created the key XXXXXX-XXXXXXXXXX in the http://developer.wolframalpha.com/portal/myapps/index.html
with the Application name: rumbl
and then generated the AppID: XXXXXX-XXXXXXXXXX
What I’m doing incorrect?
the value of the WOLFRAM_APP_ID I put just on the config/prod.secret.exs file?
like WOLFRAM_APP_ID= "XXXXXX-XXXXXXXXXX"
and then keep on the config/dev.exs file the code: System.get_env("WOLFRAM_APP_ID") || ?

You need to set an environment variable that’s visible to your BEAM process. How to do that depends on your operating system.

If you use linux/mac with a sh compatible shell, then it’s export, for fish and windows it’s set.

I have a Mac OS Mojave

Yeah just see my edited post.

It’s export then (under the assumption that you use bash or zsh, which both are the default shells in Mac, depending on the version, but as I’m not a Mac user by myself I have no clue when the change happened)

Hi,

echo $SHELL

Mojave: /bin/bash --> .bash_profile
Catalina: /bin/zsh --> .zprofile

https://elixirforum.com/t/programming-phoenix-could-not-fetch-application-environment-wolfram/26584

I’d not hardcode it into any of those…

2 Likes

I use zsh.
So I put in the ~/.zshrc file?

I readed before this post, but it’s not my case.

defmodule InfoSys.Wolfram do
  import SweetXml
  alias InfoSys.Result

  @behaviour InfoSys.Backend

  @base "http://api.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!(:info_sys, :wolfram)[:app_id]
end

1 Like

As I said, I’d not hardcode it there for several reasons, but use a .env or .envrc for the project (not comitted into source control) and source it before working with the project.

direnv is a nice tool for such setups. It will automatically “execute” .envrc files when entering a directory, if that directory is “trusted”.

5 Likes

Just for help if someone stopped like me in this part of the book, I’ll share what I do for run correctly.
I create inside the config folder a .env file and then add:
export WOLFRAM_APP_ID="XXXXXX-XXXXXXXXXX"
then after I run on terminal:
source config/.env
And then I try iex -S mix:

iex(1)> InfoSys.compute("what is elixir?")
[
  %Task{
    owner: #PID<0.366.0>,
    pid: #PID<0.368.0>,
    ref: #Reference<0.625303463.500432897.47893>
  }
]

and work’s.

Then I add in the .gitignore file:

# Ignore .env files 
/.env

for not share by git the WOLFRAM_APP_ID.
Is that correct what I’m doing?
Thank’s for Help @Nobbz and @fun2src.

2 Likes

This will only ignore .env from the repositories root. If you want to exclude config/.env, then you have to do /config/.env, assuming that git-root and project root are the same.

Other than that, the flow seems to be correct, though I prefer to have .env(rc) files in the project root for discoverability.

2 Likes

Yes, you are correct. Thank’s again @NobbZ!

Thanks romenigld, I have the same issue and solved.

1 Like

I’m also new to elixir/phoenix and struggled with this. I couldn’t get source to work since I use a windows shell, specifically cmder.

Here is how I finally got it to work. I know this is probably not the way to go in production, but would be helpful to someone who just wants to complete the project on a personal laptop.

  1. create .env file in rumbl_umbrella (the project root)
  2. add this line to the .env file:
    export WOLFRAM_APP_ID=“XXX-XXXX”
  3. add /.env to gitignore file
  4. add environment variable to Windows:
    Variable name: WOLFRAM_APP_ID
    Variable value: path to .env file
  5. restart cmder

I forgot to mention that I first made this entry into config.exs and prod.secret.exs

wolfram_app_id =
System.get_env(“WOLFRAM_APP_ID”) ||
raise “”"
environment variable WOLFRAM_APP_ID is missing.
“”"

config :info_sys, :wolfram, app_id: “XXX-XXXX”