Skip to content

Commit a2a63ee

Browse files
committed
Batch API
1 parent 6d0f4e0 commit a2a63ee

File tree

17 files changed

+363
-3
lines changed

17 files changed

+363
-3
lines changed

OpenAI.Playground/OpenAI.Playground.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
<None Update="ApiSettings.json">
6060
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
6161
</None>
62+
<None Update="SampleData\BatchDataSampleFile.jsonl">
63+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
64+
</None>
6265
<None Update="SampleData\FineTuningSample1.jsonl">
6366
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
6467
</None>

OpenAI.Playground/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949

5050
// Tools
5151
//await ChatCompletionTestHelper.RunChatFunctionCallTest(sdk);
52-
await ChatCompletionTestHelper.RunChatFunctionCallTestAsStream(sdk);
53-
52+
//await ChatCompletionTestHelper.RunChatFunctionCallTestAsStream(sdk);
53+
await BatchTestHelper.RunBatchOperationsTest(sdk);
5454
// Whisper
5555
//await AudioTestHelper.RunSimpleAudioCreateTranscriptionTest(sdk);
5656
//await AudioTestHelper.RunSimpleAudioCreateTranslationTest(sdk);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is 2+2?"}]}}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using OpenAI.Interfaces;
2+
using OpenAI.ObjectModels.RequestModels;
3+
4+
namespace OpenAI.Playground.TestHelpers;
5+
6+
internal static class BatchTestHelper
7+
{
8+
public static async Task RunBatchOperationsTest(IOpenAIService sdk)
9+
{
10+
ConsoleExtensions.WriteLine("Batch Operations Testing is starting:", ConsoleColor.Cyan);
11+
12+
try
13+
{
14+
ConsoleExtensions.WriteLine("Batch Create Test:", ConsoleColor.DarkCyan);
15+
16+
const string fileName = "BatchDataSampleFile.jsonl";
17+
var sampleFile = await FileExtensions.ReadAllBytesAsync($"SampleData/{fileName}");
18+
ConsoleExtensions.WriteLine($"Uploading file {fileName}", ConsoleColor.DarkCyan);
19+
20+
var fileUploadResult = await sdk.Files.UploadFile("batch", sampleFile, fileName);
21+
22+
if (!fileUploadResult.Successful)
23+
{
24+
throw new Exception("File upload failed");
25+
}
26+
27+
var batchCreateResult = await sdk.Batch.BatchCreate(new BatchCreateRequest
28+
{
29+
InputFileId = fileUploadResult.Id,
30+
Endpoint = "/v1/chat/completions",
31+
CompletionWindow = "24h"
32+
});
33+
34+
if (!batchCreateResult.Successful)
35+
{
36+
throw new Exception("Batch creation failed");
37+
}
38+
39+
ConsoleExtensions.WriteLine($"Batch ID: {batchCreateResult.Id}", ConsoleColor.Green);
40+
ConsoleExtensions.WriteLine($"Batch Status: {batchCreateResult.Status}", ConsoleColor.Green);
41+
42+
ConsoleExtensions.WriteLine("Batch Retrieve Test:", ConsoleColor.DarkCyan);
43+
44+
var batchRetrieveResult = await sdk.Batch.BatchRetrieve(batchCreateResult.Id);
45+
46+
if (!batchRetrieveResult.Successful)
47+
{
48+
throw new Exception("Batch retrieval failed");
49+
}
50+
51+
ConsoleExtensions.WriteLine($"Batch ID: {batchRetrieveResult.Id}", ConsoleColor.Green);
52+
ConsoleExtensions.WriteLine($"Batch Status: {batchRetrieveResult.Status}", ConsoleColor.Green);
53+
ConsoleExtensions.WriteLine($"Request Counts:", ConsoleColor.Green);
54+
ConsoleExtensions.WriteLine($" Total: {batchRetrieveResult.RequestCounts.Total}", ConsoleColor.Green);
55+
ConsoleExtensions.WriteLine($" Completed: {batchRetrieveResult.RequestCounts.Completed}", ConsoleColor.Green);
56+
ConsoleExtensions.WriteLine($" Failed: {batchRetrieveResult.RequestCounts.Failed}", ConsoleColor.Green);
57+
58+
ConsoleExtensions.WriteLine("Batch Cancel Test:", ConsoleColor.DarkCyan);
59+
60+
var batchCancelResult = await sdk.Batch.BatchCancel(batchCreateResult.Id);
61+
62+
if (!batchCancelResult.Successful)
63+
{
64+
throw new Exception("Batch cancellation failed");
65+
}
66+
67+
ConsoleExtensions.WriteLine($"Batch ID: {batchCancelResult.Id}", ConsoleColor.Green);
68+
ConsoleExtensions.WriteLine($"Batch Status: {batchCancelResult.Status}", ConsoleColor.Green);
69+
ConsoleExtensions.WriteLine($"Cancelling At: {batchCancelResult.CancellingAt}", ConsoleColor.Green);
70+
}
71+
catch (Exception e)
72+
{
73+
ConsoleExtensions.WriteLine($"Error: {e.Message}", ConsoleColor.Red);
74+
throw;
75+
}
76+
}
77+
}

OpenAI.SDK/EndpointProviders/AzureOpenAiEndpointProvider.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,21 @@ public string AudioCreateSpeech()
188188
return $"{Prefix}/audio/speech{QueryString}";
189189
}
190190

191+
public string BatchCreate()
192+
{
193+
return $"{Prefix}/batches{QueryString}";
194+
}
195+
196+
public string BatchRetrieve(string batchId)
197+
{
198+
return $"{Prefix}/batches/{batchId}{QueryString}";
199+
}
200+
201+
public string BatchCancel(string batchId)
202+
{
203+
return $"{Prefix}/batches/{batchId}/cancel{QueryString}";
204+
}
205+
191206
private string Files()
192207
{
193208
return $"{Prefix}/files{QueryString}";

OpenAI.SDK/EndpointProviders/IOpenAiEndpointProvider.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ internal interface IOpenAiEndpointProvider
3434
string AudioCreateTranscription();
3535
string AudioCreateTranslation();
3636
string AudioCreateSpeech();
37+
string BatchCreate();
38+
string BatchRetrieve(string batchId);
39+
string BatchCancel(string batchId);
3740
}

OpenAI.SDK/EndpointProviders/OpenAiEndpointProvider.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ public string AudioCreateSpeech()
4747
return $"{_apiVersion}/audio/speech";
4848
}
4949

50+
public string BatchCreate()
51+
{
52+
return $"{_apiVersion}/batches";
53+
}
54+
55+
public string BatchRetrieve(string batchId)
56+
{
57+
return $"{_apiVersion}/batches/{batchId}";
58+
}
59+
60+
public string BatchCancel(string batchId)
61+
{
62+
return $"{_apiVersion}/batches/{batchId}/cancel";
63+
}
64+
5065
public string EditCreate()
5166
{
5267
return $"{_apiVersion}/edits";
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using OpenAI.ObjectModels.RequestModels;
2+
using OpenAI.ObjectModels.ResponseModels.BatchResponseModel;
3+
4+
namespace OpenAI.Interfaces;
5+
6+
public interface IBatchService
7+
{
8+
/// <summary>
9+
/// Creates and executes a batch from an uploaded file of requests.
10+
/// </summary>
11+
/// <param name="request"></param>
12+
/// <param name="cancellationToken"></param>
13+
/// <returns>The created Batch object.</returns>
14+
Task<BatchResponse> BatchCreate(BatchCreateRequest request, CancellationToken cancellationToken = default);
15+
16+
/// <summary>
17+
/// Retrieves a batch.
18+
/// </summary>
19+
/// <param name="batchId">The ID of the batch to retrieve.</param>
20+
/// <param name="cancellationToken"></param>
21+
/// <returns>The Batch object matching the specified ID.</returns>
22+
Task<BatchResponse?> BatchRetrieve(string batchId, CancellationToken cancellationToken = default);
23+
24+
/// <summary>
25+
/// Cancels an in-progress batch.
26+
/// </summary>
27+
/// <param name="batchId">The ID of the batch to cancel.</param>
28+
/// <param name="cancellationToken"></param>
29+
/// <returns>The Batch object matching the specified ID.</returns>
30+
Task<BatchResponse> BatchCancel(string batchId, CancellationToken cancellationToken = default);
31+
32+
}

OpenAI.SDK/Interfaces/IOpenAIService.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public interface IOpenAIService
5454
/// Given an audio file, the model will return a transcription of the audio.
5555
/// </summary>
5656
public IAudioService Audio { get; }
57+
/// <summary>
58+
/// Create large batches of API requests to run asynchronously.
59+
/// </summary>
60+
public IBatchService Batch{ get; }
5761

5862

5963
/// <summary>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using OpenAI.Extensions;
2+
using OpenAI.Interfaces;
3+
using OpenAI.ObjectModels.RequestModels;
4+
using OpenAI.ObjectModels.ResponseModels.BatchResponseModel;
5+
using System.Net.Http.Json;
6+
7+
namespace OpenAI.Managers;
8+
9+
public partial class OpenAIService : IBatchService
10+
{
11+
/// <inheritdoc />
12+
public async Task<BatchResponse> BatchCreate(BatchCreateRequest request, CancellationToken cancellationToken = default)
13+
{
14+
return await _httpClient.PostAndReadAsAsync<BatchResponse>(_endpointProvider.BatchCreate(), request, cancellationToken);
15+
}
16+
17+
/// <inheritdoc />
18+
public async Task<BatchResponse?> BatchRetrieve(string batchId, CancellationToken cancellationToken = default)
19+
{
20+
return await _httpClient.GetFromJsonAsync<BatchResponse>(_endpointProvider.BatchRetrieve(batchId), cancellationToken);
21+
}
22+
23+
/// <inheritdoc />
24+
public async Task<BatchResponse> BatchCancel(string batchId, CancellationToken cancellationToken = default)
25+
{
26+
return await _httpClient.PostAndReadAsAsync<BatchResponse>(_endpointProvider.BatchCancel(batchId),null, cancellationToken);
27+
}
28+
}

0 commit comments

Comments
 (0)