Skip to content

Commit

Permalink
Merge pull request #31 from betalgo/dev
Browse files Browse the repository at this point in the history
Version 6.5 Dall-E Support
  • Loading branch information
kayhantolga authored Nov 4, 2022
2 parents a2e9c31 + 58973df commit 3585100
Show file tree
Hide file tree
Showing 21 changed files with 460 additions and 38 deletions.
6 changes: 6 additions & 0 deletions OpenAI.Playground/OpenAI.Playground.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
<None Update="SampleData\FineTuningSample1.jsonl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SampleData\image_edit_mask.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SampleData\image_edit_original.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SampleData\SentimentAnalysisSample.jsonl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
5 changes: 4 additions & 1 deletion OpenAI.Playground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
var serviceProvider = serviceCollection.BuildServiceProvider();
var sdk = serviceProvider.GetRequiredService<IOpenAIService>();

await ModelTestHelper.FetchModelsTest(sdk);
//await ModelTestHelper.FetchModelsTest(sdk);
//await ImageTestHelper.RunSimpleCreateImageTest(sdk);
//await ImageTestHelper.RunSimpleCreateImageEditTest(sdk);
await ImageTestHelper.RunSimpleCreateImageVariationTest(sdk);
//await ModerationTestHelper.CreateModerationTest(sdk);
//await CompletionTestHelper.RunSimpleCompletionTest(sdk);
//await EmbeddingTestHelper.RunSimpleEmbeddingTest(sdk);
Expand Down
Binary file added OpenAI.Playground/SampleData/image_edit_mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions OpenAI.Playground/TestHelpers/ImageTestHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
using OpenAI.GPT3.Interfaces;
using OpenAI.GPT3.ObjectModels;
using OpenAI.GPT3.ObjectModels.RequestModels;

namespace OpenAI.Playground.TestHelpers
{
internal static class ImageTestHelper
{
public static async Task RunSimpleCreateImageTest(IOpenAIService sdk)
{
ConsoleExtensions.WriteLine("Image Create Testing is starting:", ConsoleColor.Cyan);

try
{
ConsoleExtensions.WriteLine("Image Create Test:", ConsoleColor.DarkCyan);
var imageResult = await sdk.Image.CreateImage(new ImageCreateRequest
{
Prompt = "Laser cat eyes",
N = 2,
Size = StaticValues.ImageStatics.Size.Size256,
ResponseFormat = StaticValues.ImageStatics.ResponseFormat.Url,
User = "TestUser"
});


if (imageResult.Successful)
{
Console.WriteLine(string.Join("\n", imageResult.Results.Select(r => r.Url)));
}
else
{
if (imageResult.Error == null)
{
throw new Exception("Unknown Error");
}

Console.WriteLine($"{imageResult.Error.Code}: {imageResult.Error.Message}");
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

public static async Task RunSimpleCreateImageEditTest(IOpenAIService sdk)
{
ConsoleExtensions.WriteLine("Image Edit Create Testing is starting:", ConsoleColor.Cyan);
const string maskFileName = "image_edit_mask.png";
const string originalFileName = "image_edit_original.png";

// Images should be in png format with ARGB. I got help from this website to generate sample mask
// https://www.online-image-editor.com/
var maskFile = await File.ReadAllBytesAsync($"SampleData/{maskFileName}");
var originalFile = await File.ReadAllBytesAsync($"SampleData/{originalFileName}");

try
{
ConsoleExtensions.WriteLine("Image Edit Create Test:", ConsoleColor.DarkCyan);
var imageResult = await sdk.Image.CreateImageEdit(new ImageEditCreateRequest()
{
Image = originalFile,
ImageName = originalFileName,
Mask = maskFile,
MaskName = maskFileName,
Prompt = "A sunlit indoor lounge area with a pool containing a cat",
N = 4,
Size = StaticValues.ImageStatics.Size.Size1024,
ResponseFormat = StaticValues.ImageStatics.ResponseFormat.Url,
User = "TestUser"
});


if (imageResult.Successful)
{
Console.WriteLine(string.Join("\n", imageResult.Results.Select(r => r.Url)));
}
else
{
if (imageResult.Error == null)
{
throw new Exception("Unknown Error");
}

Console.WriteLine($"{imageResult.Error.Code}: {imageResult.Error.Message}");
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}

public static async Task RunSimpleCreateImageVariationTest(IOpenAIService sdk)
{
ConsoleExtensions.WriteLine("Image Variation Create Testing is starting:", ConsoleColor.Cyan);
const string originalFileName = "image_edit_original.png";

var originalFile = await File.ReadAllBytesAsync($"SampleData/{originalFileName}");

try
{
ConsoleExtensions.WriteLine("Image Variation Create Test:", ConsoleColor.DarkCyan);
var imageResult = await sdk.Image.CreateImageVariation(new ImageVariationCreateRequest()
{
Image = originalFile,
ImageName = originalFileName,
N = 2,
Size = StaticValues.ImageStatics.Size.Size1024,
ResponseFormat = StaticValues.ImageStatics.ResponseFormat.Url,
User = "TestUser"
});


if (imageResult.Successful)
{
Console.WriteLine(string.Join("\n", imageResult.Results.Select(r => r.Url)));
}
else
{
if (imageResult.Error == null)
{
throw new Exception("Unknown Error");
}

Console.WriteLine($"{imageResult.Error.Code}: {imageResult.Error.Message}");
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
}
42 changes: 42 additions & 0 deletions OpenAI.SDK/Interfaces/IImageService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using OpenAI.GPT3.ObjectModels.RequestModels;
using OpenAI.GPT3.ObjectModels.ResponseModels.ImageResponseModel;

namespace OpenAI.GPT3.Interfaces;

/// <summary>
/// Given a prompt and/or an input image, the model will generate a new image.
/// Related guide: <a href="https://beta.openai.com/docs/guides/images">Image generation</a>
/// </summary>
public interface IImageService
{
/// <summary>
/// Creates an image given a prompt.
/// </summary>
/// <param name="imageCreate"></param>
/// <returns></returns>
Task<ImageCreateResponse> CreateImage(ImageCreateRequest imageCreate);

/// <summary>
/// Creates an image given a prompt.
/// </summary>
/// <param name="prompt"></param>
/// <returns></returns>
Task<ImageCreateResponse> CreateImage(string prompt)
{
return CreateImage(new ImageCreateRequest(prompt));
}

/// <summary>
/// Creates an edited or extended image given an original image and a prompt.
/// </summary>
/// <param name="imageEditCreateRequest"></param>
/// <returns></returns>
Task<ImageCreateResponse> CreateImageEdit(ImageEditCreateRequest imageEditCreateRequest);

/// <summary>
/// Creates a variation of a given image.
/// </summary>
/// <param name="imageEditCreateRequest"></param>
/// <returns></returns>
Task<ImageCreateResponse> CreateImageVariation(ImageVariationCreateRequest imageEditCreateRequest);
}
6 changes: 6 additions & 0 deletions OpenAI.SDK/Interfaces/IOpenAIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public interface IOpenAIService

public IModerationService Moderation { get; }

/// <summary>
/// Given a prompt and/or an input image, the model will generate a new image.
/// </summary>
public IImageService Image { get; }


/// <summary>
/// Set default engine
/// </summary>
Expand Down
57 changes: 57 additions & 0 deletions OpenAI.SDK/Managers/OpenAIImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using OpenAI.GPT3.Extensions;
using OpenAI.GPT3.Interfaces;
using OpenAI.GPT3.ObjectModels.RequestModels;
using OpenAI.GPT3.ObjectModels.ResponseModels.ImageResponseModel;

namespace OpenAI.GPT3.Managers;

public partial class OpenAIService : IImageService
{
/// <summary>
/// Creates an image given a prompt.
/// </summary>
/// <param name="imageCreateModel"></param>
/// <returns></returns>
public async Task<ImageCreateResponse> CreateImage(ImageCreateRequest imageCreateModel)
{
return await _httpClient.PostAndReadAsAsync<ImageCreateResponse>(_endpointProvider.ImageCreate(), imageCreateModel);
}

/// <summary>
/// Creates an edited or extended image given an original image and a prompt.
/// </summary>
/// <param name="imageEditCreateRequest"></param>
/// <returns></returns>
public async Task<ImageCreateResponse> CreateImageEdit(ImageEditCreateRequest imageEditCreateRequest)
{
var multipartContent = new MultipartFormDataContent();
if (imageEditCreateRequest.User != null) multipartContent.Add(new StringContent(imageEditCreateRequest.User), "user");
if (imageEditCreateRequest.ResponseFormat != null) multipartContent.Add(new StringContent(imageEditCreateRequest.ResponseFormat), "response_format");
if (imageEditCreateRequest.Size!= null) multipartContent.Add(new StringContent(imageEditCreateRequest.Size), "size");
if (imageEditCreateRequest.N!= null) multipartContent.Add(new StringContent(imageEditCreateRequest.N.ToString()!), "n");

multipartContent.Add(new StringContent(imageEditCreateRequest.Prompt), "prompt");
multipartContent.Add(new ByteArrayContent(imageEditCreateRequest.Image), "image", imageEditCreateRequest.ImageName);
multipartContent.Add(new ByteArrayContent(imageEditCreateRequest.Mask), "mask", imageEditCreateRequest.MaskName);

return await _httpClient.PostFileAndReadAsAsync<ImageCreateResponse>(_endpointProvider.ImageEditCreate(), multipartContent);
}

/// <summary>
/// Creates a variation of a given image.
/// </summary>
/// <param name="imageEditCreateRequest"></param>
/// <returns></returns>
public async Task<ImageCreateResponse> CreateImageVariation(ImageVariationCreateRequest imageEditCreateRequest)
{
var multipartContent = new MultipartFormDataContent();
if (imageEditCreateRequest.User != null) multipartContent.Add(new StringContent(imageEditCreateRequest.User), "user");
if (imageEditCreateRequest.ResponseFormat != null) multipartContent.Add(new StringContent(imageEditCreateRequest.ResponseFormat), "response_format");
if (imageEditCreateRequest.Size!= null) multipartContent.Add(new StringContent(imageEditCreateRequest.Size), "size");
if (imageEditCreateRequest.N!= null) multipartContent.Add(new StringContent(imageEditCreateRequest.N.ToString()!), "n");

multipartContent.Add(new ByteArrayContent(imageEditCreateRequest.Image), "image", imageEditCreateRequest.ImageName);

return await _httpClient.PostFileAndReadAsAsync<ImageCreateResponse>(_endpointProvider.ImageVariationCreate(), multipartContent);
}
}
1 change: 1 addition & 0 deletions OpenAI.SDK/Managers/OpenAIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public OpenAIService(OpenAiOptions settings, HttpClient? httpClient = null)
public IFileService Files => this;
public IFineTuneService FineTunes => this;
public IModerationService Moderation => this;
public IImageService Image => this;

public void SetDefaultEngineId(string engineId)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace OpenAI.GPT3.ObjectModels.RequestModels
/// <summary>
/// Create Completion Request Model
/// </summary>
public record CompletionCreateRequest : IModelValidate, IOpenAiModels.ITemperature, IOpenAiModels.IModel, IOpenAiModels.ILogProbs
public record CompletionCreateRequest : IModelValidate, IOpenAiModels.ITemperature, IOpenAiModels.IModel, IOpenAiModels.ILogProbs, IOpenAiModels.IUser
{
/// <summary>
/// The prompt(s) to generate completions for, encoded as a string, a list of strings, or a list of token lists.
Expand Down
26 changes: 26 additions & 0 deletions OpenAI.SDK/ObjectModels/RequestModels/ImageCreateRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Text.Json.Serialization;
using OpenAI.GPT3.ObjectModels.SharedModels;

namespace OpenAI.GPT3.ObjectModels.RequestModels
{
/// <summary>
/// Image Create Request Model
/// </summary>
public class ImageCreateRequest : SharedImageRequestBaseModel, IOpenAiModels.IUser
{
public ImageCreateRequest()
{
}

public ImageCreateRequest(string prompt)
{
Prompt = prompt;
}

/// <summary>
/// A text description of the desired image(s). The maximum length is 1000 characters.
/// </summary>
[JsonPropertyName("prompt")]
public string Prompt { get; set; }
}
}
25 changes: 25 additions & 0 deletions OpenAI.SDK/ObjectModels/RequestModels/ImageEditCreateRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace OpenAI.GPT3.ObjectModels.RequestModels
{
public class ImageEditCreateRequest : ImageCreateRequest
{
/// <summary>
/// The image to edit. Must be a valid PNG file, less than 4MB, and square.
/// </summary>
public byte[] Image { get; set; }

/// <summary>
/// Image file name
/// </summary>
public string ImageName { get; set; }
/// <summary>
/// An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where image should be edited.
/// Must be a valid PNG file, less than 4MB, and have the same dimensions as image.
/// </summary>
public byte[] Mask { get; set; }

/// <summary>
/// Mask file name
/// </summary>
public string MaskName { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using OpenAI.GPT3.ObjectModels.SharedModels;

namespace OpenAI.GPT3.ObjectModels.RequestModels
{
public class ImageVariationCreateRequest : SharedImageRequestBaseModel
{
/// <summary>
/// The image to edit. Must be a valid PNG file, less than 4MB, and square.
/// </summary>
public byte[] Image { get; set; }

/// <summary>
/// Image file name
/// </summary>
public string ImageName { get; set; }
}
}
2 changes: 1 addition & 1 deletion OpenAI.SDK/ObjectModels/ResponseModels/BaseResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace OpenAI.GPT3.ObjectModels.ResponseModels
{
public record BaseResponse
{
[JsonPropertyName("object")] public string ObjectTypeName { get; set; }
[JsonPropertyName("object")] public string? ObjectTypeName { get; set; }
public bool Successful => Error == null;
[JsonPropertyName("error")] public Error? Error { get; set; }
}
Expand Down
Loading

0 comments on commit 3585100

Please sign in to comment.