-
Notifications
You must be signed in to change notification settings - Fork 29
/
config.ex
90 lines (69 loc) · 2.15 KB
/
config.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
defmodule ExOpenAI.Config do
@moduledoc """
Reads configuration on application start, parses all environment variables (if any)
and caches the final config in memory to avoid parsing on each read afterwards.
"""
use GenServer
@openai_url "https://api.openai.com/v1"
@config_keys [
:api_key,
:organization_key,
:http_options,
:http_headers,
:http_client,
:base_url
]
def start_link(opts), do: GenServer.start_link(__MODULE__, opts, name: __MODULE__)
@impl true
def init(_opts) do
config =
@config_keys
|> Enum.map(fn key -> {key, get_config_value(key)} end)
|> Map.new()
{:ok, config}
end
# API Key
def api_key, do: get_config_value(:api_key)
def org_key, do: get_config_value(:organization_key)
def api_url(override \\ nil) do
override || get_config_value(:base_url, @openai_url)
end
# HTTP Options
def http_options, do: get_config_value(:http_options, [])
def http_headers, do: get_config_value(:http_headers, [])
# HTTP client can be customized to facilitate testing
def http_client, do: get_config_value(:http_client, ExOpenAI.Client)
defp get_config_value(key, default \\ nil) do
value =
:ex_openai
|> Application.get_env(key)
|> parse_config_value()
if is_nil(value), do: default, else: value
end
defp parse_config_value({:system, env_name}), do: fetch_env!(env_name)
defp parse_config_value({:system, :integer, env_name}) do
env_name
|> fetch_env!()
|> String.to_integer()
end
defp parse_config_value(value), do: value
# System.fetch_env!/1 support for older versions of Elixir
defp fetch_env!(env_name) do
case System.get_env(env_name) do
nil ->
raise ArgumentError,
message: "could not fetch environment variable \"#{env_name}\" because it is not set"
value ->
value
end
end
def get(key), do: GenServer.call(__MODULE__, {:get, key})
@impl true
def handle_call({:get, key}, _from, state) do
{:reply, Map.get(state, key), state}
end
@impl true
def handle_call({:put, key, value}, _from, state) do
{:reply, value, Map.put(state, key, value)}
end
end