Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch API #537

Merged
merged 1 commit into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions OpenAI.Playground/OpenAI.Playground.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
<None Update="ApiSettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SampleData\BatchDataSampleFile.jsonl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SampleData\FineTuningSample1.jsonl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
4 changes: 2 additions & 2 deletions OpenAI.Playground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@

// Tools
//await ChatCompletionTestHelper.RunChatFunctionCallTest(sdk);
await ChatCompletionTestHelper.RunChatFunctionCallTestAsStream(sdk);

//await ChatCompletionTestHelper.RunChatFunctionCallTestAsStream(sdk);
await BatchTestHelper.RunBatchOperationsTest(sdk);
// Whisper
//await AudioTestHelper.RunSimpleAudioCreateTranscriptionTest(sdk);
//await AudioTestHelper.RunSimpleAudioCreateTranslationTest(sdk);
Expand Down
1 change: 1 addition & 0 deletions OpenAI.Playground/SampleData/BatchDataSampleFile.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +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?"}]}}
77 changes: 77 additions & 0 deletions OpenAI.Playground/TestHelpers/BatchTestHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using OpenAI.Interfaces;
using OpenAI.ObjectModels.RequestModels;

namespace OpenAI.Playground.TestHelpers;

internal static class BatchTestHelper
{
public static async Task RunBatchOperationsTest(IOpenAIService sdk)
{
ConsoleExtensions.WriteLine("Batch Operations Testing is starting:", ConsoleColor.Cyan);

try
{
ConsoleExtensions.WriteLine("Batch Create Test:", ConsoleColor.DarkCyan);

const string fileName = "BatchDataSampleFile.jsonl";
var sampleFile = await FileExtensions.ReadAllBytesAsync($"SampleData/{fileName}");
ConsoleExtensions.WriteLine($"Uploading file {fileName}", ConsoleColor.DarkCyan);

var fileUploadResult = await sdk.Files.UploadFile("batch", sampleFile, fileName);

if (!fileUploadResult.Successful)
{
throw new Exception("File upload failed");
}

var batchCreateResult = await sdk.Batch.BatchCreate(new BatchCreateRequest
{
InputFileId = fileUploadResult.Id,
Endpoint = "/v1/chat/completions",
CompletionWindow = "24h"
});

if (!batchCreateResult.Successful)
{
throw new Exception("Batch creation failed");
}

ConsoleExtensions.WriteLine($"Batch ID: {batchCreateResult.Id}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($"Batch Status: {batchCreateResult.Status}", ConsoleColor.Green);

ConsoleExtensions.WriteLine("Batch Retrieve Test:", ConsoleColor.DarkCyan);

var batchRetrieveResult = await sdk.Batch.BatchRetrieve(batchCreateResult.Id);

if (!batchRetrieveResult.Successful)
{
throw new Exception("Batch retrieval failed");
}

ConsoleExtensions.WriteLine($"Batch ID: {batchRetrieveResult.Id}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($"Batch Status: {batchRetrieveResult.Status}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($"Request Counts:", ConsoleColor.Green);
ConsoleExtensions.WriteLine($" Total: {batchRetrieveResult.RequestCounts.Total}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($" Completed: {batchRetrieveResult.RequestCounts.Completed}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($" Failed: {batchRetrieveResult.RequestCounts.Failed}", ConsoleColor.Green);

ConsoleExtensions.WriteLine("Batch Cancel Test:", ConsoleColor.DarkCyan);

var batchCancelResult = await sdk.Batch.BatchCancel(batchCreateResult.Id);

if (!batchCancelResult.Successful)
{
throw new Exception("Batch cancellation failed");
}

ConsoleExtensions.WriteLine($"Batch ID: {batchCancelResult.Id}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($"Batch Status: {batchCancelResult.Status}", ConsoleColor.Green);
ConsoleExtensions.WriteLine($"Cancelling At: {batchCancelResult.CancellingAt}", ConsoleColor.Green);
}
catch (Exception e)
{
ConsoleExtensions.WriteLine($"Error: {e.Message}", ConsoleColor.Red);
throw;
}
}
}
15 changes: 15 additions & 0 deletions OpenAI.SDK/EndpointProviders/AzureOpenAiEndpointProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,21 @@ public string AudioCreateSpeech()
return $"{Prefix}/audio/speech{QueryString}";
}

public string BatchCreate()
{
return $"{Prefix}/batches{QueryString}";
}

public string BatchRetrieve(string batchId)
{
return $"{Prefix}/batches/{batchId}{QueryString}";
}

public string BatchCancel(string batchId)
{
return $"{Prefix}/batches/{batchId}/cancel{QueryString}";
}

private string Files()
{
return $"{Prefix}/files{QueryString}";
Expand Down
3 changes: 3 additions & 0 deletions OpenAI.SDK/EndpointProviders/IOpenAiEndpointProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ internal interface IOpenAiEndpointProvider
string AudioCreateTranscription();
string AudioCreateTranslation();
string AudioCreateSpeech();
string BatchCreate();
string BatchRetrieve(string batchId);
string BatchCancel(string batchId);
}
15 changes: 15 additions & 0 deletions OpenAI.SDK/EndpointProviders/OpenAiEndpointProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ public string AudioCreateSpeech()
return $"{_apiVersion}/audio/speech";
}

public string BatchCreate()
{
return $"{_apiVersion}/batches";
}

public string BatchRetrieve(string batchId)
{
return $"{_apiVersion}/batches/{batchId}";
}

public string BatchCancel(string batchId)
{
return $"{_apiVersion}/batches/{batchId}/cancel";
}

public string EditCreate()
{
return $"{_apiVersion}/edits";
Expand Down
32 changes: 32 additions & 0 deletions OpenAI.SDK/Interfaces/IBatchService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using OpenAI.ObjectModels.RequestModels;
using OpenAI.ObjectModels.ResponseModels.BatchResponseModel;

namespace OpenAI.Interfaces;

public interface IBatchService
{
/// <summary>
/// Creates and executes a batch from an uploaded file of requests.
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns>The created Batch object.</returns>
Task<BatchResponse> BatchCreate(BatchCreateRequest request, CancellationToken cancellationToken = default);

/// <summary>
/// Retrieves a batch.
/// </summary>
/// <param name="batchId">The ID of the batch to retrieve.</param>
/// <param name="cancellationToken"></param>
/// <returns>The Batch object matching the specified ID.</returns>
Task<BatchResponse?> BatchRetrieve(string batchId, CancellationToken cancellationToken = default);

/// <summary>
/// Cancels an in-progress batch.
/// </summary>
/// <param name="batchId">The ID of the batch to cancel.</param>
/// <param name="cancellationToken"></param>
/// <returns>The Batch object matching the specified ID.</returns>
Task<BatchResponse> BatchCancel(string batchId, CancellationToken cancellationToken = default);

}
4 changes: 4 additions & 0 deletions OpenAI.SDK/Interfaces/IOpenAIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public interface IOpenAIService
/// Given an audio file, the model will return a transcription of the audio.
/// </summary>
public IAudioService Audio { get; }
/// <summary>
/// Create large batches of API requests to run asynchronously.
/// </summary>
public IBatchService Batch{ get; }


/// <summary>
Expand Down
28 changes: 28 additions & 0 deletions OpenAI.SDK/Managers/OpenAIBatchService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using OpenAI.Extensions;
using OpenAI.Interfaces;
using OpenAI.ObjectModels.RequestModels;
using OpenAI.ObjectModels.ResponseModels.BatchResponseModel;
using System.Net.Http.Json;

namespace OpenAI.Managers;

public partial class OpenAIService : IBatchService
{
/// <inheritdoc />
public async Task<BatchResponse> BatchCreate(BatchCreateRequest request, CancellationToken cancellationToken = default)
{
return await _httpClient.PostAndReadAsAsync<BatchResponse>(_endpointProvider.BatchCreate(), request, cancellationToken);
}

/// <inheritdoc />
public async Task<BatchResponse?> BatchRetrieve(string batchId, CancellationToken cancellationToken = default)
{
return await _httpClient.GetFromJsonAsync<BatchResponse>(_endpointProvider.BatchRetrieve(batchId), cancellationToken);
}

/// <inheritdoc />
public async Task<BatchResponse> BatchCancel(string batchId, CancellationToken cancellationToken = default)
{
return await _httpClient.PostAndReadAsAsync<BatchResponse>(_endpointProvider.BatchCancel(batchId),null, cancellationToken);
}
}
3 changes: 3 additions & 0 deletions OpenAI.SDK/Managers/OpenAIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ public void Dispose()

/// <inheritdoc />
public IAudioService Audio => this;

/// <inheritdoc />
public IBatchService Batch => this;

/// <summary>
/// Sets default Model Id
Expand Down
32 changes: 32 additions & 0 deletions OpenAI.SDK/ObjectModels/RequestModels/BatchCreateRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Text.Json.Serialization;

namespace OpenAI.ObjectModels.RequestModels;

public record BatchCreateRequest
{
/// <summary>
/// The ID of an uploaded file that contains requests for the new batch.
/// See [upload file](/docs/api-reference/files/create) for how to upload a file.
/// Your input file must be formatted as a JSONL file, and must be uploaded with the purpose `batch`.
/// </summary>
[JsonPropertyName("input_file_id")]
public string InputFileId { get; set; }

/// <summary>
/// The endpoint to be used for all requests in the batch. Currently only `/v1/chat/completions` is supported.
/// </summary>
[JsonPropertyName("endpoint")]
public string Endpoint { get; set; }

/// <summary>
/// The time frame within which the batch should be processed. Currently only `24h` is supported.
/// </summary>
[JsonPropertyName("completion_window")]
public string CompletionWindow { get; set; }

/// <summary>
/// Optional custom metadata for the batch.
/// </summary>
[JsonPropertyName("metadata")]
public Dictionary<string, string>? MetaData { get; set; }
}
2 changes: 2 additions & 0 deletions OpenAI.SDK/ObjectModels/ResponseModels/BaseResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class Error

[JsonPropertyName("type")] public string? Type { get; set; }

[JsonPropertyName("line")]
public int? Line { get; set; }
[JsonIgnore] public string? Message { get; private set; }

[JsonIgnore] public List<string?> Messages { get; private set; }
Expand Down
Loading
Loading