diff --git a/Deepgram.Tests/ClientTests/PrerecordedTranscriptionTests.cs b/Deepgram.Tests/ClientTests/PrerecordedTranscriptionTests.cs index 366e7a27..3881592b 100644 --- a/Deepgram.Tests/ClientTests/PrerecordedTranscriptionTests.cs +++ b/Deepgram.Tests/ClientTests/PrerecordedTranscriptionTests.cs @@ -2,13 +2,19 @@ using Deepgram.Models; using Deepgram.Request; using Deepgram.Tests.Fakes; +using System.IO; +using System.Threading.Tasks; +using System; +using Xunit; namespace Deepgram.Tests.ClientTests { public class PrerecordedTranscriptionTests { - PrerecordedTranscriptionOptions _prerecordedTranscriptionOptions; - UrlSource _urlSource; + private readonly PrerecordedTranscriptionOptions _prerecordedTranscriptionOptions; + private readonly UrlSource _urlSource; + private readonly Faker _faker = new(); + public PrerecordedTranscriptionTests() { _prerecordedTranscriptionOptions = new PrerecordedTranscriptionOptionsFaker().Generate(); @@ -16,11 +22,12 @@ public PrerecordedTranscriptionTests() } [Fact] - public async void GetTransaction_Should_Return_PrerecordedTranscription_When_UrlSource_Present() + public async Task GetTransaction_Should_Return_PrerecordedTranscription_When_UrlSource_Present() { //Arrange var fakePrecordedTranscription = new AutoFaker().Generate(); var SUT = GetDeepgramClient(fakePrecordedTranscription); + _prerecordedTranscriptionOptions.Callback = null; //Act var result = await SUT.Transcription.Prerecorded.GetTranscriptionAsync(_urlSource, _prerecordedTranscriptionOptions); @@ -33,12 +40,13 @@ public async void GetTransaction_Should_Return_PrerecordedTranscription_When_Url } [Fact] - public async void GetTransaction_Should_Return_PrerecordedTranscription_When_StreamSource_Present() + public async Task GetTransaction_Should_Return_PrerecordedTranscription_When_StreamSource_Present() { //Arrange var fakePrecordedTranscription = new AutoFaker().Generate(); var SUT = GetDeepgramClient(fakePrecordedTranscription); var fakeStreamSource = new StreamSourceFaker().Generate(); + _prerecordedTranscriptionOptions.Callback = null; //Act var result = await SUT.Transcription.Prerecorded.GetTranscriptionAsync(fakeStreamSource, _prerecordedTranscriptionOptions); @@ -51,7 +59,7 @@ public async void GetTransaction_Should_Return_PrerecordedTranscription_When_Str } [Fact] - public async void Should_Return_A_Summary_Short_When_Summarize_Set_To_v2() + public async Task Should_Return_A_Summary_Short_When_Summarize_Set_To_v2() { //Arrange var responseObject = new AutoFaker().Generate(); @@ -74,25 +82,20 @@ public async void Should_Return_A_Summary_Short_When_Summarize_Set_To_v2() } - - [Theory] [InlineData(true)] [InlineData(false)] - public async void Should_Return_A_Summary_Short_When_Summarize_Set_To_bool(bool value) + public async Task Should_Return_A_Summary_Short_When_Summarize_Set_To_bool(bool value) { //Arrange var responseObject = new AutoFaker().Generate(); var SUT = GetDeepgramClient(responseObject); responseObject.Results.Summary.Short = null; - var client = MockHttpClient.CreateHttpClientWithResult(responseObject); var fakeOptions = new PrerecordedTranscriptionOptions() { Summarize = value }; - SUT.Transcription.Prerecorded.ApiRequest = new ApiRequest(client); - //Act var result = await SUT.Transcription.Prerecorded.GetTranscriptionAsync(_urlSource, fakeOptions); @@ -103,6 +106,83 @@ public async void Should_Return_A_Summary_Short_When_Summarize_Set_To_bool(bool } + [Fact] + public async Task Should_Return_RequestId_When_Async_Transcription_From_Url_Requested() + { + //Arrange + var responseObject = new AutoFaker().Generate(); + responseObject.RequestId = Guid.NewGuid(); + _prerecordedTranscriptionOptions.Callback = null; + + var SUT = GetDeepgramClient(responseObject); + + // Act + var result = await SUT.Transcription.Prerecorded.GetTranscriptionAsync(_urlSource, _faker.Internet.Url(), _prerecordedTranscriptionOptions); + + // Assert + + Assert.Equal(responseObject.RequestId, result.RequestId); + } + + [Fact] + public async Task Should_Throw_When_Async_Transcription_From_Url_Has_No_Callback() + { + // Arrange + var responseObject = new AutoFaker().Generate(); + _prerecordedTranscriptionOptions.Callback = null; + + var SUT = GetDeepgramClient(responseObject); + + var exception = await Assert.ThrowsAsync(async () => + await SUT.Transcription.Prerecorded.GetTranscriptionAsync(_urlSource, + null, _prerecordedTranscriptionOptions)); + + Assert.Matches("CallbackUrl is required for this call. Please set the callbackUrl parameter or the callbackUrl property in the options object.", exception.Message); + } + + [Fact] + public async Task Should_Return_RequestId_When_Async_Transcription_From_Stream_Requested() + { + // Arrange + var responseObject = new AutoFaker().Generate(); + responseObject.RequestId = Guid.NewGuid(); + _prerecordedTranscriptionOptions.Callback = null; + + var SUT = GetDeepgramClient(responseObject); + + using var stream = new MemoryStream(_faker.Random.Bytes(100)); + + // Act + var result = await SUT.Transcription.Prerecorded.GetTranscriptionAsync(new StreamSource(stream, "audio/wav"), + _faker.Internet.Url(), _prerecordedTranscriptionOptions); + + // Assert + Assert.Equal(responseObject.RequestId, result.RequestId); + } + + [Fact] + public async Task Should_Throw_When_Async_Transcription_From_Stream_Has_No_Callback() + { + // Arrange + var responseObject = new AutoFaker().Generate(); + responseObject.RequestId = Guid.NewGuid(); + _prerecordedTranscriptionOptions.Callback = null; + + var httpClient = MockHttpClient.CreateHttpClientWithResult(responseObject); + + var SUT = GetDeepgramClient(responseObject); + SUT.Transcription.Prerecorded.ApiRequest = new ApiRequest(httpClient); + + using var stream = new MemoryStream(_faker.Random.Bytes(100)); + + // Act + var exception = await Assert.ThrowsAsync(async () => + await SUT.Transcription.Prerecorded.GetTranscriptionAsync(_urlSource, + null, _prerecordedTranscriptionOptions)); + + // Assert + Assert.Matches("CallbackUrl is required for this call. Please set the callbackUrl parameter or the callbackUrl property in the options object.", exception.Message); + } private static DeepgramClient GetDeepgramClient(T returnObject) { diff --git a/Deepgram.Tests/Fakers/PrerecordedTranscriptionOptionsFaker.cs b/Deepgram.Tests/Fakers/PrerecordedTranscriptionOptionsFaker.cs index e5bb3fda..88903140 100644 --- a/Deepgram.Tests/Fakers/PrerecordedTranscriptionOptionsFaker.cs +++ b/Deepgram.Tests/Fakers/PrerecordedTranscriptionOptionsFaker.cs @@ -1,7 +1,8 @@ using System.Linq; using AutoBogus; -using Bogus.Extensions; using Deepgram.Models; +using Bogus.Extensions; + namespace Deepgram.Tests.Fakers { public class PrerecordedTranscriptionOptionsFaker : AutoFaker diff --git a/Deepgram.Tests/UtilitiesTests/QueryParameterUtilTests.cs b/Deepgram.Tests/UtilitiesTests/QueryParameterUtilTests.cs index 05b9c22b..46178903 100644 --- a/Deepgram.Tests/UtilitiesTests/QueryParameterUtilTests.cs +++ b/Deepgram.Tests/UtilitiesTests/QueryParameterUtilTests.cs @@ -66,7 +66,7 @@ public void GetParameters_Should_Return_String_When_Passing_Decimal_Parameter() //Assert Assert.NotNull(result); - Assert.Contains($"utt_split={prerecordedTranscriptionOptions.UtteranceSplit}", result); + Assert.Contains($"utt_split={System.Web.HttpUtility.UrlEncode(prerecordedTranscriptionOptions.UtteranceSplit.ToString())}", result); } [Fact] diff --git a/Deepgram/Clients/PrerecordedTranscriptionClient.cs b/Deepgram/Clients/PrerecordedTranscriptionClient.cs index a322c38b..00411eba 100644 --- a/Deepgram/Clients/PrerecordedTranscriptionClient.cs +++ b/Deepgram/Clients/PrerecordedTranscriptionClient.cs @@ -1,4 +1,5 @@ -using System.Net.Http; +using System; +using System.Net.Http; using System.Threading.Tasks; using Deepgram.Interfaces; using Deepgram.Models; @@ -8,40 +9,78 @@ namespace Deepgram.Clients public class PrerecordedTranscriptionClient : BaseClient, IPrerecordedTranscriptionClient { public PrerecordedTranscriptionClient(Credentials credentials) : base(credentials) { } - /// - /// Submits a request to the Deepgram API to transcribe prerecorded audio - /// - /// Url source to send for transcription - /// Feature options for the transcription - /// Transcription of the provided audio + /// public async Task GetTranscriptionAsync(UrlSource source, PrerecordedTranscriptionOptions options) { var req = RequestMessageBuilder.CreateHttpRequestMessage( HttpMethod.Post, - "listen", - Credentials, - source, - options); + "listen", + Credentials, + source, + options); return await ApiRequest.SendHttpRequestAsync(req); } - /// - /// Submits a request to the Deepgram API to transcribe prerecorded audio - /// - /// Audio source to send for transcription - /// Feature options for the transcription - /// Transcription of the provided audio + /// public async Task GetTranscriptionAsync(StreamSource source, PrerecordedTranscriptionOptions options) { var req = RequestMessageBuilder.CreateStreamHttpRequestMessage( HttpMethod.Post, - "listen", - Credentials, - source, - options); + "listen", + Credentials, + source, + options); return await ApiRequest.SendHttpRequestAsync(req); } + + /// + public async Task GetTranscriptionAsync(UrlSource source, string callbackUrl, PrerecordedTranscriptionOptions options) + { + if (!String.IsNullOrEmpty(options.Callback) && !String.IsNullOrEmpty(callbackUrl)) + { + throw new System.ArgumentException("CallbackUrl is already set in the options object. Please use one or the other."); + } + + if (!String.IsNullOrEmpty(callbackUrl)) + { + options.Callback = callbackUrl; + } + + _ = options.Callback ?? throw new System.ArgumentException("CallbackUrl is required for this call. Please set the callbackUrl parameter or the callbackUrl property in the options object."); + + var req = RequestMessageBuilder.CreateHttpRequestMessage( + HttpMethod.Post, + "listen", + Credentials, + source, + options); + return await ApiRequest.SendHttpRequestAsync(req); + } + + /// + public async Task GetTranscriptionAsync(StreamSource source, string callbackUrl, PrerecordedTranscriptionOptions options) + { + if (!String.IsNullOrEmpty(options.Callback) && !String.IsNullOrEmpty(callbackUrl)) + { + throw new System.ArgumentException("CallbackUrl is already set in the options object. Please use one or the other."); + } + + if( !String.IsNullOrEmpty(callbackUrl)) { + options.Callback = callbackUrl; + } + + _ = options.Callback ?? throw new System.ArgumentException("CallbackUrl is required for this call. Please set the callbackUrl parameter or the callbackUrl property in the options object."); + + + var req = RequestMessageBuilder.CreateStreamHttpRequestMessage( + HttpMethod.Post, + "listen", + Credentials, + source, + options); + return await ApiRequest.SendHttpRequestAsync(req); + } } } diff --git a/Deepgram/DeepgramClient.cs b/Deepgram/DeepgramClient.cs index e920e681..9a27cb1f 100644 --- a/Deepgram/DeepgramClient.cs +++ b/Deepgram/DeepgramClient.cs @@ -19,7 +19,6 @@ public DeepgramClient() : this(null) { } public DeepgramClient(Credentials credentials) { - Initialize(credentials); } diff --git a/Deepgram/Interfaces/IPrerecordedTranscriptionClient.cs b/Deepgram/Interfaces/IPrerecordedTranscriptionClient.cs index 101da1b1..d90ddf34 100644 --- a/Deepgram/Interfaces/IPrerecordedTranscriptionClient.cs +++ b/Deepgram/Interfaces/IPrerecordedTranscriptionClient.cs @@ -20,5 +20,24 @@ public interface IPrerecordedTranscriptionClient : IBaseClient /// Feature options for the transcription /// Transcription of the provided audio Task GetTranscriptionAsync(StreamSource source, PrerecordedTranscriptionOptions options); + + /// + /// Asynchronously submits a request to the Deepgram API to transcribe prerecorded audio + /// + /// Url source to send for transcription + /// Url to send the transcription results to + /// Feature options for the transcription + /// Transcription of the provided audio + Task GetTranscriptionAsync(UrlSource source, string callbackUrl, PrerecordedTranscriptionOptions options); + + /// + /// Asynchronously submits a request to the Deepgram API to transcribe prerecorded audio + /// + /// Audio source to send for transcription + /// Url to send the transcription results to + /// Feature options for the transcription + /// Transcription of the provided audio + Task GetTranscriptionAsync(StreamSource source, string callbackUrl, PrerecordedTranscriptionOptions options); + } } diff --git a/Deepgram/Models/PrerecordedTranscriptionCallbackResult.cs b/Deepgram/Models/PrerecordedTranscriptionCallbackResult.cs new file mode 100644 index 00000000..ada9600b --- /dev/null +++ b/Deepgram/Models/PrerecordedTranscriptionCallbackResult.cs @@ -0,0 +1,15 @@ +using System; +using Newtonsoft.Json; + +namespace Deepgram.Models +{ + public class PrerecordedTranscriptionCallbackResult + + { + /// + /// Id of the request. + /// + [JsonProperty("request_id")] + public Guid RequestId { get; set; } + } +} diff --git a/Deepgram/Models/PrerecordedTranscriptionOptions.cs b/Deepgram/Models/PrerecordedTranscriptionOptions.cs index 747895c0..f21abfbe 100644 --- a/Deepgram/Models/PrerecordedTranscriptionOptions.cs +++ b/Deepgram/Models/PrerecordedTranscriptionOptions.cs @@ -162,7 +162,7 @@ public class PrerecordedTranscriptionOptions /// Callback URL to provide if you would like your submitted audio to be processed asynchronously. /// When passed, Deepgram will immediately respond with a request_id. /// - [JsonProperty("callback")] + [JsonProperty("callback"), Obsolete("This parameter has been replaced with the callback argument to GetTranscriptionAsync and may be removed at a later date")] public string Callback { get; set; } = null; ///