diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Audio.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Audio.cs index 9f950dc1e..8b900edc4 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Audio.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Audio.cs @@ -2,12 +2,11 @@ #nullable disable +using OpenAI.Models; using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Threading; using System.Threading.Tasks; -using OpenAI.Models; namespace OpenAI { @@ -42,29 +41,25 @@ internal Audio(ClientPipeline pipeline, ApiKeyCredential keyCredential, Uri endp /// Generates audio from the input text. /// The to use. - /// The cancellation token to use. /// is null. - public virtual async Task> CreateSpeechAsync(CreateSpeechRequest speech, CancellationToken cancellationToken = default) + public virtual async Task> CreateSpeechAsync(CreateSpeechRequest speech) { Argument.AssertNotNull(speech, nameof(speech)); - RequestOptions context = FromCancellationToken(cancellationToken); - using BinaryContent content = speech.ToBinaryBody(); - ClientResult result = await CreateSpeechAsync(content, context).ConfigureAwait(false); + using BinaryContent content = speech.ToBinaryContent(); + ClientResult result = await CreateSpeechAsync(content).ConfigureAwait(false); return ClientResult.FromValue(result.GetRawResponse().Content, result.GetRawResponse()); } /// Generates audio from the input text. /// The to use. - /// The cancellation token to use. /// is null. - public virtual ClientResult CreateSpeech(CreateSpeechRequest speech, CancellationToken cancellationToken = default) + public virtual ClientResult CreateSpeech(CreateSpeechRequest speech) { Argument.AssertNotNull(speech, nameof(speech)); - RequestOptions context = FromCancellationToken(cancellationToken); - using BinaryContent content = speech.ToBinaryBody(); - ClientResult result = CreateSpeech(content, context); + using BinaryContent content = speech.ToBinaryContent(); + ClientResult result = CreateSpeech(content); return ClientResult.FromValue(result.GetRawResponse().Content, result.GetRawResponse()); } @@ -73,27 +68,29 @@ public virtual ClientResult CreateSpeech(CreateSpeechRequest speech, /// /// /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. /// /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// /// /// The content to send as the body of the request. - /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// is null. /// Service returned a non-success status code. /// The response returned from the service. - public virtual async Task CreateSpeechAsync(BinaryContent content, RequestOptions context = null) + public virtual async Task CreateSpeechAsync(BinaryContent content, RequestOptions options = null) { Argument.AssertNotNull(content, nameof(content)); - using PipelineMessage message = CreateCreateSpeechRequest(content, context); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false)); + options ??= new RequestOptions(); + + using PipelineMessage message = CreateCreateSpeechRequest(content, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } /// @@ -101,54 +98,52 @@ public virtual async Task CreateSpeechAsync(BinaryContent content, /// /// /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. /// /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// /// /// The content to send as the body of the request. - /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// is null. /// Service returned a non-success status code. /// The response returned from the service. - public virtual ClientResult CreateSpeech(BinaryContent content, RequestOptions context = null) + public virtual ClientResult CreateSpeech(BinaryContent content, RequestOptions options = null) { Argument.AssertNotNull(content, nameof(content)); - using PipelineMessage message = CreateCreateSpeechRequest(content, context); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, context)); + options ??= new RequestOptions(); + + using PipelineMessage message = CreateCreateSpeechRequest(content, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); } /// Transcribes audio into the input language. /// The to use. - /// The cancellation token to use. /// is null. - public virtual async Task> CreateTranscriptionAsync(CreateTranscriptionRequest audio, CancellationToken cancellationToken = default) + public virtual async Task> CreateTranscriptionAsync(CreateTranscriptionRequest audio) { Argument.AssertNotNull(audio, nameof(audio)); - RequestOptions context = FromCancellationToken(cancellationToken); - using BinaryContent content = audio.ToBinaryBody(); - ClientResult result = await CreateTranscriptionAsync(content, context).ConfigureAwait(false); + (BinaryContent content, string contentType, RequestOptions options) = await audio.ToMultipartContentAsync().ConfigureAwait(false); + ClientResult result = await CreateTranscriptionAsync(content, contentType, options).ConfigureAwait(false); return ClientResult.FromValue(CreateTranscriptionResponse.FromResponse(result.GetRawResponse()), result.GetRawResponse()); } /// Transcribes audio into the input language. /// The to use. - /// The cancellation token to use. /// is null. - public virtual ClientResult CreateTranscription(CreateTranscriptionRequest audio, CancellationToken cancellationToken = default) + public virtual ClientResult CreateTranscription(CreateTranscriptionRequest audio) { Argument.AssertNotNull(audio, nameof(audio)); - RequestOptions context = FromCancellationToken(cancellationToken); - using BinaryContent content = audio.ToBinaryBody(); - ClientResult result = CreateTranscription(content, context); + (BinaryContent content, string contentType, RequestOptions options) = audio.ToMultipartContentAsync().GetAwaiter().GetResult(); + ClientResult result = CreateTranscription(content, contentType, options); return ClientResult.FromValue(CreateTranscriptionResponse.FromResponse(result.GetRawResponse()), result.GetRawResponse()); } @@ -157,27 +152,30 @@ public virtual ClientResult CreateTranscription(Cre /// /// /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. /// /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// /// /// The content to send as the body of the request. - /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// The content type of the content in the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// is null. /// Service returned a non-success status code. /// The response returned from the service. - public virtual async Task CreateTranscriptionAsync(BinaryContent content, RequestOptions context = null) + public virtual async Task CreateTranscriptionAsync(BinaryContent content, string contentType, RequestOptions options = null) { Argument.AssertNotNull(content, nameof(content)); - using PipelineMessage message = CreateCreateTranscriptionRequest(content, context); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false)); + options ??= new RequestOptions(); + + using PipelineMessage message = CreateCreateTranscriptionRequest(content, contentType, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } /// @@ -185,54 +183,53 @@ public virtual async Task CreateTranscriptionAsync(BinaryContent c /// /// /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. /// /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// /// /// The content to send as the body of the request. - /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// The content type of the content in the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// is null. /// Service returned a non-success status code. /// The response returned from the service. - public virtual ClientResult CreateTranscription(BinaryContent content, RequestOptions context = null) + public virtual ClientResult CreateTranscription(BinaryContent content, string contentType, RequestOptions options = null) { Argument.AssertNotNull(content, nameof(content)); - using PipelineMessage message = CreateCreateTranscriptionRequest(content, context); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, context)); + options ??= new RequestOptions(); + + using PipelineMessage message = CreateCreateTranscriptionRequest(content, contentType, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); } /// Translates audio into English.. /// The to use. - /// The cancellation token to use. /// is null. - public virtual async Task> CreateTranslationAsync(CreateTranslationRequest audio, CancellationToken cancellationToken = default) + public virtual async Task> CreateTranslationAsync(CreateTranslationRequest audio) { Argument.AssertNotNull(audio, nameof(audio)); - RequestOptions context = FromCancellationToken(cancellationToken); - using BinaryContent content = audio.ToBinaryBody(); - ClientResult result = await CreateTranslationAsync(content, context).ConfigureAwait(false); + (BinaryContent content, string contentType, RequestOptions options) = await audio.ToMultipartContentAsync().ConfigureAwait(false); + ClientResult result = await CreateTranslationAsync(content, contentType, options).ConfigureAwait(false); return ClientResult.FromValue(CreateTranslationResponse.FromResponse(result.GetRawResponse()), result.GetRawResponse()); } /// Translates audio into English.. /// The to use. - /// The cancellation token to use. /// is null. - public virtual ClientResult CreateTranslation(CreateTranslationRequest audio, CancellationToken cancellationToken = default) + public virtual ClientResult CreateTranslation(CreateTranslationRequest audio) { Argument.AssertNotNull(audio, nameof(audio)); - RequestOptions context = FromCancellationToken(cancellationToken); - using BinaryContent content = audio.ToBinaryBody(); - ClientResult result = CreateTranslation(content, context); + (BinaryContent content, string contentType, RequestOptions options) = audio.ToMultipartContentAsync().GetAwaiter().GetResult(); + ClientResult result = CreateTranslation(content, contentType, options); return ClientResult.FromValue(CreateTranslationResponse.FromResponse(result.GetRawResponse()), result.GetRawResponse()); } @@ -241,27 +238,30 @@ public virtual ClientResult CreateTranslation(CreateT /// /// /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. /// /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// /// /// The content to send as the body of the request. - /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// The content type of the content in the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// is null. /// Service returned a non-success status code. /// The response returned from the service. - public virtual async Task CreateTranslationAsync(BinaryContent content, RequestOptions context = null) + public virtual async Task CreateTranslationAsync(BinaryContent content, string contentType, RequestOptions options = null) { Argument.AssertNotNull(content, nameof(content)); - using PipelineMessage message = CreateCreateTranslationRequest(content, context); - return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, context).ConfigureAwait(false)); + options ??= new RequestOptions(); + + using PipelineMessage message = CreateCreateTranslationRequest(content, contentType, options); + return ClientResult.FromResponse(await _pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false)); } /// @@ -269,36 +269,35 @@ public virtual async Task CreateTranslationAsync(BinaryContent con /// /// /// - /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. + /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios. /// /// /// /// - /// Please try the simpler convenience overload with strongly typed models first. + /// Please try the simpler convenience overload with strongly typed models first. /// /// /// /// /// The content to send as the body of the request. - /// The request context, which can override default behaviors of the client pipeline on a per-call basis. + /// The content type of the content in the body of the request. + /// The request options, which can override default behaviors of the client pipeline on a per-call basis. /// is null. /// Service returned a non-success status code. /// The response returned from the service. - public virtual ClientResult CreateTranslation(BinaryContent content, RequestOptions context = null) + public virtual ClientResult CreateTranslation(BinaryContent content, string contentType, RequestOptions options = null) { Argument.AssertNotNull(content, nameof(content)); - using PipelineMessage message = CreateCreateTranslationRequest(content, context); - return ClientResult.FromResponse(_pipeline.ProcessMessage(message, context)); + options ??= new RequestOptions(); + + using PipelineMessage message = CreateCreateTranslationRequest(content, contentType, options); + return ClientResult.FromResponse(_pipeline.ProcessMessage(message, options)); } - internal PipelineMessage CreateCreateSpeechRequest(BinaryContent content, RequestOptions context) + private PipelineMessage CreateCreateSpeechRequest(BinaryContent content, RequestOptions options) { var message = _pipeline.CreateMessage(); - if (context != null) - { - message.Apply(context); - } message.ResponseClassifier = PipelineMessageClassifier200; var request = message.Request; request.Method = "POST"; @@ -309,16 +308,13 @@ internal PipelineMessage CreateCreateSpeechRequest(BinaryContent content, Reques request.Headers.Set("Accept", "application/octet-stream"); request.Headers.Set("Content-Type", "application/json"); request.Content = content; + message.Apply(options); return message; } - internal PipelineMessage CreateCreateTranscriptionRequest(BinaryContent content, RequestOptions context) + private PipelineMessage CreateCreateTranscriptionRequest(BinaryContent content, string contentType, RequestOptions options) { var message = _pipeline.CreateMessage(); - if (context != null) - { - message.Apply(context); - } message.ResponseClassifier = PipelineMessageClassifier200; var request = message.Request; request.Method = "POST"; @@ -327,18 +323,15 @@ internal PipelineMessage CreateCreateTranscriptionRequest(BinaryContent content, uri.AppendPath("/audio/transcriptions", false); request.Uri = uri.ToUri(); request.Headers.Set("Accept", "application/json"); - request.Headers.Set("content-type", "multipart/form-data"); + request.Headers.Set("Content-Type", contentType); request.Content = content; + message.Apply(options); return message; } - internal PipelineMessage CreateCreateTranslationRequest(BinaryContent content, RequestOptions context) + private PipelineMessage CreateCreateTranslationRequest(BinaryContent content, string contentType, RequestOptions options) { var message = _pipeline.CreateMessage(); - if (context != null) - { - message.Apply(context); - } message.ResponseClassifier = PipelineMessageClassifier200; var request = message.Request; request.Method = "POST"; @@ -347,22 +340,12 @@ internal PipelineMessage CreateCreateTranslationRequest(BinaryContent content, R uri.AppendPath("/audio/translations", false); request.Uri = uri.ToUri(); request.Headers.Set("Accept", "application/json"); - request.Headers.Set("content-type", "multipart/form-data"); + request.Headers.Set("Content-Type", contentType); request.Content = content; + message.Apply(options); return message; } - private static RequestOptions DefaultRequestContext = new RequestOptions(); - internal static RequestOptions FromCancellationToken(CancellationToken cancellationToken = default) - { - if (!cancellationToken.CanBeCanceled) - { - return DefaultRequestContext; - } - - return new RequestOptions() { CancellationToken = cancellationToken }; - } - private static PipelineMessageClassifier _pipelineMessageClassifier200; private static PipelineMessageClassifier PipelineMessageClassifier200 => _pipelineMessageClassifier200 ??= PipelineMessageClassifier.Create(stackalloc ushort[] { 200 }); } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientPipelineExtensions.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientPipelineExtensions.cs index 778208b4f..bd86316a3 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientPipelineExtensions.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientPipelineExtensions.cs @@ -1,49 +1,37 @@ // -#nullable disable +#nullable enable -using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Threading; using System.Threading.Tasks; namespace OpenAI { internal static class ClientPipelineExtensions { - public static async ValueTask ProcessMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions requestContext, CancellationToken cancellationToken = default) + public static async ValueTask ProcessMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) { await pipeline.SendAsync(message).ConfigureAwait(false); - if (message.Response == null) + if (message.Response!.IsError && options.ErrorOptions == ClientErrorBehaviors.Default) { - throw new InvalidOperationException("Failed to receive Result."); + throw await ClientResultException.CreateAsync(message.Response).ConfigureAwait(false); } - if (!message.Response.IsError || requestContext?.ErrorOptions == ClientErrorBehaviors.NoThrow) - { - return message.Response; - } - - throw new ClientResultException(message.Response); + return message.Response; } - public static PipelineResponse ProcessMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions requestContext, CancellationToken cancellationToken = default) + public static PipelineResponse ProcessMessage(this ClientPipeline pipeline, PipelineMessage message, RequestOptions options) { pipeline.Send(message); - if (message.Response == null) - { - throw new InvalidOperationException("Failed to receive Result."); - } - - if (!message.Response.IsError || requestContext?.ErrorOptions == ClientErrorBehaviors.NoThrow) + if (message.Response!.IsError && options.ErrorOptions == ClientErrorBehaviors.Default) { - return message.Response; + throw new ClientResultException(message.Response); } - throw new ClientResultException(message.Response); + return message.Response; } public static async ValueTask> ProcessHeadAsBoolMessageAsync(this ClientPipeline pipeline, PipelineMessage message, RequestOptions requestContext) diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientUriBuilder.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientUriBuilder.cs index b24daf525..ed3a5840b 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientUriBuilder.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ClientUriBuilder.cs @@ -1,210 +1,82 @@ -// +// -#nullable disable +#nullable enable using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -namespace OpenAI -{ - internal class ClientUriBuilder - { - private UriBuilder _uriBuilder; - private StringBuilder _pathBuilder; - private StringBuilder _queryBuilder; - private const char PathSeparator = '/'; - - public ClientUriBuilder() - { - } - - private UriBuilder UriBuilder => _uriBuilder ??= new UriBuilder(); - - private StringBuilder PathBuilder => _pathBuilder ??= new StringBuilder(UriBuilder.Path); - - private StringBuilder QueryBuilder => _queryBuilder ??= new StringBuilder(UriBuilder.Query); - - public void Reset(Uri uri) - { - _uriBuilder = new UriBuilder(uri); - _pathBuilder = new StringBuilder(UriBuilder.Path); - _queryBuilder = new StringBuilder(UriBuilder.Query); - } - - public void AppendPath(string value, bool escape) - { - Argument.AssertNotNullOrWhiteSpace(value, nameof(value)); - - if (escape) - { - value = Uri.EscapeDataString(value); - } - - if (value[0] == PathSeparator) - { - value = value.Substring(1); - } - - PathBuilder.Append(value); - UriBuilder.Path = PathBuilder.ToString(); - } - - public void AppendPath(bool value, bool escape = false) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } - - public void AppendPath(float value, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } - - public void AppendPath(double value, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } - - public void AppendPath(int value, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } - - public void AppendPath(byte[] value, string format, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value, format), escape); - } - - public void AppendPath(IEnumerable value, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } - - public void AppendPath(DateTimeOffset value, string format, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value, format), escape); - } - - public void AppendPath(TimeSpan value, string format, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value, format), escape); - } - - public void AppendPath(Guid value, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } +namespace OpenAI; - public void AppendPath(long value, bool escape = true) - { - AppendPath(ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } - - public void AppendQuery(string name, string value, bool escape) - { - Argument.AssertNotNullOrWhiteSpace(name, nameof(name)); - Argument.AssertNotNullOrWhiteSpace(value, nameof(value)); - - if (QueryBuilder.Length == 0) - { - QueryBuilder.Append('?'); - } - else - { - QueryBuilder.Append('&'); - } - - if (escape) - { - value = Uri.EscapeDataString(value); - } - - QueryBuilder.Append(name); - QueryBuilder.Append('='); - QueryBuilder.Append(value); - } +internal class ClientUriBuilder +{ + private UriBuilder? _uriBuilder; + private StringBuilder? _pathBuilder; + private StringBuilder? _queryBuilder; - public void AppendQuery(string name, bool value, bool escape = false) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } + private UriBuilder UriBuilder => _uriBuilder ??= new(); + private StringBuilder PathBuilder => _pathBuilder ??= new(UriBuilder.Path); + private StringBuilder QueryBuilder => _queryBuilder ??= new(UriBuilder.Query); - public void AppendQuery(string name, float value, bool escape = true) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } + public ClientUriBuilder() + { + } - public void AppendQuery(string name, DateTimeOffset value, string format, bool escape = true) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value, format), escape); - } + public void Reset(Uri uri) + { + _uriBuilder = new(uri); + _pathBuilder = new(_uriBuilder.Path); + _queryBuilder = new(_uriBuilder.Query); + } - public void AppendQuery(string name, TimeSpan value, string format, bool escape = true) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value, format), escape); - } + public void AppendPath(string value, bool escape) + { + Argument.AssertNotNullOrWhiteSpace(value, nameof(value)); - public void AppendQuery(string name, double value, bool escape = true) + if (escape) { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); + value = Uri.EscapeDataString(value); } - public void AppendQuery(string name, decimal value, bool escape = true) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } + PathBuilder.Append(value); + UriBuilder.Path = PathBuilder.ToString(); + } - public void AppendQuery(string name, int value, bool escape = true) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } + public void AppendQuery(string name, string value, bool escape) + { + Argument.AssertNotNullOrWhiteSpace(name, nameof(name)); + Argument.AssertNotNullOrWhiteSpace(value, nameof(value)); - public void AppendQuery(string name, long value, bool escape = true) + if (QueryBuilder.Length is 0) { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); + QueryBuilder.Append('?'); } - - public void AppendQuery(string name, TimeSpan value, bool escape = true) + else { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); + QueryBuilder.Append('&'); } - public void AppendQuery(string name, byte[] value, string format, bool escape = true) + if (escape) { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value, format), escape); + value = Uri.EscapeDataString(value); } - public void AppendQuery(string name, Guid value, bool escape = true) - { - AppendQuery(name, ModelSerializationExtensions.TypeFormatters.ConvertToString(value), escape); - } + QueryBuilder.Append(name); + QueryBuilder.Append('='); + QueryBuilder.Append(value); + } - public void AppendQueryDelimited(string name, IEnumerable value, string delimiter, bool escape = true) + public Uri ToUri() + { + if (_pathBuilder is not null) { - var stringValues = value.Select(v => ModelSerializationExtensions.TypeFormatters.ConvertToString(v)); - AppendQuery(name, string.Join(delimiter, stringValues), escape); + UriBuilder.Path = _pathBuilder.ToString(); } - public void AppendQueryDelimited(string name, IEnumerable value, string delimiter, string format, bool escape = true) + if (_queryBuilder is not null) { - var stringValues = value.Select(v => ModelSerializationExtensions.TypeFormatters.ConvertToString(v, format)); - AppendQuery(name, string.Join(delimiter, stringValues), escape); + UriBuilder.Query = _queryBuilder.ToString(); } - public Uri ToUri() - { - if (_pathBuilder != null) - { - UriBuilder.Path = _pathBuilder.ToString(); - } - - if (_queryBuilder != null) - { - UriBuilder.Query = _queryBuilder.ToString(); - } - - return UriBuilder.Uri; - } + return UriBuilder.Uri; } -} +} \ No newline at end of file diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ModelSerializationExtensions.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ModelSerializationExtensions.cs index c45878d86..258cc5d23 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ModelSerializationExtensions.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Internal/ModelSerializationExtensions.cs @@ -257,7 +257,7 @@ internal static class TypeFormatters public static string ToString(DateTime value, string format) => value.Kind switch { DateTimeKind.Utc => ToString((DateTimeOffset)value, format), - _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Azure SDK requires it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.") + _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Generated clients require it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.") }; public static string ToString(DateTimeOffset value, string format) => format switch diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/AudioSegment.Serialization.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/AudioSegment.Serialization.cs index 61dd710e6..4d1c07c34 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/AudioSegment.Serialization.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/AudioSegment.Serialization.cs @@ -205,15 +205,15 @@ AudioSegment IPersistableModel.Create(BinaryData data, ModelReader string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; /// Deserializes the model from a raw response. - /// The result to deserialize the model from. + /// The response to deserialize the model from. internal static AudioSegment FromResponse(PipelineResponse response) { using var document = JsonDocument.Parse(response.Content); return DeserializeAudioSegment(document.RootElement); } - /// Convert into a Utf8JsonRequestBody. - internal virtual BinaryContent ToBinaryBody() + /// Convert into a BinaryContent. + internal virtual BinaryContent ToBinaryContent() { return BinaryContent.Create(this, new ModelReaderWriterOptions("W")); } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateSpeechRequest.Serialization.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateSpeechRequest.Serialization.cs index 1776cf051..ebd1a3c8f 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateSpeechRequest.Serialization.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateSpeechRequest.Serialization.cs @@ -164,15 +164,15 @@ CreateSpeechRequest IPersistableModel.Create(BinaryData dat string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; /// Deserializes the model from a raw response. - /// The result to deserialize the model from. + /// The response to deserialize the model from. internal static CreateSpeechRequest FromResponse(PipelineResponse response) { using var document = JsonDocument.Parse(response.Content); return DeserializeCreateSpeechRequest(document.RootElement); } - /// Convert into a Utf8JsonRequestBody. - internal virtual BinaryContent ToBinaryBody() + /// Convert into a BinaryContent. + internal virtual BinaryContent ToBinaryContent() { return BinaryContent.Create(this, new ModelReaderWriterOptions("W")); } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs index 83eb744ff..c09ab7d54 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.Serialization.cs @@ -5,191 +5,100 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; namespace OpenAI.Models { - public partial class CreateTranscriptionRequest : IJsonModel + public partial class CreateTranscriptionRequest { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + private static Random _random = new(); + private static readonly char[] _boundaryValues = "0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray(); + + internal async Task<(BinaryContent, string, RequestOptions)> ToMultipartContentAsync() { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(CreateTranscriptionRequest)} does not support writing '{format}' format."); - } + MultipartFormDataContent content = new(CreateBoundary()); - writer.WriteStartObject(); - writer.WritePropertyName("file"u8); - writer.WriteBase64StringValue(File.ToArray(), "D"); - writer.WritePropertyName("model"u8); - writer.WriteStringValue(Model.ToString()); - if (Optional.IsDefined(Language)) + if (FileName is not null) { - writer.WritePropertyName("language"u8); - writer.WriteStringValue(Language); + StreamContent fileContent = new StreamContent(File); + ContentDispositionHeaderValue header = new("form-data") + { + Name = "file", + FileName = FileName + }; + content.Headers.ContentDisposition = header; + content.Add(new StreamContent(File)); } - if (Optional.IsDefined(Prompt)) + else { - writer.WritePropertyName("prompt"u8); - writer.WriteStringValue(Prompt); + content.Add(new StreamContent(File), "file"); } - if (Optional.IsDefined(ResponseFormat)) + + content.Add(new StringContent(Model.ToString()), "model"); + + if (Language is not null) { - writer.WritePropertyName("response_format"u8); - writer.WriteStringValue(ResponseFormat.Value.ToString()); + content.Add(new StringContent(Language), "language"); } - if (Optional.IsDefined(Temperature)) + + if (Prompt is not null) { - writer.WritePropertyName("temperature"u8); - writer.WriteNumberValue(Temperature.Value); + content.Add(new StringContent(Prompt), "prompt"); } - if (options.Format != "W" && _serializedAdditionalRawData != null) + + if (ResponseFormat is not null) { - foreach (var item in _serializedAdditionalRawData) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } + content.Add(new StringContent(ResponseFormat.ToString()), "response_format"); } - writer.WriteEndObject(); - } - CreateTranscriptionRequest IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") + if (Temperature is not null) { - throw new FormatException($"The model {nameof(CreateTranscriptionRequest)} does not support reading '{format}' format."); + // https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#GFormatString + string value = Temperature.Value.ToString("G", CultureInfo.InvariantCulture); + content.Add(new StringContent(value), "temperature"); } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeCreateTranscriptionRequest(document.RootElement, options); - } - - internal static CreateTranscriptionRequest DeserializeCreateTranscriptionRequest(JsonElement element, ModelReaderWriterOptions options = null) - { - options ??= new ModelReaderWriterOptions("W"); - - if (element.ValueKind == JsonValueKind.Null) + string contentType = default; + if (content.Headers.ContentType is MediaTypeHeaderValue contentTypeValue) { - return null; + contentType = contentTypeValue.ToString(); } - BinaryData file = default; - CreateTranscriptionRequestModel model = default; - string language = default; - string prompt = default; - CreateTranscriptionRequestResponseFormat? responseFormat = default; - double? temperature = default; - IDictionary serializedAdditionalRawData = default; - Dictionary additionalPropertiesDictionary = new Dictionary(); - foreach (var property in element.EnumerateObject()) + + RequestOptions options = new(); + if (content.Headers.ContentLength is long contentLength) { - if (property.NameEquals("file"u8)) - { - file = BinaryData.FromBytes(property.Value.GetBytesFromBase64("D")); - continue; - } - if (property.NameEquals("model"u8)) - { - model = new CreateTranscriptionRequestModel(property.Value.GetString()); - continue; - } - if (property.NameEquals("language"u8)) - { - language = property.Value.GetString(); - continue; - } - if (property.NameEquals("prompt"u8)) - { - prompt = property.Value.GetString(); - continue; - } - if (property.NameEquals("response_format"u8)) - { - if (property.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - responseFormat = new CreateTranscriptionRequestResponseFormat(property.Value.GetString()); - continue; - } - if (property.NameEquals("temperature"u8)) - { - if (property.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - temperature = property.Value.GetDouble(); - continue; - } - if (options.Format != "W") - { - additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); - } + options.SetHeader("Content-Length", contentLength.ToString()); } - serializedAdditionalRawData = additionalPropertiesDictionary; - return new CreateTranscriptionRequest( - file, - model, - language, - prompt, - responseFormat, - temperature, - serializedAdditionalRawData); + + Stream stream = await content.ReadAsStreamAsync().ConfigureAwait(false); + return (BinaryContent.Create(stream), contentType, options); } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + private static string CreateBoundary() { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + Span chars = new char[70]; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options); - default: - throw new FormatException($"The model {nameof(CreateTranscriptionRequest)} does not support writing '{options.Format}' format."); - } - } + byte[] random = new byte[70]; + _random.NextBytes(random); - CreateTranscriptionRequest IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) - { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + // The following will sample evenly from the possible values. + // This is important to ensuring that the odds of creating a boundary + // that occurs in any content part are astronomically small. + int mask = 255 >> 2; + + Debug.Assert(_boundaryValues.Length - 1 == mask); - switch (format) + for (int i = 0; i < 70; i++) { - case "J": - { - using JsonDocument document = JsonDocument.Parse(data); - return DeserializeCreateTranscriptionRequest(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(CreateTranscriptionRequest)} does not support reading '{options.Format}' format."); + chars[i] = _boundaryValues[random[i] & mask]; } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - /// Deserializes the model from a raw response. - /// The result to deserialize the model from. - internal static CreateTranscriptionRequest FromResponse(PipelineResponse response) - { - using var document = JsonDocument.Parse(response.Content); - return DeserializeCreateTranscriptionRequest(document.RootElement); - } - - /// Convert into a Utf8JsonRequestBody. - internal virtual BinaryContent ToBinaryBody() - { - return BinaryContent.Create(this, new ModelReaderWriterOptions("W")); + return chars.ToString(); } } } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.cs index e9fe6902b..25d96a539 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionRequest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.IO; namespace OpenAI.Models { @@ -47,13 +48,15 @@ public partial class CreateTranscriptionRequest /// The audio file object (not file name) to transcribe, in one of these formats: flac, mp3, mp4, /// mpeg, mpga, m4a, ogg, wav, or webm. /// + /// The name of the file passed in . /// ID of the model to use. Only `whisper-1` is currently available. /// is null. - public CreateTranscriptionRequest(BinaryData file, CreateTranscriptionRequestModel model) + public CreateTranscriptionRequest(Stream file, string fileName, CreateTranscriptionRequestModel model) { Argument.AssertNotNull(file, nameof(file)); File = file; + FileName = fileName; Model = model; } @@ -62,6 +65,7 @@ public CreateTranscriptionRequest(BinaryData file, CreateTranscriptionRequestMod /// The audio file object (not file name) to transcribe, in one of these formats: flac, mp3, mp4, /// mpeg, mpga, m4a, ogg, wav, or webm. /// + /// The name of the file passed in . /// ID of the model to use. Only `whisper-1` is currently available. /// /// The language of the input audio. Supplying the input language in @@ -83,9 +87,10 @@ public CreateTranscriptionRequest(BinaryData file, CreateTranscriptionRequestMod /// automatically increase the temperature until certain thresholds are hit. /// /// Keeps track of any properties unknown to the library. - internal CreateTranscriptionRequest(BinaryData file, CreateTranscriptionRequestModel model, string language, string prompt, CreateTranscriptionRequestResponseFormat? responseFormat, double? temperature, IDictionary serializedAdditionalRawData) + internal CreateTranscriptionRequest(Stream file, string fileName, CreateTranscriptionRequestModel model, string language, string prompt, CreateTranscriptionRequestResponseFormat? responseFormat, double? temperature, IDictionary serializedAdditionalRawData) { File = file; + FileName = fileName; Model = model; Language = language; Prompt = prompt; @@ -116,7 +121,11 @@ internal CreateTranscriptionRequest() /// /// /// - public BinaryData File { get; } + public Stream File { get; } + /// + /// The name of the file passed in . + /// + public string FileName { get; } /// ID of the model to use. Only `whisper-1` is currently available. public CreateTranscriptionRequestModel Model { get; } /// diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs index aaf727675..e6de58390 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranscriptionResponse.Serialization.cs @@ -191,8 +191,8 @@ internal static CreateTranscriptionResponse FromResponse(PipelineResponse respon return DeserializeCreateTranscriptionResponse(document.RootElement); } - /// Convert into a Utf8JsonRequestBody. - internal virtual BinaryContent ToBinaryBody() + /// Convert into a BinaryContent. + internal virtual BinaryContent ToBinaryContent() { return BinaryContent.Create(this, new ModelReaderWriterOptions("W")); } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.Serialization.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.Serialization.cs index e77c859f0..21ddd6c23 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.Serialization.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.Serialization.cs @@ -5,179 +5,95 @@ using System; using System.ClientModel; using System.ClientModel.Primitives; -using System.Collections.Generic; -using System.Text.Json; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; namespace OpenAI.Models { - public partial class CreateTranslationRequest : IJsonModel + public partial class CreateTranslationRequest { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + private static Random _random = new(); + private static readonly char[] _boundaryValues = "0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray(); + + internal async Task<(BinaryContent, string, RequestOptions)> ToMultipartContentAsync() { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") - { - throw new FormatException($"The model {nameof(CreateTranslationRequest)} does not support writing '{format}' format."); - } + MultipartFormDataContent content = new(CreateBoundary()); - writer.WriteStartObject(); - writer.WritePropertyName("file"u8); - writer.WriteBase64StringValue(File.ToArray(), "D"); - writer.WritePropertyName("model"u8); - writer.WriteStringValue(Model.ToString()); - if (Optional.IsDefined(Prompt)) + if (FileName is not null) { - writer.WritePropertyName("prompt"u8); - writer.WriteStringValue(Prompt); + StreamContent fileContent = new StreamContent(File); + ContentDispositionHeaderValue header = new("form-data") + { + Name = "file", + FileName = FileName + }; + content.Headers.ContentDisposition = header; + content.Add(new StreamContent(File)); } - if (Optional.IsDefined(ResponseFormat)) + else { - writer.WritePropertyName("response_format"u8); - writer.WriteStringValue(ResponseFormat.Value.ToString()); + content.Add(new StreamContent(File), "file"); } - if (Optional.IsDefined(Temperature)) + + content.Add(new StringContent(Model.ToString()), "model"); + + if (Prompt is not null) { - writer.WritePropertyName("temperature"u8); - writer.WriteNumberValue(Temperature.Value); + content.Add(new StringContent(Prompt), "prompt"); } - if (options.Format != "W" && _serializedAdditionalRawData != null) + + if (ResponseFormat is not null) { - foreach (var item in _serializedAdditionalRawData) - { - writer.WritePropertyName(item.Key); -#if NET6_0_OR_GREATER - writer.WriteRawValue(item.Value); -#else - using (JsonDocument document = JsonDocument.Parse(item.Value)) - { - JsonSerializer.Serialize(writer, document.RootElement); - } -#endif - } + content.Add(new StringContent(ResponseFormat.ToString()), "response_format"); } - writer.WriteEndObject(); - } - CreateTranslationRequest IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) - { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; - if (format != "J") + if (Temperature is not null) { - throw new FormatException($"The model {nameof(CreateTranslationRequest)} does not support reading '{format}' format."); + // https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#GFormatString + string value = Temperature.Value.ToString("G", CultureInfo.InvariantCulture); + content.Add(new StringContent(value), "temperature"); } - using JsonDocument document = JsonDocument.ParseValue(ref reader); - return DeserializeCreateTranslationRequest(document.RootElement, options); - } - - internal static CreateTranslationRequest DeserializeCreateTranslationRequest(JsonElement element, ModelReaderWriterOptions options = null) - { - options ??= new ModelReaderWriterOptions("W"); - - if (element.ValueKind == JsonValueKind.Null) + string contentType = default; + if (content.Headers.ContentType is MediaTypeHeaderValue contentTypeValue) { - return null; + contentType = contentTypeValue.ToString(); } - BinaryData file = default; - CreateTranslationRequestModel model = default; - string prompt = default; - CreateTranslationRequestResponseFormat? responseFormat = default; - double? temperature = default; - IDictionary serializedAdditionalRawData = default; - Dictionary additionalPropertiesDictionary = new Dictionary(); - foreach (var property in element.EnumerateObject()) + + RequestOptions options = new(); + if (content.Headers.ContentLength is long contentLength) { - if (property.NameEquals("file"u8)) - { - file = BinaryData.FromBytes(property.Value.GetBytesFromBase64("D")); - continue; - } - if (property.NameEquals("model"u8)) - { - model = new CreateTranslationRequestModel(property.Value.GetString()); - continue; - } - if (property.NameEquals("prompt"u8)) - { - prompt = property.Value.GetString(); - continue; - } - if (property.NameEquals("response_format"u8)) - { - if (property.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - responseFormat = new CreateTranslationRequestResponseFormat(property.Value.GetString()); - continue; - } - if (property.NameEquals("temperature"u8)) - { - if (property.Value.ValueKind == JsonValueKind.Null) - { - continue; - } - temperature = property.Value.GetDouble(); - continue; - } - if (options.Format != "W") - { - additionalPropertiesDictionary.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); - } + options.SetHeader("Content-Length", contentLength.ToString()); } - serializedAdditionalRawData = additionalPropertiesDictionary; - return new CreateTranslationRequest( - file, - model, - prompt, - responseFormat, - temperature, - serializedAdditionalRawData); + + Stream stream = await content.ReadAsStreamAsync().ConfigureAwait(false); + return (BinaryContent.Create(stream), contentType, options); } - BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + private static string CreateBoundary() { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + Span chars = new char[70]; - switch (format) - { - case "J": - return ModelReaderWriter.Write(this, options); - default: - throw new FormatException($"The model {nameof(CreateTranslationRequest)} does not support writing '{options.Format}' format."); - } - } + byte[] random = new byte[70]; + _random.NextBytes(random); - CreateTranslationRequest IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) - { - var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format; + // The following will sample evenly from the possible values. + // This is important to ensuring that the odds of creating a boundary + // that occurs in any content part are astronomically small. + int mask = 255 >> 2; + + Debug.Assert(_boundaryValues.Length - 1 == mask); - switch (format) + for (int i = 0; i < 70; i++) { - case "J": - { - using JsonDocument document = JsonDocument.Parse(data); - return DeserializeCreateTranslationRequest(document.RootElement, options); - } - default: - throw new FormatException($"The model {nameof(CreateTranslationRequest)} does not support reading '{options.Format}' format."); + chars[i] = _boundaryValues[random[i] & mask]; } - } - - string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J"; - /// Deserializes the model from a raw response. - /// The result to deserialize the model from. - internal static CreateTranslationRequest FromResponse(PipelineResponse response) - { - using var document = JsonDocument.Parse(response.Content); - return DeserializeCreateTranslationRequest(document.RootElement); - } - - /// Convert into a Utf8JsonRequestBody. - internal virtual BinaryContent ToBinaryBody() - { - return BinaryContent.Create(this, new ModelReaderWriterOptions("W")); + return chars.ToString(); } } } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.cs index 781902a78..5b916b8b1 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationRequest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.IO; namespace OpenAI.Models { @@ -47,13 +48,15 @@ public partial class CreateTranslationRequest /// The audio file object (not file name) to translate, in one of these formats: flac, mp3, mp4, /// mpeg, mpga, m4a, ogg, wav, or webm. /// + /// The name of the file passed in . /// ID of the model to use. Only `whisper-1` is currently available. /// is null. - public CreateTranslationRequest(BinaryData file, CreateTranslationRequestModel model) + public CreateTranslationRequest(Stream file, string fileName, CreateTranslationRequestModel model) { Argument.AssertNotNull(file, nameof(file)); File = file; + FileName = fileName; Model = model; } @@ -62,6 +65,7 @@ public CreateTranslationRequest(BinaryData file, CreateTranslationRequestModel m /// The audio file object (not file name) to translate, in one of these formats: flac, mp3, mp4, /// mpeg, mpga, m4a, ogg, wav, or webm. /// + /// The name of the file passed in . /// ID of the model to use. Only `whisper-1` is currently available. /// /// An optional text to guide the model's style or continue a previous audio segment. The @@ -78,9 +82,10 @@ public CreateTranslationRequest(BinaryData file, CreateTranslationRequestModel m /// automatically increase the temperature until certain thresholds are hit. /// /// Keeps track of any properties unknown to the library. - internal CreateTranslationRequest(BinaryData file, CreateTranslationRequestModel model, string prompt, CreateTranslationRequestResponseFormat? responseFormat, double? temperature, IDictionary serializedAdditionalRawData) + internal CreateTranslationRequest(Stream file, string fileName, CreateTranslationRequestModel model, string prompt, CreateTranslationRequestResponseFormat? responseFormat, double? temperature, IDictionary serializedAdditionalRawData) { File = file; + FileName = fileName; Model = model; Prompt = prompt; ResponseFormat = responseFormat; @@ -110,7 +115,11 @@ internal CreateTranslationRequest() /// /// /// - public BinaryData File { get; } + public Stream File { get; } + /// + /// The name of the file passed in . + /// + public string FileName { get; } /// ID of the model to use. Only `whisper-1` is currently available. public CreateTranslationRequestModel Model { get; } /// diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationResponse.Serialization.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationResponse.Serialization.cs index 44fe6401c..fdd247b30 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationResponse.Serialization.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/Models/CreateTranslationResponse.Serialization.cs @@ -191,8 +191,8 @@ internal static CreateTranslationResponse FromResponse(PipelineResponse response return DeserializeCreateTranslationResponse(document.RootElement); } - /// Convert into a Utf8JsonRequestBody. - internal virtual BinaryContent ToBinaryBody() + /// Convert into a BinaryContent. + internal virtual BinaryContent ToBinaryContent() { return BinaryContent.Create(this, new ModelReaderWriterOptions("W")); } diff --git a/tsp-output/@azure-tools/typespec-csharp/src/Generated/OpenAIClient.cs b/tsp-output/@azure-tools/typespec-csharp/src/Generated/OpenAIClient.cs index c56780241..4d1bea49b 100644 --- a/tsp-output/@azure-tools/typespec-csharp/src/Generated/OpenAIClient.cs +++ b/tsp-output/@azure-tools/typespec-csharp/src/Generated/OpenAIClient.cs @@ -28,7 +28,7 @@ protected OpenAIClient() } /// Initializes a new instance of OpenAIClient. - /// A credential used to authenticate to an Azure Service. + /// A credential used to authenticate with the service. /// is null. public OpenAIClient(ApiKeyCredential credential) : this(new Uri("https://api.openai.com/v1"), credential, new OpenAIClientOptions()) { @@ -36,7 +36,7 @@ protected OpenAIClient() /// Initializes a new instance of OpenAIClient. /// OpenAI Endpoint. - /// A credential used to authenticate to an Azure Service. + /// A credential used to authenticate with the service. /// The options for configuring the client. /// or is null. public OpenAIClient(Uri endpoint, ApiKeyCredential credential, OpenAIClientOptions options) @@ -46,100 +46,20 @@ public OpenAIClient(Uri endpoint, ApiKeyCredential credential, OpenAIClientOptio options ??= new OpenAIClientOptions(); _keyCredential = credential; - _pipeline = ClientPipeline.Create(options, Array.Empty(), new PipelinePolicy[] { ApiKeyAuthenticationPolicy.CreateHeaderApiKeyPolicy(_keyCredential, AuthorizationHeader, AuthorizationApiKeyPrefix) }, Array.Empty()); + var authenticationPolicy = ApiKeyAuthenticationPolicy.CreateBearerAuthorizationPolicy(_keyCredential); + _pipeline = ClientPipeline.Create(options, + perCallPolicies: ReadOnlySpan.Empty, + perTryPolicies: new PipelinePolicy[] { authenticationPolicy }, + beforeTransportPolicies: ReadOnlySpan.Empty); _endpoint = endpoint; } private Audio _cachedAudio; - private Assistants _cachedAssistants; - private Chat _cachedChat; - private Completions _cachedCompletions; - private Embeddings _cachedEmbeddings; - private Files _cachedFiles; - private FineTuning _cachedFineTuning; - private Images _cachedImages; - private Messages _cachedMessages; - private ModelsOps _cachedModelsOps; - private Moderations _cachedModerations; - private Runs _cachedRuns; - private Threads _cachedThreads; /// Initializes a new instance of Audio. public virtual Audio GetAudioClient() { return Volatile.Read(ref _cachedAudio) ?? Interlocked.CompareExchange(ref _cachedAudio, new Audio(_pipeline, _keyCredential, _endpoint), null) ?? _cachedAudio; } - - /// Initializes a new instance of Assistants. - public virtual Assistants GetAssistantsClient() - { - return Volatile.Read(ref _cachedAssistants) ?? Interlocked.CompareExchange(ref _cachedAssistants, new Assistants(_pipeline, _keyCredential, _endpoint), null) ?? _cachedAssistants; - } - - /// Initializes a new instance of Chat. - public virtual Chat GetChatClient() - { - return Volatile.Read(ref _cachedChat) ?? Interlocked.CompareExchange(ref _cachedChat, new Chat(_pipeline, _keyCredential, _endpoint), null) ?? _cachedChat; - } - - /// Initializes a new instance of Completions. - public virtual Completions GetCompletionsClient() - { - return Volatile.Read(ref _cachedCompletions) ?? Interlocked.CompareExchange(ref _cachedCompletions, new Completions(_pipeline, _keyCredential, _endpoint), null) ?? _cachedCompletions; - } - - /// Initializes a new instance of Embeddings. - public virtual Embeddings GetEmbeddingsClient() - { - return Volatile.Read(ref _cachedEmbeddings) ?? Interlocked.CompareExchange(ref _cachedEmbeddings, new Embeddings(_pipeline, _keyCredential, _endpoint), null) ?? _cachedEmbeddings; - } - - /// Initializes a new instance of Files. - public virtual Files GetFilesClient() - { - return Volatile.Read(ref _cachedFiles) ?? Interlocked.CompareExchange(ref _cachedFiles, new Files(_pipeline, _keyCredential, _endpoint), null) ?? _cachedFiles; - } - - /// Initializes a new instance of FineTuning. - public virtual FineTuning GetFineTuningClient() - { - return Volatile.Read(ref _cachedFineTuning) ?? Interlocked.CompareExchange(ref _cachedFineTuning, new FineTuning(_pipeline, _keyCredential, _endpoint), null) ?? _cachedFineTuning; - } - - /// Initializes a new instance of Images. - public virtual Images GetImagesClient() - { - return Volatile.Read(ref _cachedImages) ?? Interlocked.CompareExchange(ref _cachedImages, new Images(_pipeline, _keyCredential, _endpoint), null) ?? _cachedImages; - } - - /// Initializes a new instance of Messages. - public virtual Messages GetMessagesClient() - { - return Volatile.Read(ref _cachedMessages) ?? Interlocked.CompareExchange(ref _cachedMessages, new Messages(_pipeline, _keyCredential, _endpoint), null) ?? _cachedMessages; - } - - /// Initializes a new instance of ModelsOps. - public virtual ModelsOps GetModelsOpsClient() - { - return Volatile.Read(ref _cachedModelsOps) ?? Interlocked.CompareExchange(ref _cachedModelsOps, new ModelsOps(_pipeline, _keyCredential, _endpoint), null) ?? _cachedModelsOps; - } - - /// Initializes a new instance of Moderations. - public virtual Moderations GetModerationsClient() - { - return Volatile.Read(ref _cachedModerations) ?? Interlocked.CompareExchange(ref _cachedModerations, new Moderations(_pipeline, _keyCredential, _endpoint), null) ?? _cachedModerations; - } - - /// Initializes a new instance of Runs. - public virtual Runs GetRunsClient() - { - return Volatile.Read(ref _cachedRuns) ?? Interlocked.CompareExchange(ref _cachedRuns, new Runs(_pipeline, _keyCredential, _endpoint), null) ?? _cachedRuns; - } - - /// Initializes a new instance of Threads. - public virtual Threads GetThreadsClient() - { - return Volatile.Read(ref _cachedThreads) ?? Interlocked.CompareExchange(ref _cachedThreads, new Threads(_pipeline, _keyCredential, _endpoint), null) ?? _cachedThreads; - } } }