diff --git a/OpenAI_API/APIAuthentication.cs b/OpenAI_API/APIAuthentication.cs index 1c1ff36..4346281 100644 --- a/OpenAI_API/APIAuthentication.cs +++ b/OpenAI_API/APIAuthentication.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.Threading.Tasks; namespace OpenAI_API { @@ -156,6 +159,32 @@ public static APIAuthentication LoadFromPath(string directory = null, string fil } + /// + /// Tests the api key against the OpenAI API, to ensure it is valid. This hits the models endpoint so should not be charged for usage. + /// + /// if the api key is valid, or if empty or not accepted by the OpenAI API. + public async Task ValidateAPIKey() + { + if (string.IsNullOrEmpty(ApiKey)) + return false; + + var api = new OpenAIAPI(this); + + List results; + + try + { + results = await api.Models.GetModelsAsync(); + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + return false; + } + + return (results.Count > 0); + } + } internal static class AuthHelpers diff --git a/OpenAI_API/EndpointBase.cs b/OpenAI_API/EndpointBase.cs index b25336c..2734e96 100644 --- a/OpenAI_API/EndpointBase.cs +++ b/OpenAI_API/EndpointBase.cs @@ -135,7 +135,18 @@ private async Task HttpRequestRaw(string url = null, HttpMe resultAsString = "Additionally, the following error was thrown when attemping to read the response content: " + e.ToString(); } - throw new HttpRequestException(GetErrorMessage(resultAsString, response, Endpoint, url)); + if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) + { + throw new AuthenticationException("OpenAI rejected your authorization, most likely due to an invalid API Key. Try checking your API Key and see https://github.com/OkGoDoIt/OpenAI-API-dotnet#authentication for guidance. Full API response follows: " + resultAsString); + } + else if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) + { + throw new HttpRequestException("OpenAI had an internal server error, which can happen occasionally. Please retry your request. " + GetErrorMessage(resultAsString, response, Endpoint, url)); + } + else + { + throw new HttpRequestException(GetErrorMessage(resultAsString, response, Endpoint, url)); + } } } diff --git a/OpenAI_Tests/AuthTests.cs b/OpenAI_Tests/AuthTests.cs index 5d4b43f..e791c81 100644 --- a/OpenAI_Tests/AuthTests.cs +++ b/OpenAI_Tests/AuthTests.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using System; using System.IO; +using System.Threading.Tasks; namespace OpenAI_Tests { @@ -105,5 +106,22 @@ public void ParseKey() Assert.AreEqual("orgTest", auth.OpenAIOrganization); } + [Test] + public async Task TestBadKey() + { + var auth = new OpenAI_API.APIAuthentication("pk-testAA"); + Assert.IsFalse(await auth.ValidateAPIKey()); + + auth = new OpenAI_API.APIAuthentication(null); + Assert.IsFalse(await auth.ValidateAPIKey()); + } + + [Test] + public async Task TestValidateGoodKey() + { + var auth = new OpenAI_API.APIAuthentication(Environment.GetEnvironmentVariable("TEST_OPENAI_SECRET_KEY")); + Assert.IsTrue(await auth.ValidateAPIKey()); + } + } } \ No newline at end of file diff --git a/OpenAI_Tests/CompletionEndpointTests.cs b/OpenAI_Tests/CompletionEndpointTests.cs index b65b292..936cecb 100644 --- a/OpenAI_Tests/CompletionEndpointTests.cs +++ b/OpenAI_Tests/CompletionEndpointTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using OpenAI_API; using System; using System.Linq; using System.Threading.Tasks; diff --git a/OpenAI_Tests/EmbeddingEndpointTests.cs b/OpenAI_Tests/EmbeddingEndpointTests.cs index 570a504..ee58a57 100644 --- a/OpenAI_Tests/EmbeddingEndpointTests.cs +++ b/OpenAI_Tests/EmbeddingEndpointTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using OpenAI_API; using OpenAI_API.Embedding; using OpenAI_API.Models; using System; diff --git a/OpenAI_Tests/ModelEndpointTests.cs b/OpenAI_Tests/ModelEndpointTests.cs index f197631..3ccfef6 100644 --- a/OpenAI_Tests/ModelEndpointTests.cs +++ b/OpenAI_Tests/ModelEndpointTests.cs @@ -4,7 +4,7 @@ using OpenAI_API.Models; using System; using System.Linq; -using System.Net.Http; +using System.Security.Authentication; using System.Threading.Tasks; namespace OpenAI_Tests @@ -66,7 +66,7 @@ public void GetEnginesAsync_ShouldFailIfInvalidAuthIsProvided() var api = new OpenAIAPI(new APIAuthentication(Guid.NewGuid().ToString())); Func act = () => api.Models.GetModelsAsync(); act.Should() - .ThrowAsync() + .ThrowAsync() .Where(exc => exc.Message.Contains("Incorrect API key provided")); }