From 3d8b5d65b68c7774c71a1f48e27aa2bd7ba8bf2a Mon Sep 17 00:00:00 2001 From: John Wilger Date: Tue, 8 Oct 2024 16:00:41 -0700 Subject: [PATCH] Update to use assistants API v2 and drop org id Regarding org ID, all clients should be using project-specific API keys now. --- config/runtime.exs | 2 - lib/open_ai_client.ex | 20 ++------ mix.exs | 2 +- test/open_ai_client_test.exs | 90 +----------------------------------- 4 files changed, 5 insertions(+), 109 deletions(-) diff --git a/config/runtime.exs b/config/runtime.exs index 1619ce9..6a9a294 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -8,6 +8,4 @@ config :open_ai_client, :openai_api_key, System.get_env("OPENAI_API_KEY") || raise("OPENAI_API_KEY is not set") -config :open_ai_client, :openai_organization_id, System.get_env("OPENAI_ORGANIZATION_ID") - config :open_ai_client, :receive_timeout, System.get_env("OPENAI_RECEIVE_TIMEOUT") || 600_000 diff --git a/lib/open_ai_client.ex b/lib/open_ai_client.ex index e375989..7efd1e7 100644 --- a/lib/open_ai_client.ex +++ b/lib/open_ai_client.ex @@ -4,7 +4,6 @@ defmodule OpenAiClient do This client supports all options provided by the `Req` library, as well as additional options: - :breaker - a circuit breaker module (default: `ExBreak`) - - :openai_organization - the OpenAI organization ID """ import Req.Request, only: [put_new_header: 3] @@ -65,15 +64,12 @@ defmodule OpenAiClient do end defp build_request(url, options) do - openai_organization = options[:openai_organization] || default_organization() - options = Keyword.delete(options, :openai_organization) - options |> Keyword.put(:url, url) |> validate_options() |> remove_nil_values() |> Req.new() - |> set_headers(openai_organization: openai_organization) + |> set_headers() end defp validate_options(options) do @@ -107,17 +103,7 @@ defmodule OpenAiClient do Application.get_env(:open_ai_client, :openai_api_key) end - defp default_organization do - Application.get_env(:open_ai_client, :openai_organization_id) - end - - defp set_headers(%Req.Request{} = req, options) when is_list(options) do - req - |> put_new_header("openai-beta", "assistants=v1") - |> then( - &if options[:openai_organization], - do: put_new_header(&1, "openai-organization", options[:openai_organization]), - else: &1 - ) + defp set_headers(%Req.Request{} = req) do + put_new_header(req, "openai-beta", "assistants=v2") end end diff --git a/mix.exs b/mix.exs index 3f85779..23dfa93 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule OpenAiClient.MixProject do [ app: :open_ai_client, description: "OpenAI API client for Elixir", - version: "2.1.0", + version: "3.0.0", elixir: "~> 1.15", start_permanent: Mix.env() == :prod, aliases: aliases(), diff --git a/test/open_ai_client_test.exs b/test/open_ai_client_test.exs index 0e0d797..4c9757a 100644 --- a/test/open_ai_client_test.exs +++ b/test/open_ai_client_test.exs @@ -65,7 +65,7 @@ defmodule OpenAiClientTest do bypass: bypass } do Bypass.expect_once(bypass, "POST", "/foo", fn conn -> - assert {"openai-beta", "assistants=v1"} in conn.req_headers + assert {"openai-beta", "assistants=v2"} in conn.req_headers Plug.Conn.resp(conn, 201, "") end) @@ -77,62 +77,6 @@ defmodule OpenAiClientTest do ) end - test "adds the openai_organization_id as a request header when it is a string", %{ - bypass: bypass - } do - organization_id = "test_organization_id" - - Bypass.expect_once(bypass, "POST", "/foo", fn conn -> - assert {"openai-organization", organization_id} in conn.req_headers - - Plug.Conn.resp(conn, 201, "") - end) - - {:ok, _response} = - OpenAiClient.post("/foo", - base_url: endpoint_url(bypass), - openai_organization: organization_id, - breaker: MockBreaker - ) - end - - test "does not include the OpenAI-Organization header when the organization_id is nil", %{ - bypass: bypass - } do - Bypass.expect_once(bypass, "POST", "/foo", fn conn -> - refute Enum.any?(conn.req_headers, fn {key, _value} -> key == "openai-organization" end) - - Plug.Conn.resp(conn, 201, "") - end) - - {:ok, _response} = - OpenAiClient.post("/foo", base_url: endpoint_url(bypass), breaker: MockBreaker) - end - - test "retries the request on a 408, 429, 500, 502, 503, or 504 http status response", %{ - bypass: bypass - } do - retry_statuses = [408, 429, 500, 502, 503, 504] - {:ok, _pid} = Agent.start_link(fn -> 0 end, name: :retry_counter) - - Enum.each(retry_statuses, fn status -> - Bypass.expect(bypass, "POST", "/foo", fn conn -> - Agent.update(:retry_counter, &(&1 + 1)) - Plug.Conn.resp(conn, status, "") - end) - - assert {:ok, %{status: ^status}} = - OpenAiClient.post("/foo", - base_url: endpoint_url(bypass), - retry_delay: 0, - retry_log_level: false, - breaker: MockBreaker - ) - - assert Agent.get_and_update(:retry_counter, fn value -> {value, 0} end) == 4 - end) - end - test "MockBreaker is called with the expected arguments", %{ bypass: bypass } do @@ -188,38 +132,6 @@ defmodule OpenAiClientTest do OpenAiClient.get("/foo", base_url: endpoint_url(bypass), breaker: MockBreaker) end - test "adds the openai_organization_id as a request header when it is a string", %{ - bypass: bypass - } do - organization_id = "test_organization_id" - - Bypass.expect_once(bypass, "GET", "/foo", fn conn -> - assert {"openai-organization", organization_id} in conn.req_headers - - Plug.Conn.resp(conn, 200, "") - end) - - {:ok, _response} = - OpenAiClient.get("/foo", - base_url: endpoint_url(bypass), - openai_organization: organization_id, - breaker: MockBreaker - ) - end - - test "does not include the OpenAI-Organization header when the organization_id is nil", %{ - bypass: bypass - } do - Bypass.expect_once(bypass, "GET", "/foo", fn conn -> - refute Enum.any?(conn.req_headers, fn {key, _value} -> key == "openai-organization" end) - - Plug.Conn.resp(conn, 200, "") - end) - - {:ok, _response} = - OpenAiClient.get("/foo", base_url: endpoint_url(bypass), breaker: MockBreaker) - end - test "retries the request on a 408, 429, 500, 502, 503, or 504 http status response", %{ bypass: bypass } do