Skip to content

Commit 0876a15

Browse files
committed
Add API Key Validation and better API error handling
1 parent f85c4ae commit 0876a15

File tree

6 files changed

+61
-5
lines changed

6 files changed

+61
-5
lines changed

OpenAI_API/APIAuthentication.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
24
using System.IO;
5+
using System.Threading.Tasks;
36

47
namespace OpenAI_API
58
{
@@ -156,6 +159,32 @@ public static APIAuthentication LoadFromPath(string directory = null, string fil
156159
}
157160

158161

162+
/// <summary>
163+
/// 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.
164+
/// </summary>
165+
/// <returns><see langword="true"/> if the api key is valid, or <see langword="false"/> if empty or not accepted by the OpenAI API.</returns>
166+
public async Task<bool> ValidateAPIKey()
167+
{
168+
if (string.IsNullOrEmpty(ApiKey))
169+
return false;
170+
171+
var api = new OpenAIAPI(this);
172+
173+
List<Models.Model> results;
174+
175+
try
176+
{
177+
results = await api.Models.GetModelsAsync();
178+
}
179+
catch (Exception ex)
180+
{
181+
Debug.WriteLine(ex.ToString());
182+
return false;
183+
}
184+
185+
return (results.Count > 0);
186+
}
187+
159188
}
160189

161190
internal static class AuthHelpers

OpenAI_API/EndpointBase.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,18 @@ private async Task<HttpResponseMessage> HttpRequestRaw(string url = null, HttpMe
135135
resultAsString = "Additionally, the following error was thrown when attemping to read the response content: " + e.ToString();
136136
}
137137

138-
throw new HttpRequestException(GetErrorMessage(resultAsString, response, Endpoint, url));
138+
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
139+
{
140+
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);
141+
}
142+
else if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
143+
{
144+
throw new HttpRequestException("OpenAI had an internal server error, which can happen occasionally. Please retry your request. " + GetErrorMessage(resultAsString, response, Endpoint, url));
145+
}
146+
else
147+
{
148+
throw new HttpRequestException(GetErrorMessage(resultAsString, response, Endpoint, url));
149+
}
139150
}
140151
}
141152

OpenAI_Tests/AuthTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using NUnit.Framework;
22
using System;
33
using System.IO;
4+
using System.Threading.Tasks;
45

56
namespace OpenAI_Tests
67
{
@@ -105,5 +106,22 @@ public void ParseKey()
105106
Assert.AreEqual("orgTest", auth.OpenAIOrganization);
106107
}
107108

109+
[Test]
110+
public async Task TestBadKey()
111+
{
112+
var auth = new OpenAI_API.APIAuthentication("pk-testAA");
113+
Assert.IsFalse(await auth.ValidateAPIKey());
114+
115+
auth = new OpenAI_API.APIAuthentication(null);
116+
Assert.IsFalse(await auth.ValidateAPIKey());
117+
}
118+
119+
[Test]
120+
public async Task TestValidateGoodKey()
121+
{
122+
var auth = new OpenAI_API.APIAuthentication(Environment.GetEnvironmentVariable("TEST_OPENAI_SECRET_KEY"));
123+
Assert.IsTrue(await auth.ValidateAPIKey());
124+
}
125+
108126
}
109127
}

OpenAI_Tests/CompletionEndpointTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using NUnit.Framework;
2-
using OpenAI_API;
32
using System;
43
using System.Linq;
54
using System.Threading.Tasks;

OpenAI_Tests/EmbeddingEndpointTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using NUnit.Framework;
2-
using OpenAI_API;
32
using OpenAI_API.Embedding;
43
using OpenAI_API.Models;
54
using System;

OpenAI_Tests/ModelEndpointTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using OpenAI_API.Models;
55
using System;
66
using System.Linq;
7-
using System.Net.Http;
7+
using System.Security.Authentication;
88
using System.Threading.Tasks;
99

1010
namespace OpenAI_Tests
@@ -66,7 +66,7 @@ public void GetEnginesAsync_ShouldFailIfInvalidAuthIsProvided()
6666
var api = new OpenAIAPI(new APIAuthentication(Guid.NewGuid().ToString()));
6767
Func<Task> act = () => api.Models.GetModelsAsync();
6868
act.Should()
69-
.ThrowAsync<HttpRequestException>()
69+
.ThrowAsync<AuthenticationException>()
7070
.Where(exc => exc.Message.Contains("Incorrect API key provided"));
7171
}
7272

0 commit comments

Comments
 (0)