diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c2969f..80d6d4e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: - name: Run Tests env: CB_PROJECT_ID: ${{ secrets.CB_PROJECT_ID }} + CB_API_KEY: ${{ secrets.CB_API_KEY }} run: dotnet test release: diff --git a/Commonbase.Examples/ChatCompletion.cs b/Commonbase.Examples/ChatCompletion.cs index e69dc43..bf5fc35 100644 --- a/Commonbase.Examples/ChatCompletion.cs +++ b/Commonbase.Examples/ChatCompletion.cs @@ -4,7 +4,7 @@ public static class ChatCompletionExample { public static async Task RunAsync() { - CommonbaseClient client = new(); + CommonbaseClient client = new(apiKey: Program.CB_API_KEY!); string systemMessage = "You help people with geography."; ChatMessage[] messages = new[] { diff --git a/Commonbase.Examples/Program.cs b/Commonbase.Examples/Program.cs index 08c20c4..70fb70f 100644 --- a/Commonbase.Examples/Program.cs +++ b/Commonbase.Examples/Program.cs @@ -5,12 +5,15 @@ public class Program // Set a CB_PROJECT_ID environment variable to run these examples without writing any code. // You can also hard-code your project ID here if you prefer. public static string? CB_PROJECT_ID = Environment.GetEnvironmentVariable("CB_PROJECT_ID"); + public static string? CB_API_KEY = Environment.GetEnvironmentVariable("CB_API_KEY"); public static async Task Main() { - if (string.IsNullOrWhiteSpace(CB_PROJECT_ID)) + if (string.IsNullOrWhiteSpace(CB_PROJECT_ID) || string.IsNullOrWhiteSpace(CB_API_KEY)) { - Console.Error.WriteLine("Please set the CB_PROJECT_ID environment variable to your Commonbase Project ID."); + Console.Error.WriteLine( + "Please set the CB_PROJECT_ID and CB_API_KEY environment variables to run these examples." + ); return; } diff --git a/Commonbase.Examples/StreamingCompletion.cs b/Commonbase.Examples/StreamingCompletion.cs index 1bef01f..12e7acb 100644 --- a/Commonbase.Examples/StreamingCompletion.cs +++ b/Commonbase.Examples/StreamingCompletion.cs @@ -4,7 +4,8 @@ public static class StreamingCompletionExample { public static async Task RunAsync() { - CommonbaseClient client = new(); + CommonbaseClient client = new(apiKey: Program.CB_API_KEY!); + string prompt = "Write me an essay about artificial intelligence."; var stream = client.StreamCompletionAsync( diff --git a/Commonbase.Examples/TextCompletion.cs b/Commonbase.Examples/TextCompletion.cs index 2612615..7ff8406 100644 --- a/Commonbase.Examples/TextCompletion.cs +++ b/Commonbase.Examples/TextCompletion.cs @@ -4,7 +4,8 @@ public static class TextCompletionExample { public static async Task RunAsync() { - CommonbaseClient client = new(); + CommonbaseClient client = new(apiKey: Program.CB_API_KEY!); + string prompt = "Hello, what is your name?"; Console.WriteLine("\n======================================================="); diff --git a/Commonbase.Tests/ClientTests.cs b/Commonbase.Tests/ClientTests.cs index e210035..c2c592b 100644 --- a/Commonbase.Tests/ClientTests.cs +++ b/Commonbase.Tests/ClientTests.cs @@ -8,10 +8,19 @@ public ClientTests() { Client = new CommonbaseClient(new ClientOptions { - ProjectId = Environment.GetEnvironmentVariable("CB_PROJECT_ID") + ApiKey = Environment.GetEnvironmentVariable("CB_API_KEY")!, + ProjectId = Environment.GetEnvironmentVariable("CB_PROJECT_ID")! }); } + [Fact] + public void ShouldThrowArgumentExceptionOnNoApiKey() + { + Assert.Throws( + () => new CommonbaseClient(apiKey: "") + ); + } + [Fact] public async void ShouldFailOnInvalidProjectId() { diff --git a/Commonbase/CommonbaseClient.cs b/Commonbase/CommonbaseClient.cs index 7674312..d19bfe1 100644 --- a/Commonbase/CommonbaseClient.cs +++ b/Commonbase/CommonbaseClient.cs @@ -4,7 +4,11 @@ namespace Commonbase; -public record ClientOptions(string? ProjectId = null, string? ApiKey = null); +public record ClientOptions +{ + public required string ApiKey { get; init; } + public string? ProjectId { get; init; } +} public class CommonbaseClient { @@ -21,9 +25,15 @@ static CommonbaseClient() private HttpClient HttpClient; private ClientOptions clientOptions; - public CommonbaseClient(ClientOptions? options = null) + public CommonbaseClient(string apiKey) : this(new ClientOptions { ApiKey = apiKey }) { } + public CommonbaseClient(ClientOptions options) { - clientOptions = options ?? new ClientOptions(); + if (string.IsNullOrWhiteSpace(options.ApiKey)) + { + throw new ArgumentException("Api Key must not be null or empty.", nameof(options.ApiKey)); + } + + clientOptions = options; HttpClient = new HttpClient(); } @@ -59,6 +69,7 @@ private async Task SendCompletionRequestAsync( request.Content = body; + request.Headers.Add("Authorization", clientOptions.ApiKey); request.Headers.Add("User-Agent", $"commonbase-dotnet/{ClientVersion}"); if (stream) diff --git a/README.md b/README.md index 9e3a8d0..7daef4a 100644 --- a/README.md +++ b/README.md @@ -16,24 +16,25 @@ dotnet package add Commonbase ## Usage -A project ID is required for all Commonbase requests. You can find your project ID -in the [Commonbase Dashboard](https://commonbase.com/). +A Project ID and API Key are required for all Commonbase requests. You can find your Project ID +and generate an API Key in the [Commonbase Dashboard](https://commonbase.com/). -To create text and chat completions, use `CommonbaseClient.CreateCompletionAsync`: +To create a completion, configure a `CommonbaseClient` with your API Key and provide your Project +ID and prompt to `CreateCompletionAsync`: ```c# using Commonbase; -CommonbaseClient client = new(); +CommonbaseClient client = new(apiKey: "API_KEY"); var response = await client.CreateCompletionAsync( prompt: "Hello!", - projectId: "" + projectId: "PROJECT_ID" ); Console.WriteLine(response.BestResult); ``` -To stream a completion as it is generated, use `CommonbaseClient.StreamCompletionAsync`. +To stream a completion as it is generated, use `StreamCompletionAsync`. For more examples, see [/Commonbase.Examples](https://github.com/commonbaseapp/commonbase-dotnet/tree/main/Commonbase.Examples).