Harden OpenAI api layer
- Support rate limiting - Add proper error handling (don't rely on exceptions) Closes #147
This commit is contained in:
+3
-1
@@ -72,7 +72,9 @@ config :music_library, BraveSearch,
|
||||
user_agent: user_agent,
|
||||
api_cooldown: 1000
|
||||
|
||||
config :music_library, OpenAI, api_key: "change me"
|
||||
config :music_library, OpenAI,
|
||||
api_key: "change me",
|
||||
api_cooldown: 250
|
||||
|
||||
# Configure esbuild (the version is required)
|
||||
config :esbuild,
|
||||
|
||||
+2
-1
@@ -96,7 +96,8 @@ config :music_library, OpenAI,
|
||||
req_options: [
|
||||
plug: {Req.Test, OpenAI.API},
|
||||
max_retries: 0
|
||||
]
|
||||
],
|
||||
api_cooldown: 0
|
||||
|
||||
config :phoenix_test, :endpoint, MusicLibraryWeb.Endpoint
|
||||
|
||||
|
||||
+11
-8
@@ -3,8 +3,7 @@ defmodule OpenAI.API do
|
||||
|
||||
@spec gpt(OpenAI.Completion.t(), OpenAI.Config.t()) :: {:ok, map()} | {:error, term()}
|
||||
def gpt(completion, config) do
|
||||
resp =
|
||||
config
|
||||
case config
|
||||
|> new_request()
|
||||
|> Req.merge(
|
||||
url: "/v1/chat/completions",
|
||||
@@ -17,13 +16,16 @@ defmodule OpenAI.API do
|
||||
temperature: completion.temperature
|
||||
}
|
||||
)
|
||||
|> Req.post!()
|
||||
|> Req.post() do
|
||||
{:ok, %{status: status, body: body}} when status in 200..299 ->
|
||||
content = get_in(body, ["choices", Access.at(0), "message", "content"])
|
||||
JSON.decode(content)
|
||||
|
||||
if resp.status in 200..299 do
|
||||
content = get_in(resp.body, ["choices", Access.at(0), "message", "content"])
|
||||
{:ok, JSON.decode!(content)}
|
||||
else
|
||||
{:error, resp.body}
|
||||
{:ok, %{body: body}} ->
|
||||
{:error, "OpenAI API error: #{inspect(body)}"}
|
||||
|
||||
{:error, exception} ->
|
||||
{:error, "Connection error: #{Exception.message(exception)}"}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -92,6 +94,7 @@ defmodule OpenAI.API do
|
||||
auth: {:bearer, config.api_key}
|
||||
)
|
||||
|> Req.Request.merge_options(config.req_options)
|
||||
|> Req.RateLimiter.attach(name: :open_ai, cooldown: config.api_cooldown)
|
||||
|> Req.Request.append_request_steps(log_attempt: &log_attempt/1)
|
||||
|> Req.Request.append_response_steps(log_error: &log_error/1)
|
||||
end
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
defmodule OpenAI.Config do
|
||||
@type t :: %__MODULE__{
|
||||
api_key: String.t(),
|
||||
req_options: Keyword.t()
|
||||
req_options: Keyword.t(),
|
||||
api_cooldown: non_neg_integer()
|
||||
}
|
||||
|
||||
@enforce_keys [:api_key]
|
||||
defstruct api_key: "",
|
||||
req_options: []
|
||||
req_options: [],
|
||||
api_cooldown: 500
|
||||
|
||||
@schema NimbleOptions.new!(
|
||||
api_key: [
|
||||
@@ -17,6 +19,11 @@ defmodule OpenAI.Config do
|
||||
type: :keyword_list,
|
||||
required: false,
|
||||
default: []
|
||||
],
|
||||
api_cooldown: [
|
||||
type: :integer,
|
||||
required: false,
|
||||
default: 500
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user