Skip to content

Commit

Permalink
OpenAI-DotNet 7.3.8 (#192)
Browse files Browse the repository at this point in the history
- Added Chat.Content.ctr overloads and implicit casting for easier usage
- Internal refactoring of FilesEndpoint.DeleteFileAsync (better status checking)
- Internal refactoring of FineTuningEndpoint to ensure we're properly setting response data
- Updated unit tests
- Updated docs
  • Loading branch information
StephenHodgson authored Nov 29, 2023
1 parent bdd720d commit 929f45e
Show file tree
Hide file tree
Showing 23 changed files with 310 additions and 551 deletions.
3 changes: 3 additions & 0 deletions OpenAI-DotNet-Tests/TestFixture_01_Models.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal class TestFixture_01_Models : AbstractTestFixture
[Test]
public async Task Test_1_GetModels()
{
Assert.IsNotNull(OpenAIClient.ModelsEndpoint);
var results = await OpenAIClient.ModelsEndpoint.GetModelsAsync();
Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand All @@ -18,7 +19,9 @@ public async Task Test_1_GetModels()
[Test]
public async Task Test_2_RetrieveModelDetails()
{
Assert.IsNotNull(OpenAIClient.ModelsEndpoint);
var models = await OpenAIClient.ModelsEndpoint.GetModelsAsync();
Assert.IsNotEmpty(models);
Console.WriteLine($"Found {models.Count} models!");

foreach (var model in models.OrderBy(model => model.Id))
Expand Down
426 changes: 82 additions & 344 deletions OpenAI-DotNet-Tests/TestFixture_03_Chat.cs

Large diffs are not rendered by default.

15 changes: 7 additions & 8 deletions OpenAI-DotNet-Tests/TestFixture_05_Images.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ namespace OpenAI.Tests
internal class TestFixture_05_Images : AbstractTestFixture
{
[Test]
public async Task Test_1_GenerateImages()
public async Task Test_01_01_GenerateImages()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var request = new ImageGenerationRequest("A house riding a velociraptor", Model.DallE_2);
var request = new ImageGenerationRequest("A house riding a velociraptor", Model.DallE_3);
var imageResults = await OpenAIClient.ImagesEndPoint.GenerateImageAsync(request);

Assert.IsNotNull(imageResults);
Expand All @@ -28,7 +27,7 @@ public async Task Test_1_GenerateImages()
}

[Test]
public async Task Test_2_GenerateImages_B64_Json()
public async Task Test_01_02_GenerateImages_B64_Json()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

Expand All @@ -46,7 +45,7 @@ public async Task Test_2_GenerateImages_B64_Json()
}

[Test]
public async Task Test_3_GenerateImageEdits()
public async Task Test_02_01_CreateImageEdit()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

Expand All @@ -67,7 +66,7 @@ public async Task Test_3_GenerateImageEdits()
}

[Test]
public async Task Test_4_GenerateImageEdits_B64_Json()
public async Task Test_02_02_CreateImageEdit_B64_Json()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

Expand All @@ -88,7 +87,7 @@ public async Task Test_4_GenerateImageEdits_B64_Json()
}

[Test]
public async Task Test_5_GenerateImageVariations()
public async Task Test_03_01_CreateImageVariation()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

Expand All @@ -107,7 +106,7 @@ public async Task Test_5_GenerateImageVariations()
}

[Test]
public async Task Test_6_GenerateImageVariations_B64_Json()
public async Task Test_03_02_CreateImageVariation_B64_Json()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

Expand Down
6 changes: 3 additions & 3 deletions OpenAI-DotNet-Tests/TestFixture_08_Files.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task Test_01_UploadFile()
{
Assert.IsNotNull(OpenAIClient.FilesEndpoint);
var testData = new Conversation(new List<Message> { new Message(Role.Assistant, "I'm a learning language model") });
await File.WriteAllTextAsync("test.jsonl", JsonSerializer.Serialize(testData, OpenAIClient.JsonSerializationOptions));
await File.WriteAllTextAsync("test.jsonl", testData);
Assert.IsTrue(File.Exists("test.jsonl"));
var result = await OpenAIClient.FilesEndpoint.UploadFileAsync("test.jsonl", "fine-tune");
Assert.IsNotNull(result);
Expand Down Expand Up @@ -72,8 +72,8 @@ public async Task Test_04_DeleteFiles()

foreach (var file in fileList)
{
var result = await OpenAIClient.FilesEndpoint.DeleteFileAsync(file);
Assert.IsTrue(result);
var isDeleted = await OpenAIClient.FilesEndpoint.DeleteFileAsync(file);
Assert.IsTrue(isDeleted);
Console.WriteLine($"{file.Id} -> deleted");
}

Expand Down
29 changes: 15 additions & 14 deletions OpenAI-DotNet-Tests/TestFixture_09_FineTuning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ private async Task<FileResponse> CreateTestTrainingDataAsync()
})
};
const string localTrainingDataPath = "fineTunesTestTrainingData.jsonl";
await File.WriteAllLinesAsync(localTrainingDataPath, conversations.Select(conversation => JsonSerializer.Serialize(conversation, OpenAIClient.JsonSerializationOptions)));
await File.WriteAllLinesAsync(localTrainingDataPath, conversations.Select(conversation => conversation.ToString()));

var fileData = await OpenAIClient.FilesEndpoint.UploadFileAsync(localTrainingDataPath, "fine-tune");
File.Delete(localTrainingDataPath);
Assert.IsFalse(File.Exists(localTrainingDataPath));
Expand All @@ -92,6 +93,7 @@ public async Task Test_01_CreateFineTuneJob()
{
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var fileData = await CreateTestTrainingDataAsync();
Assert.IsNotNull(fileData);
var request = new CreateFineTuneJobRequest(Model.GPT3_5_Turbo, fileData);
var job = await OpenAIClient.FineTuningEndpoint.CreateJobAsync(request);

Expand All @@ -103,11 +105,11 @@ public async Task Test_01_CreateFineTuneJob()
public async Task Test_02_ListFineTuneJobs()
{
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Items);
var jobList = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(jobList);
Assert.IsNotEmpty(jobList.Items);

foreach (var job in list.Items.OrderByDescending(job => job.CreatedAt))
foreach (var job in jobList.Items.OrderByDescending(job => job.CreatedAt))
{
Assert.IsNotNull(job);
Assert.IsNotNull(job.Client);
Expand Down Expand Up @@ -135,11 +137,11 @@ public async Task Test_03_RetrieveFineTuneJobInfo()
public async Task Test_04_ListFineTuneEvents()
{
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Items);
var jobList = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(jobList);
Assert.IsNotEmpty(jobList.Items);

foreach (var job in list.Items)
foreach (var job in jobList.Items)
{
if (job.Status == JobStatus.Cancelled) { continue; }

Expand All @@ -163,11 +165,11 @@ public async Task Test_04_ListFineTuneEvents()
public async Task Test_05_CancelFineTuneJob()
{
Assert.IsNotNull(OpenAIClient.FineTuningEndpoint);
var list = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(list);
Assert.IsNotEmpty(list.Items);
var jobList = await OpenAIClient.FineTuningEndpoint.ListJobsAsync();
Assert.IsNotNull(jobList);
Assert.IsNotEmpty(jobList.Items);

foreach (var job in list.Items)
foreach (var job in jobList.Items)
{
if (job.Status is > JobStatus.NotStarted and < JobStatus.Succeeded)
{
Expand All @@ -186,7 +188,6 @@ public async Task Test_05_CancelFineTuneJob()
public async Task Test_06_DeleteFineTunedModel()
{
Assert.IsNotNull(OpenAIClient.ModelsEndpoint);

var models = await OpenAIClient.ModelsEndpoint.GetModelsAsync();
Assert.IsNotNull(models);
Assert.IsNotEmpty(models);
Expand Down
2 changes: 1 addition & 1 deletion OpenAI-DotNet-Tests/TestFixture_10_Moderations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task Test_01_Moderate()
[Test]
public async Task Test_02_Moderate_Scores()
{

Assert.IsNotNull(OpenAIClient.ModerationsEndpoint);
var response = await OpenAIClient.ModerationsEndpoint.CreateModerationAsync(new ModerationsRequest("I love you"));
Assert.IsNotNull(response);
Console.WriteLine(response.Results?[0]?.Scores?.ToString());
Expand Down
34 changes: 17 additions & 17 deletions OpenAI-DotNet/Assistants/AssistantsEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace OpenAI.Assistants
{
public sealed class AssistantsEndpoint : BaseEndPoint
{
internal AssistantsEndpoint(OpenAIClient api) : base(api) { }
internal AssistantsEndpoint(OpenAIClient client) : base(client) { }

protected override string Root => "assistants";

Expand All @@ -21,9 +21,9 @@ internal AssistantsEndpoint(OpenAIClient api) : base(api) { }
/// <returns><see cref="ListResponse{Assistant}"/></returns>
public async Task<ListResponse<AssistantResponse>> ListAssistantsAsync(ListQuery query = null, CancellationToken cancellationToken = default)
{
var response = await Api.Client.GetAsync(GetUrl(queryParameters: query), cancellationToken).ConfigureAwait(false);
var response = await client.Client.GetAsync(GetUrl(queryParameters: query), cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<ListResponse<AssistantResponse>>(responseAsString, Api);
return response.Deserialize<ListResponse<AssistantResponse>>(responseAsString, client);
}

/// <summary>
Expand All @@ -36,9 +36,9 @@ public async Task<AssistantResponse> CreateAssistantAsync(CreateAssistantRequest
{
request ??= new CreateAssistantRequest();
var jsonContent = JsonSerializer.Serialize(request, OpenAIClient.JsonSerializationOptions).ToJsonStringContent(EnableDebug);
var response = await Api.Client.PostAsync(GetUrl(), jsonContent, cancellationToken).ConfigureAwait(false);
var response = await client.Client.PostAsync(GetUrl(), jsonContent, cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<AssistantResponse>(responseAsString, Api);
return response.Deserialize<AssistantResponse>(responseAsString, client);
}

/// <summary>
Expand All @@ -49,9 +49,9 @@ public async Task<AssistantResponse> CreateAssistantAsync(CreateAssistantRequest
/// <returns><see cref="AssistantResponse"/>.</returns>
public async Task<AssistantResponse> RetrieveAssistantAsync(string assistantId, CancellationToken cancellationToken = default)
{
var response = await Api.Client.GetAsync(GetUrl($"/{assistantId}"), cancellationToken).ConfigureAwait(false);
var response = await client.Client.GetAsync(GetUrl($"/{assistantId}"), cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<AssistantResponse>(responseAsString, Api);
return response.Deserialize<AssistantResponse>(responseAsString, client);
}

/// <summary>
Expand All @@ -64,9 +64,9 @@ public async Task<AssistantResponse> RetrieveAssistantAsync(string assistantId,
public async Task<AssistantResponse> ModifyAssistantAsync(string assistantId, CreateAssistantRequest request, CancellationToken cancellationToken = default)
{
var jsonContent = JsonSerializer.Serialize(request, OpenAIClient.JsonSerializationOptions).ToJsonStringContent(EnableDebug);
var response = await Api.Client.PostAsync(GetUrl($"/{assistantId}"), jsonContent, cancellationToken).ConfigureAwait(false);
var response = await client.Client.PostAsync(GetUrl($"/{assistantId}"), jsonContent, cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<AssistantResponse>(responseAsString, Api);
return response.Deserialize<AssistantResponse>(responseAsString, client);
}

/// <summary>
Expand All @@ -77,7 +77,7 @@ public async Task<AssistantResponse> ModifyAssistantAsync(string assistantId, Cr
/// <returns>True, if the assistant was deleted.</returns>
public async Task<bool> DeleteAssistantAsync(string assistantId, CancellationToken cancellationToken = default)
{
var response = await Api.Client.DeleteAsync(GetUrl($"/{assistantId}"), cancellationToken).ConfigureAwait(false);
var response = await client.Client.DeleteAsync(GetUrl($"/{assistantId}"), cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return JsonSerializer.Deserialize<DeletedResponse>(responseAsString, OpenAIClient.JsonSerializationOptions)?.Deleted ?? false;
}
Expand All @@ -93,9 +93,9 @@ public async Task<bool> DeleteAssistantAsync(string assistantId, CancellationTok
/// <returns><see cref="ListResponse{AssistantFile}"/>.</returns>
public async Task<ListResponse<AssistantFileResponse>> ListFilesAsync(string assistantId, ListQuery query = null, CancellationToken cancellationToken = default)
{
var response = await Api.Client.GetAsync(GetUrl($"/{assistantId}/files", query), cancellationToken).ConfigureAwait(false);
var response = await client.Client.GetAsync(GetUrl($"/{assistantId}/files", query), cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<ListResponse<AssistantFileResponse>>(responseAsString, Api);
return response.Deserialize<ListResponse<AssistantFileResponse>>(responseAsString, client);
}

/// <summary>
Expand All @@ -116,9 +116,9 @@ public async Task<AssistantFileResponse> AttachFileAsync(string assistantId, Fil
}

var jsonContent = JsonSerializer.Serialize(new { file_id = file.Id }, OpenAIClient.JsonSerializationOptions).ToJsonStringContent(EnableDebug);
var response = await Api.Client.PostAsync(GetUrl($"/{assistantId}/files"), jsonContent, cancellationToken).ConfigureAwait(false);
var response = await client.Client.PostAsync(GetUrl($"/{assistantId}/files"), jsonContent, cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<AssistantFileResponse>(responseAsString, Api);
return response.Deserialize<AssistantFileResponse>(responseAsString, client);
}

/// <summary>
Expand All @@ -130,9 +130,9 @@ public async Task<AssistantFileResponse> AttachFileAsync(string assistantId, Fil
/// <returns><see cref="AssistantFileResponse"/>.</returns>
public async Task<AssistantFileResponse> RetrieveFileAsync(string assistantId, string fileId, CancellationToken cancellationToken = default)
{
var response = await Api.Client.GetAsync(GetUrl($"/{assistantId}/files/{fileId}"), cancellationToken).ConfigureAwait(false);
var response = await client.Client.GetAsync(GetUrl($"/{assistantId}/files/{fileId}"), cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return response.Deserialize<AssistantFileResponse>(responseAsString, Api);
return response.Deserialize<AssistantFileResponse>(responseAsString, client);
}

/// <summary>
Expand All @@ -149,7 +149,7 @@ public async Task<AssistantFileResponse> RetrieveFileAsync(string assistantId, s
/// <returns>True, if file was removed.</returns>
public async Task<bool> RemoveFileAsync(string assistantId, string fileId, CancellationToken cancellationToken = default)
{
var response = await Api.Client.DeleteAsync(GetUrl($"/{assistantId}/files/{fileId}"), cancellationToken).ConfigureAwait(false);
var response = await client.Client.DeleteAsync(GetUrl($"/{assistantId}/files/{fileId}"), cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);
return JsonSerializer.Deserialize<DeletedResponse>(responseAsString, OpenAIClient.JsonSerializationOptions)?.Deleted ?? false;
}
Expand Down
8 changes: 4 additions & 4 deletions OpenAI-DotNet/Audio/AudioEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public AudioResponse(string text)
}

/// <inheritdoc />
public AudioEndpoint(OpenAIClient api) : base(api) { }
public AudioEndpoint(OpenAIClient client) : base(client) { }

/// <inheritdoc />
protected override string Root => "audio";
Expand All @@ -42,7 +42,7 @@ public AudioEndpoint(OpenAIClient api) : base(api) { }
public async Task<ReadOnlyMemory<byte>> CreateSpeechAsync(SpeechRequest request, Func<ReadOnlyMemory<byte>, Task> chunkCallback = null, CancellationToken cancellationToken = default)
{
var jsonContent = JsonSerializer.Serialize(request, OpenAIClient.JsonSerializationOptions).ToJsonStringContent(EnableDebug);
var response = await Api.Client.PostAsync(GetUrl("/speech"), jsonContent, cancellationToken).ConfigureAwait(false);
var response = await client.Client.PostAsync(GetUrl("/speech"), jsonContent, cancellationToken).ConfigureAwait(false);
await response.CheckResponseAsync(cancellationToken).ConfigureAwait(false);
await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using var memoryStream = new MemoryStream();
Expand Down Expand Up @@ -106,7 +106,7 @@ public async Task<string> CreateTranscriptionAsync(AudioTranscriptionRequest req

request.Dispose();

var response = await Api.Client.PostAsync(GetUrl("/transcriptions"), content, cancellationToken).ConfigureAwait(false);
var response = await client.Client.PostAsync(GetUrl("/transcriptions"), content, cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);

return responseFormat == AudioResponseFormat.Json
Expand Down Expand Up @@ -143,7 +143,7 @@ public async Task<string> CreateTranslationAsync(AudioTranslationRequest request

request.Dispose();

var response = await Api.Client.PostAsync(GetUrl("/translations"), content, cancellationToken).ConfigureAwait(false);
var response = await client.Client.PostAsync(GetUrl("/translations"), content, cancellationToken).ConfigureAwait(false);
var responseAsString = await response.ReadAsStringAsync(EnableDebug, cancellationToken).ConfigureAwait(false);

return responseFormat == AudioResponseFormat.Json
Expand Down
Loading

0 comments on commit 929f45e

Please sign in to comment.