From 56b3a53a2a31070693351525379b6a675b068496 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:41:32 -0600 Subject: [PATCH] feat: add DeleteMessageBatchAsync method and MessageBatchDeleteResponse model with tests --- src/AnthropicClient/AnthropicApiClient.cs | 99 ++--------------- src/AnthropicClient/IAnthropicApiClient.cs | 101 ++++++++++++++++++ .../Models/MessageBatchDeleteResponse.cs | 17 +++ .../Integration/AnthropicApiClientTests.cs | 24 +++++ .../Integration/IntegrationTest.cs | 6 ++ .../Models/MessageBatchDeleteResponseTests.cs | 41 +++++++ 6 files changed, 197 insertions(+), 91 deletions(-) create mode 100644 src/AnthropicClient/IAnthropicApiClient.cs create mode 100644 src/AnthropicClient/Models/MessageBatchDeleteResponse.cs create mode 100644 tests/AnthropicClient.Tests/Unit/Models/MessageBatchDeleteResponseTests.cs diff --git a/src/AnthropicClient/AnthropicApiClient.cs b/src/AnthropicClient/AnthropicApiClient.cs index 13ceafe..826b735 100644 --- a/src/AnthropicClient/AnthropicApiClient.cs +++ b/src/AnthropicClient/AnthropicApiClient.cs @@ -8,97 +8,6 @@ using AnthropicClient.Utils; namespace AnthropicClient; -/// -/// Represents a client for interacting with the Anthropic API. -/// -public interface IAnthropicApiClient -{ - /// - /// Creates a message asynchronously. - /// - /// The message request to create. - /// A task that represents the asynchronous operation. The task result contains the response as an . - Task> CreateMessageAsync(MessageRequest request); - - /// - /// Creates a message asynchronously and streams the response. - /// - /// The message request to create. - /// An asynchronous enumerable that yields the response event by event. - IAsyncEnumerable CreateMessageAsync(StreamMessageRequest request); - - /// - /// Creates a batch of messages asynchronously. - /// - /// The message batch request to create. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is . - Task> CreateMessageBatchAsync(MessageBatchRequest request); - - /// - /// Gets a message batch asynchronously. - /// - /// The ID of the message batch to get. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is . - Task> GetMessageBatchAsync(string batchId); - - /// - /// Lists the message batches asynchronously. - /// - /// The paging request to use for listing the message batches. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is . - Task>> ListMessageBatchesAsync(PagingRequest? request = null); - - /// - /// Lists all message batches asynchronously. - /// - /// The maximum number of message batches to return in each page. - /// An asynchronous enumerable that yields the response as an where T is where T is . - IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20); - - /// - /// Cancels a message batch asynchronously. - /// - /// The ID of the message batch to cancel. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is . - Task> CancelMessageBatchAsync(string batchId); - - /// - /// Gets the results of a message batch asynchronously. - /// - /// The ID of the message batch to get the results for. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is . - Task>> GetMessageBatchResultsAsync(string batchId); - - /// - /// Counts the tokens in a message asynchronously. - /// - /// The count message tokens request. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is . - Task> CountMessageTokensAsync(CountMessageTokensRequest request); - - /// - /// Lists the models asynchronously. - /// - /// The paging request to use for listing the models. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is . - Task>> ListModelsAsync(PagingRequest? request = null); - - /// - /// Lists the models asynchronously - /// - /// The maximum number of models to return in each page. - /// An asynchronous enumerable that yields the response as an where T is where T is . - /// - IAsyncEnumerable>> ListAllModelsAsync(int limit = 20); - - /// - /// Gets a model by its ID asynchronously. - /// - /// The ID of the model to get. - /// A task that represents the asynchronous operation. The task result contains the response as an where T is . - Task> GetModelAsync(string modelId); -} - /// public class AnthropicApiClient : IAnthropicApiClient { @@ -369,6 +278,14 @@ public class AnthropicApiClient : IAnthropicApiClient return await CreateResultAsync(response); } + /// + public async Task> DeleteMessageBatchAsync(string batchId) + { + var endpoint = $"{MessageBatchesEndpoint}/{batchId}"; + var response = await SendRequestAsync(endpoint, HttpMethod.Delete); + return await CreateResultAsync(response); + } + /// public async Task>> GetMessageBatchResultsAsync(string batchId) { diff --git a/src/AnthropicClient/IAnthropicApiClient.cs b/src/AnthropicClient/IAnthropicApiClient.cs new file mode 100644 index 0000000..8081166 --- /dev/null +++ b/src/AnthropicClient/IAnthropicApiClient.cs @@ -0,0 +1,101 @@ +using AnthropicClient.Models; + +namespace AnthropicClient; + +/// +/// Represents a client for interacting with the Anthropic API. +/// +public interface IAnthropicApiClient +{ + /// + /// Creates a message asynchronously. + /// + /// The message request to create. + /// A task that represents the asynchronous operation. The task result contains the response as an . + Task> CreateMessageAsync(MessageRequest request); + + /// + /// Creates a message asynchronously and streams the response. + /// + /// The message request to create. + /// An asynchronous enumerable that yields the response event by event. + IAsyncEnumerable CreateMessageAsync(StreamMessageRequest request); + + /// + /// Creates a batch of messages asynchronously. + /// + /// The message batch request to create. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is . + Task> CreateMessageBatchAsync(MessageBatchRequest request); + + /// + /// Gets a message batch asynchronously. + /// + /// The ID of the message batch to get. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is . + Task> GetMessageBatchAsync(string batchId); + + /// + /// Lists the message batches asynchronously. + /// + /// The paging request to use for listing the message batches. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is . + Task>> ListMessageBatchesAsync(PagingRequest? request = null); + + /// + /// Lists all message batches asynchronously. + /// + /// The maximum number of message batches to return in each page. + /// An asynchronous enumerable that yields the response as an where T is where T is . + IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20); + + /// + /// Cancels a message batch asynchronously. + /// + /// The ID of the message batch to cancel. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is . + Task> CancelMessageBatchAsync(string batchId); + + /// + /// Deletes a message batch asynchronously. + /// + /// The ID of the message batch to delete. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is . + Task> DeleteMessageBatchAsync(string batchId); + + /// + /// Gets the results of a message batch asynchronously. + /// + /// The ID of the message batch to get the results for. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is . + Task>> GetMessageBatchResultsAsync(string batchId); + + /// + /// Counts the tokens in a message asynchronously. + /// + /// The count message tokens request. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is . + Task> CountMessageTokensAsync(CountMessageTokensRequest request); + + /// + /// Lists the models asynchronously. + /// + /// The paging request to use for listing the models. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is . + Task>> ListModelsAsync(PagingRequest? request = null); + + /// + /// Lists the models asynchronously + /// + /// The maximum number of models to return in each page. + /// An asynchronous enumerable that yields the response as an where T is where T is . + /// + IAsyncEnumerable>> ListAllModelsAsync(int limit = 20); + + /// + /// Gets a model by its ID asynchronously. + /// + /// The ID of the model to get. + /// A task that represents the asynchronous operation. The task result contains the response as an where T is . + Task> GetModelAsync(string modelId); +} diff --git a/src/AnthropicClient/Models/MessageBatchDeleteResponse.cs b/src/AnthropicClient/Models/MessageBatchDeleteResponse.cs new file mode 100644 index 0000000..877c808 --- /dev/null +++ b/src/AnthropicClient/Models/MessageBatchDeleteResponse.cs @@ -0,0 +1,17 @@ +namespace AnthropicClient.Models; + +/// +/// Represents a message batch delete response. +/// +public class MessageBatchDeleteResponse +{ + /// + /// Gets the ID of the message batch that was deleted. + /// + public string Id { get; init; } = string.Empty; + + /// + /// Gets the type of the message batch response. + /// + public string Type { get; init; } = string.Empty; +} \ No newline at end of file diff --git a/tests/AnthropicClient.Tests/Integration/AnthropicApiClientTests.cs b/tests/AnthropicClient.Tests/Integration/AnthropicApiClientTests.cs index 8b312c2..6cab022 100644 --- a/tests/AnthropicClient.Tests/Integration/AnthropicApiClientTests.cs +++ b/tests/AnthropicClient.Tests/Integration/AnthropicApiClientTests.cs @@ -1904,4 +1904,28 @@ public class AnthropicApiClientTests : IntegrationTest result.Error.Should().BeOfType(); result.Error.Error.Should().BeOfType(); } + + [Fact] + public async Task DeleteMessageBatchAsync_WhenCalled_ItShouldReturnDeletionResponse() + { + var batchId = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF"; + + _mockHttpMessageHandler + .WhenDeleteMessageBatchRequest(batchId) + .Respond( + HttpStatusCode.OK, + "application/json", + @"{ + ""id"": ""msgbatch_013Zva2CMHLNnXjNJJKqJ2EF"", + ""type"": ""message_batch_deleted"" + }" + ); + + var result = await Client.DeleteMessageBatchAsync(batchId); + + result.IsSuccess.Should().BeTrue(); + result.Value.Should().BeOfType(); + result.Value.Id.Should().Be(batchId); + result.Value.Type.Should().Be("message_batch_deleted"); + } } \ No newline at end of file diff --git a/tests/AnthropicClient.Tests/Integration/IntegrationTest.cs b/tests/AnthropicClient.Tests/Integration/IntegrationTest.cs index e521d0c..223107b 100644 --- a/tests/AnthropicClient.Tests/Integration/IntegrationTest.cs +++ b/tests/AnthropicClient.Tests/Integration/IntegrationTest.cs @@ -97,4 +97,10 @@ public static class MockHttpMessageHandlerExtensions return mockHttpMessageHandler .SetupBaseRequest(HttpMethod.Post, $"{MessageBatchesEndpoint}/{batchId}/cancel"); } + + public static MockedRequest WhenDeleteMessageBatchRequest(this MockHttpMessageHandler mockHttpMessageHandler, string batchId) + { + return mockHttpMessageHandler + .SetupBaseRequest(HttpMethod.Delete, $"{MessageBatchesEndpoint}/{batchId}"); + } } \ No newline at end of file diff --git a/tests/AnthropicClient.Tests/Unit/Models/MessageBatchDeleteResponseTests.cs b/tests/AnthropicClient.Tests/Unit/Models/MessageBatchDeleteResponseTests.cs new file mode 100644 index 0000000..a069ebd --- /dev/null +++ b/tests/AnthropicClient.Tests/Unit/Models/MessageBatchDeleteResponseTests.cs @@ -0,0 +1,41 @@ +namespace AnthropicClient.Tests.Unit.Models; + +public class MessageBatchDeleteResponseTests : SerializationTest +{ + private const string SampleJson = @"{ + ""id"": ""test-id"", + ""type"": ""test-type"" + }"; + + [Fact] + public void Constructor_WhenCalled_ItShouldReturnAnInstanceWithPropertiesSet() + { + var result = new MessageBatchDeleteResponse(); + + result.Id.Should().BeEmpty(); + result.Type.Should().BeEmpty(); + } + + [Fact] + public void JsonSerialization_WhenSerialized_ItShouldHaveExpectedShape() + { + var result = new MessageBatchDeleteResponse + { + Id = "test-id", + Type = "test-type" + }; + + var json = Serialize(result); + + JsonAssert.Equal(SampleJson, json); + } + + [Fact] + public void JsonDeserialization_WhenDeserialized_ItShouldHaveExpectedValues() + { + var result = Deserialize(SampleJson); + + result!.Id.Should().Be("test-id"); + result.Type.Should().Be("test-type"); + } +} \ No newline at end of file