Skip to content

Commit

Permalink
finish up image endpoint changes
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenHodgson committed Nov 7, 2023
1 parent 34b0d8f commit e3e8026
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 58 deletions.
32 changes: 18 additions & 14 deletions OpenAI-DotNet-Tests/TestFixture_05_Images.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public async Task Test_1_GenerateImages()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var results = await OpenAIClient.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small);
var request = new ImageGenerationRequest("A house riding a velociraptor", Models.Model.DallE_2);
var results = await OpenAIClient.ImagesEndPoint.GenerateImageAsync(request);

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand All @@ -30,7 +31,8 @@ public async Task Test_2_GenerateImages_B64_Json()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var results = await OpenAIClient.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small, responseFormat: ResponseFormat.B64_Json);
var request = new ImageGenerationRequest("A house riding a velociraptor", Models.Model.DallE_2, responseFormat: ResponseFormat.B64_Json);
var results = await OpenAIClient.ImagesEndPoint.GenerateImageAsync(request);

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand All @@ -47,10 +49,11 @@ public async Task Test_3_GenerateImageEdits()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var imageAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_original.png");
var maskAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_mask.png");
var imageAssetPath = Path.GetFullPath(@"..\..\..\Assets\image_edit_original.png");
var maskAssetPath = Path.GetFullPath(@"..\..\..\Assets\image_edit_mask.png");

var results = await OpenAIClient.ImagesEndPoint.CreateImageEditAsync(imageAssetPath, maskAssetPath, "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small);
var request = new ImageEditRequest(imageAssetPath, maskAssetPath, "A sunlit indoor lounge area with a pool containing a flamingo", size: ImageSize.Small);
var results = await OpenAIClient.ImagesEndPoint.CreateImageEditAsync(request);

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand All @@ -66,10 +69,11 @@ public async Task Test_4_GenerateImageEdits_B64_Json()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var imageAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_original.png");
var maskAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_mask.png");
var imageAssetPath = Path.GetFullPath(@"..\..\..\Assets\image_edit_original.png");
var maskAssetPath = Path.GetFullPath(@"..\..\..\Assets\image_edit_mask.png");

var results = await OpenAIClient.ImagesEndPoint.CreateImageEditAsync(imageAssetPath, maskAssetPath, "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small);
var request = new ImageEditRequest(imageAssetPath, maskAssetPath, "A sunlit indoor lounge area with a pool containing a flamingo", size: ImageSize.Small, responseFormat: ResponseFormat.B64_Json);
var results = await OpenAIClient.ImagesEndPoint.CreateImageEditAsync(request);

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand All @@ -85,9 +89,9 @@ public async Task Test_5_GenerateImageVariations()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var imageAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_original.png");

var results = await OpenAIClient.ImagesEndPoint.CreateImageVariationAsync(imageAssetPath, 1, ImageSize.Small);
var imageAssetPath = Path.GetFullPath(@"..\..\..\Assets\image_edit_original.png");
var request = new ImageVariationRequest(imageAssetPath, size: ImageSize.Small);
var results = await OpenAIClient.ImagesEndPoint.CreateImageVariationAsync(request);

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand All @@ -103,9 +107,9 @@ public async Task Test_6_GenerateImageVariations_B64_Json()
{
Assert.IsNotNull(OpenAIClient.ImagesEndPoint);

var imageAssetPath = Path.GetFullPath("..\\..\\..\\Assets\\image_edit_original.png");

var results = await OpenAIClient.ImagesEndPoint.CreateImageVariationAsync(imageAssetPath, 1, ImageSize.Small, responseFormat: ResponseFormat.B64_Json);
var imageAssetPath = Path.GetFullPath(@"..\..\..\Assets\image_edit_original.png");
var request = new ImageVariationRequest(imageAssetPath, size: ImageSize.Small, responseFormat: ResponseFormat.B64_Json);
var results = await OpenAIClient.ImagesEndPoint.CreateImageVariationAsync(request);

Assert.IsNotNull(results);
Assert.NotZero(results.Count);
Expand Down
19 changes: 8 additions & 11 deletions OpenAI-DotNet/Images/AbstractBaseImageRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using OpenAI.Extensions;
using System;
using System.Text.Json.Serialization;

namespace OpenAI.Images
Expand All @@ -23,10 +24,10 @@ public abstract class AbstractBaseImageRequest
/// <param name="responseFormat">
/// The format in which the generated images are returned.
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="Images.ResponseFormat.Url"/>
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
protected AbstractBaseImageRequest(int numberOfResults = 1, ImageSize size = ImageSize.Large, ResponseFormat responseFormat = Images.ResponseFormat.Url, string user = null)
protected AbstractBaseImageRequest(int numberOfResults = 1, ImageSize size = ImageSize.Large, ResponseFormat responseFormat = ResponseFormat.Url, string user = null)
{
Number = numberOfResults;

Expand All @@ -39,12 +40,7 @@ protected AbstractBaseImageRequest(int numberOfResults = 1, ImageSize size = Ima
};

User = user;
ResponseFormat = responseFormat switch
{
Images.ResponseFormat.Url => "url",
Images.ResponseFormat.B64_Json => "b64_json",
_ => throw new ArgumentOutOfRangeException(nameof(responseFormat), responseFormat, null)
};
ResponseFormat = responseFormat;
}

/// <summary>
Expand All @@ -56,10 +52,11 @@ protected AbstractBaseImageRequest(int numberOfResults = 1, ImageSize size = Ima
/// <summary>
/// The format in which the generated images are returned.
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="Images.ResponseFormat.Url"/>
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </summary>
[JsonPropertyName("response_format")]
public string ResponseFormat { get; }
[JsonConverter(typeof(JsonStringEnumConverter<ResponseFormat>))]
public ResponseFormat ResponseFormat { get; }

/// <summary>
/// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024.
Expand Down
11 changes: 6 additions & 5 deletions OpenAI-DotNet/Images/ImageEditRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ public sealed class ImageEditRequest : AbstractBaseImageRequest, IDisposable
/// <param name="responseFormat">
/// The format in which the generated images are returned.
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="Images.ResponseFormat.Url"/>
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </param>
public ImageEditRequest(
string imagePath,
string prompt,
int numberOfResults = 1,
ImageSize size = ImageSize.Large,
string user = null, ResponseFormat responseFormat = Images.ResponseFormat.Url)
string user = null,
ResponseFormat responseFormat = ResponseFormat.Url)
: this(imagePath, null, prompt, numberOfResults, size, user, responseFormat)
{
}
Expand Down Expand Up @@ -74,7 +75,7 @@ public ImageEditRequest(
int numberOfResults = 1,
ImageSize size = ImageSize.Large,
string user = null,
ResponseFormat responseFormat = Images.ResponseFormat.Url)
ResponseFormat responseFormat = ResponseFormat.Url)
: this(
File.OpenRead(imagePath),
Path.GetFileName(imagePath),
Expand Down Expand Up @@ -120,7 +121,7 @@ public ImageEditRequest(
int numberOfResults = 1,
ImageSize size = ImageSize.Large,
string user = null,
ResponseFormat responseFormat = Images.ResponseFormat.Url)
ResponseFormat responseFormat = ResponseFormat.Url)
: this(image, imageName, null, null, prompt, numberOfResults, size, user, responseFormat)
{
}
Expand Down Expand Up @@ -164,7 +165,7 @@ public ImageEditRequest(
int numberOfResults = 1,
ImageSize size = ImageSize.Large,
string user = null,
ResponseFormat responseFormat = Images.ResponseFormat.Url)
ResponseFormat responseFormat = ResponseFormat.Url)
: base(numberOfResults, size, responseFormat, user)
{
Image = image;
Expand Down
129 changes: 106 additions & 23 deletions OpenAI-DotNet/Images/ImageGenerationRequest.cs
Original file line number Diff line number Diff line change
@@ -1,53 +1,136 @@
using System;
using OpenAI.Models;
using System;
using System.Text.Json.Serialization;
using OpenAI.Extensions;

namespace OpenAI.Images
{
/// <summary>
/// Creates an image given a prompt.
/// </summary>
public sealed class ImageGenerationRequest : AbstractBaseImageRequest
public sealed class ImageGenerationRequest
{
[Obsolete("Use new constructor")]
public ImageGenerationRequest(string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, ResponseFormat responseFormat = ResponseFormat.Url)
{
throw new NotSupportedException();
}

/// <summary>
/// Constructor.
/// </summary>
/// <param name="prompt">
/// A text description of the desired image(s). The maximum length is 1000 characters.
/// A text description of the desired image(s).
/// The maximum length is 1000 characters for dall-e-2 and 4000 characters for dall-e-3.
/// </param>
/// <param name="model">
/// The model to use for image generation.
/// </param>
/// <param name="numberOfResults">
/// The number of images to generate. Must be between 1 and 10.
/// The number of images to generate.
/// Must be between 1 and 10. For dall-e-3, only n=1 is supported.
/// </param>
/// <param name="quality">
/// The quality of the image that will be generated.
/// hd creates images with finer details and greater consistency across the image.
/// This param is only supported for dall-e-3.
/// </param>
/// <param name="responseFormat">
/// The format in which the generated images are returned.
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </param>
/// <param name="size">
/// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024.
/// The size of the generated images.
/// Must be one of 256x256, 512x512, or 1024x1024 for dall-e-2.
/// Must be one of 1024x1024, 1792x1024, or 1024x1792 for dall-e-3 models.
/// </param>
/// <param name="style">
/// The style of the generated images.
/// Must be one of vivid or natural.
/// Vivid causes the model to lean towards generating hyper-real and dramatic images.
/// Natural causes the model to produce more natural, less hyper-real looking images.
/// This param is only supported for dall-e-3.
/// </param>
/// <param name="user">
/// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
/// </param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <param name="responseFormat">
/// The format in which the generated images are returned. Must be one of url or b64_json.
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </param>
public ImageGenerationRequest(string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, ResponseFormat responseFormat = Images.ResponseFormat.Url)
: base(numberOfResults, size, responseFormat, user)
public ImageGenerationRequest(
string prompt,
Model model = null,
int numberOfResults = 1,
string quality = null,
ResponseFormat responseFormat = ResponseFormat.Url,
string size = null,
string style = null,
string user = null)
{
if (prompt.Length > 1000)
{
throw new ArgumentOutOfRangeException(nameof(prompt), "The maximum character length for the prompt is 1000 characters.");
}

Prompt = prompt;

if (numberOfResults is > 10 or < 1)
{
throw new ArgumentOutOfRangeException(nameof(numberOfResults), "The number of results must be between 1 and 10");
}
Model = string.IsNullOrWhiteSpace(model?.Id) ? Models.Model.DallE_2 : model;
Number = numberOfResults;
Quality = quality;
ResponseFormat = responseFormat;
Size = size;
Style = style;
User = user;
}

[JsonPropertyName("model")]
public string Model { get; }

/// <summary>
/// A text description of the desired image(s). The maximum length is 1000 characters.
/// A text description of the desired image(s).
/// The maximum length is 1000 characters for dall-e-2 and 4000 characters for dall-e-3.
/// </summary>
[JsonPropertyName("prompt")]
public string Prompt { get; }

/// <summary>
/// The number of images to generate.
/// Must be between 1 and 10. For dall-e-3, only n=1 is supported.
/// </summary>
[JsonPropertyName("n")]
public int Number { get; }

/// <summary>
/// The quality of the image that will be generated.
/// hd creates images with finer details and greater consistency across the image.
/// This param is only supported for dall-e-3.
/// </summary>
[JsonPropertyName("quality")]
public string Quality { get; }

/// <summary>
/// The format in which the generated images are returned.
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </summary>
[JsonPropertyName("response_format")]
[JsonConverter(typeof(JsonStringEnumConverter<ResponseFormat>))]
public ResponseFormat ResponseFormat { get; }

/// <summary>
/// The size of the generated images.
/// Must be one of 256x256, 512x512, or 1024x1024 for dall-e-2.
/// Must be one of 1024x1024, 1792x1024, or 1024x1792 for dall-e-3 models.
/// </summary>
[JsonPropertyName("size")]
public string Size { get; }

/// <summary>
/// The style of the generated images.
/// Must be one of vivid or natural.
/// Vivid causes the model to lean towards generating hyper-real and dramatic images.
/// Natural causes the model to produce more natural, less hyper-real looking images.
/// This param is only supported for dall-e-3.
/// </summary>
[JsonPropertyName("style")]
public string Style { get; }

/// <summary>
/// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse.
/// </summary>
[JsonPropertyName("user")]
public string User { get; }
}
}
4 changes: 2 additions & 2 deletions OpenAI-DotNet/Images/ImageVariationRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public sealed class ImageVariationRequest : AbstractBaseImageRequest, IDisposabl
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </param>
public ImageVariationRequest(string imagePath, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, ResponseFormat responseFormat = Images.ResponseFormat.Url)
public ImageVariationRequest(string imagePath, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, ResponseFormat responseFormat = ResponseFormat.Url)
: this(File.OpenRead(imagePath), Path.GetFileName(imagePath), numberOfResults, size, user, responseFormat)
{
}
Expand Down Expand Up @@ -53,7 +53,7 @@ public ImageVariationRequest(string imagePath, int numberOfResults = 1, ImageSiz
/// Must be one of url or b64_json.
/// <para/> Defaults to <see cref="ResponseFormat.Url"/>
/// </param>
public ImageVariationRequest(Stream image, string imageName, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, ResponseFormat responseFormat = Images.ResponseFormat.Url)
public ImageVariationRequest(Stream image, string imageName, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, ResponseFormat responseFormat = ResponseFormat.Url)
: base(numberOfResults, size, responseFormat, user)
{
Image = image;
Expand Down
Loading

0 comments on commit e3e8026

Please sign in to comment.