Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
29 changes: 29 additions & 0 deletions api/OpenAI.net8.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class OpenAIClient {
public virtual RealtimeClient GetRealtimeClient();
[Experimental("OPENAI001")]
public virtual VectorStoreClient GetVectorStoreClient();
[Experimental("OPENAI001")]
public virtual Videos.VideoClient GetVideoClient();
}
public class OpenAIClientOptions : ClientPipelineOptions {
public Uri Endpoint { get; set; }
Expand Down Expand Up @@ -6815,4 +6817,31 @@ public enum VectorStoreStatus {
Completed = 2,
Expired = 3
}
}
namespace OpenAI.Videos {
[Experimental("OPENAI001")]
public class VideoClient {
protected VideoClient();
public VideoClient(ApiKeyCredential credential, OpenAIClientOptions options);
public VideoClient(ApiKeyCredential credential);
public VideoClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options);
public VideoClient(AuthenticationPolicy authenticationPolicy);
protected internal VideoClient(ClientPipeline pipeline, OpenAIClientOptions options);
public VideoClient(string apiKey);
[Experimental("OPENAI001")]
public Uri Endpoint { get; }
public ClientPipeline Pipeline { get; }
public virtual ClientResult CreateVideo(BinaryContent content, string contentType, RequestOptions options = null);
public virtual Task<ClientResult> CreateVideoAsync(BinaryContent content, string contentType, RequestOptions options = null);
public virtual ClientResult CreateVideoRemix(string videoId, BinaryContent content, string contentType, RequestOptions options = null);
public virtual Task<ClientResult> CreateVideoRemixAsync(string videoId, BinaryContent content, string contentType, RequestOptions options = null);
public virtual ClientResult DeleteVideo(string videoId, RequestOptions options = null);
public virtual Task<ClientResult> DeleteVideoAsync(string videoId, RequestOptions options = null);
public virtual ClientResult GetVideo(string videoId, RequestOptions options = null);
public virtual Task<ClientResult> GetVideoAsync(string videoId, RequestOptions options = null);
public virtual ClientResult GetVideos(long? limit = null, string order = null, string after = null, RequestOptions options = null);
public virtual Task<ClientResult> GetVideosAsync(long? limit = null, string order = null, string after = null, RequestOptions options = null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"GetVideos" and "GetVideosAsync" should implement the pagination pattern. As an example, you can take a look at the ContainerClient:
🔗 https://github.com/openai/openai-dotnet/blob/main/api/OpenAI.net8.0.cs#L2429

This is Chris's PR:
🔗 #624

We don't need to block the release on this, so we can add it in a separate PR. 🙂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created an issue for this: #776

public virtual ClientResult RetrieveVideoContent(string videoId, string variant = null, RequestOptions options = null);
public virtual Task<ClientResult> RetrieveVideoContentAsync(string videoId, string variant = null, RequestOptions options = null);
}
}
26 changes: 26 additions & 0 deletions api/OpenAI.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class OpenAIClient {
public virtual OpenAIResponseClient GetOpenAIResponseClient(string model);
public virtual RealtimeClient GetRealtimeClient();
public virtual VectorStoreClient GetVectorStoreClient();
public virtual Videos.VideoClient GetVideoClient();
}
public class OpenAIClientOptions : ClientPipelineOptions {
public Uri Endpoint { get; set; }
Expand Down Expand Up @@ -6007,4 +6008,29 @@ public enum VectorStoreStatus {
Completed = 2,
Expired = 3
}
}
namespace OpenAI.Videos {
public class VideoClient {
protected VideoClient();
public VideoClient(ApiKeyCredential credential, OpenAIClientOptions options);
public VideoClient(ApiKeyCredential credential);
public VideoClient(AuthenticationPolicy authenticationPolicy, OpenAIClientOptions options);
public VideoClient(AuthenticationPolicy authenticationPolicy);
protected internal VideoClient(ClientPipeline pipeline, OpenAIClientOptions options);
public VideoClient(string apiKey);
public Uri Endpoint { get; }
public ClientPipeline Pipeline { get; }
public virtual ClientResult CreateVideo(BinaryContent content, string contentType, RequestOptions options = null);
public virtual Task<ClientResult> CreateVideoAsync(BinaryContent content, string contentType, RequestOptions options = null);
public virtual ClientResult CreateVideoRemix(string videoId, BinaryContent content, string contentType, RequestOptions options = null);
public virtual Task<ClientResult> CreateVideoRemixAsync(string videoId, BinaryContent content, string contentType, RequestOptions options = null);
public virtual ClientResult DeleteVideo(string videoId, RequestOptions options = null);
public virtual Task<ClientResult> DeleteVideoAsync(string videoId, RequestOptions options = null);
public virtual ClientResult GetVideo(string videoId, RequestOptions options = null);
public virtual Task<ClientResult> GetVideoAsync(string videoId, RequestOptions options = null);
public virtual ClientResult GetVideos(long? limit = null, string order = null, string after = null, RequestOptions options = null);
public virtual Task<ClientResult> GetVideosAsync(long? limit = null, string order = null, string after = null, RequestOptions options = null);
public virtual ClientResult RetrieveVideoContent(string videoId, string variant = null, RequestOptions options = null);
public virtual Task<ClientResult> RetrieveVideoContentAsync(string videoId, string variant = null, RequestOptions options = null);
}
}
2 changes: 1 addition & 1 deletion examples/OpenAI.Examples.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>

Expand Down
52 changes: 52 additions & 0 deletions examples/Videos/Example01_VideoCreation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using OpenAI.Videos;
using System;
using System.ClientModel;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace OpenAI.Examples;

// This example uses experimental APIs which are subject to change. To use experimental APIs,
// please acknowledge their experimental status by suppressing the corresponding warning.
#pragma warning disable OPENAI001

public partial class VideoExamples
{
[Test]
public void Example01_VideoCreation()
{
// 1) Create the client
VideoClient client = new(new ApiKeyCredential(Environment.GetEnvironmentVariable("OPENAI_API_KEY")));

// 2) Build the multipart/form-data payload with an explicit boundary
var boundary = Guid.NewGuid().ToString();
var contentType = $"multipart/form-data; boundary=\"{boundary}\"";
using var multipart = new MultipartFormDataContent(boundary);

multipart.Add(new StringContent("sora-2", Encoding.UTF8, "text/plain"), "model");
multipart.Add(new StringContent("A calico cat playing a piano on stage", Encoding.UTF8, "text/plain"), "prompt");

// 3) Get a stream for the multipart body
using var bodyStream = multipart.ReadAsStream();

// 4) Send the request
var createResult = client.CreateVideo(BinaryContent.Create(bodyStream), contentType);
var createRaw = createResult.GetRawResponse().Content;

// 5) Parse the JSON response
using var createdDoc = JsonDocument.Parse(createRaw);
var id = createdDoc.RootElement.GetProperty("id").GetString();
var status = createdDoc.RootElement.GetProperty("status").GetString();

Console.WriteLine($"CreateVideo => id: {id}, status: {status}");
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!


#pragma warning restore OPENAI001
49 changes: 49 additions & 0 deletions examples/Videos/Example01_VideoCreationAsync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using OpenAI.Videos;
using System;
using System.ClientModel;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace OpenAI.Examples;

// This example uses experimental APIs which are subject to change. To use experimental APIs,
// please acknowledge their experimental status by suppressing the corresponding warning.
#pragma warning disable OPENAI001

public partial class VideoExamples
{
[Test]
public async Task Example01_VideoCreationAsync()
{
// 1) Create the client
VideoClient client = new(new ApiKeyCredential(Environment.GetEnvironmentVariable("OPENAI_API_KEY")));

// 2) Build the multipart/form-data payload with an explicit boundary
var boundary = Guid.NewGuid().ToString();
var contentType = $"multipart/form-data; boundary=\"{boundary}\"";
using var multipart = new MultipartFormDataContent(boundary);

multipart.Add(new StringContent("sora-2", Encoding.UTF8, "text/plain"), "model");
multipart.Add(new StringContent("A calico cat playing a piano on stage", Encoding.UTF8, "text/plain"), "prompt");

// 3) Get a stream for the multipart body
using var bodyStream = await multipart.ReadAsStreamAsync();

// 4) Send the request
var createResult = await client.CreateVideoAsync(BinaryContent.Create(bodyStream), contentType);
var createRaw = createResult.GetRawResponse().Content;

// 5) Parse the JSON response
using var createdDoc = JsonDocument.Parse(createRaw);
var id = createdDoc.RootElement.GetProperty("id").GetString();
var status = createdDoc.RootElement.GetProperty("status").GetString();

Console.WriteLine($"CreateVideo => id: {id}, status: {status}");
}
}

#pragma warning restore OPENAI001
9 changes: 9 additions & 0 deletions specification/base/typespec/common/models.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,12 @@ union ServiceTier {
"flex",
"scale",
}

#suppress "@azure-tools/typespec-azure-core/no-enum" "Auto-suppressed warnings non-applicable rules during import."
#suppress "@azure-tools/typespec-azure-core/documentation-required" "Auto-suppressed warnings non-applicable rules during import."
enum OrderEnum {
#suppress "@azure-tools/typespec-azure-core/documentation-required" "Auto-suppressed warnings non-applicable rules during import."
asc,
#suppress "@azure-tools/typespec-azure-core/documentation-required" "Auto-suppressed warnings non-applicable rules during import."
desc,
}
1 change: 1 addition & 0 deletions specification/base/typespec/main.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ import "./runs";
import "./threads";
import "./responses";
import "./vector-stores";
import "./videos";
import "./uploads";
2 changes: 2 additions & 0 deletions specification/base/typespec/videos/main.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./models.tsp";
import "./operations.tsp";
Loading