diff --git a/README.md b/README.md index d993087..77595b9 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,6 @@ while(page.PageDetails.PrevUrl != null)
Delete a transcript - ```csharp var transcript = await client.Transcripts.DeleteAsync(transcript.Id); ``` diff --git a/src/AssemblyAI.IntegrationTests/TranscriptsClientTests.cs b/src/AssemblyAI.IntegrationTests/TranscriptsClientTests.cs index 5f6c34a..a86aa35 100644 --- a/src/AssemblyAI.IntegrationTests/TranscriptsClientTests.cs +++ b/src/AssemblyAI.IntegrationTests/TranscriptsClientTests.cs @@ -217,7 +217,7 @@ public async Task Should_Transcribe_Using_Stream_With_Dispose() var testFilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "nbc.mp3"); var stream = File.OpenRead(testFilePath); - var transcript = await client.Transcripts.TranscribeAsync(stream, disposeStream: true).ConfigureAwait(false); + var transcript = await client.Transcripts.TranscribeAsync(stream, disposeStream: true, new TranscriptOptionalParams()).ConfigureAwait(false); Assert.That(transcript, Is.Not.Null); Assert.Multiple(() => diff --git a/src/AssemblyAI/AssemblyAIClient.cs b/src/AssemblyAI/AssemblyAIClient.cs index ef658a0..6f14267 100644 --- a/src/AssemblyAI/AssemblyAIClient.cs +++ b/src/AssemblyAI/AssemblyAIClient.cs @@ -8,16 +8,28 @@ namespace AssemblyAI; +/// +/// The client to interact with the AssemblyAI API. +/// public class AssemblyAIClient { + /// public FilesClient Files { get; private init; } + /// public ExtendedTranscriptsClient Transcripts { get; private init; } + /// public RealtimeClient Realtime { get; private init; } + /// public LemurClient Lemur { get; private init; } + /// + /// Create a new instance of the class. + /// + /// Your AssemblyAI API key + /// Thrown if apiKey is null or empty. public AssemblyAIClient(string apiKey) : this(new ClientOptions { ApiKey = apiKey @@ -25,6 +37,11 @@ public AssemblyAIClient(string apiKey) : this(new ClientOptions { } + /// + /// Create a new instance of the class. + /// + /// The AssemblyAI client options + /// Thrown if ClientOptions.ApiKey is null or empty. public AssemblyAIClient(ClientOptions clientOptions) { if (string.IsNullOrEmpty(clientOptions.ApiKey)) diff --git a/src/AssemblyAI/Core/CustomConstants.cs b/src/AssemblyAI/Core/CustomConstants.cs index d2fd139..697b545 100644 --- a/src/AssemblyAI/Core/CustomConstants.cs +++ b/src/AssemblyAI/Core/CustomConstants.cs @@ -2,5 +2,9 @@ namespace AssemblyAI.Core; internal static class CustomConstants { + /// + /// This is used for the AssemblyAI User-Agent. + /// If you update this, make sure to also update the version numbers in AssemblyAI.csproj + /// internal const string Version = "1.1.0"; } \ No newline at end of file diff --git a/src/AssemblyAI/Core/JsonConfiguration.cs b/src/AssemblyAI/Core/JsonConfiguration.cs index 8c9384f..3d8609b 100644 --- a/src/AssemblyAI/Core/JsonConfiguration.cs +++ b/src/AssemblyAI/Core/JsonConfiguration.cs @@ -5,8 +5,14 @@ namespace AssemblyAI.Core; +/// +/// The JSON options used by the AssemblyAI SDK. +/// internal static class JsonOptions { + /// + /// The JSON options used by the AssemblyAI SDK. + /// internal static readonly JsonSerializerOptions JsonSerializerOptions; static JsonOptions() @@ -24,13 +30,28 @@ static JsonOptions() } } +/// +/// Utilities class for JSON serialization and deserialization. +/// internal static class JsonUtils { + /// + /// Serialize an object to JSON using the AssemblyAI SDK's JSON options. + /// + /// Object to serialize + /// Type of the object to serialize + /// The object serialized as JSON internal static string Serialize(T obj) { return JsonSerializer.Serialize(obj, JsonOptions.JsonSerializerOptions); } + /// + /// Deserialize a JSON string to an object using the AssemblyAI SDK's JSON options. + /// + /// The JSON string + /// The type to deserialize the JSON to + /// The deserialized object of type T internal static T Deserialize(string json) { return JsonSerializer.Deserialize(json, JsonOptions.JsonSerializerOptions)!; diff --git a/src/AssemblyAI/Core/Public/ApiException.cs b/src/AssemblyAI/Core/Public/ApiException.cs index 932e331..a09b11f 100644 --- a/src/AssemblyAI/Core/Public/ApiException.cs +++ b/src/AssemblyAI/Core/Public/ApiException.cs @@ -35,6 +35,11 @@ internal ApiException(string message, int statusCode, object body) } // TODO: Remove when Fern generator can set this property + /// + /// Serialize the HTTP response body to a string. + /// + /// The HTTP response body + /// The serialized HTTP response body private static string GetResponseContentFromBody(object body) { return body switch @@ -45,6 +50,12 @@ private static string GetResponseContentFromBody(object body) }; } + /// + /// Retrieves the error message from the JSON body of the response. + /// + /// The default error message to fallback to + /// The HTTP response body + /// The error message private static string GetMessageFromJsonBody(string message, object body) { if (body is not string stringBody) return message; diff --git a/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs b/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs index 148f07b..9bdec3e 100644 --- a/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs +++ b/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs @@ -1,6 +1,13 @@ +// ReSharper disable CheckNamespace namespace AssemblyAI; -public class AssemblyAIClientEnvironment +/// +/// Available AssemblyAI API environments +/// +public static class AssemblyAIClientEnvironment { - public static string Default = "https://api.assemblyai.com"; + /// + /// The default base URL for the AssemblyAI API. + /// + public const string Default = "https://api.assemblyai.com"; } diff --git a/src/AssemblyAI/Core/Public/ClientOptions.cs b/src/AssemblyAI/Core/Public/ClientOptions.cs index 883e38b..8241f7a 100644 --- a/src/AssemblyAI/Core/Public/ClientOptions.cs +++ b/src/AssemblyAI/Core/Public/ClientOptions.cs @@ -1,8 +1,6 @@ -using System; using System.Net.Http; using AssemblyAI.Core; - -#nullable enable +// ReSharper disable CheckNamespace namespace AssemblyAI; @@ -16,7 +14,7 @@ public partial class ClientOptions /// /// The http client used to make requests. /// - public HttpClient HttpClient { get; set; } = new HttpClient(); + public HttpClient HttpClient { get; set; } = new(); /// /// The amount to retry sending the HTTP request if it fails. diff --git a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs index 53f1752..291f27b 100644 --- a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs +++ b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs @@ -1,8 +1,12 @@ +// ReSharper disable PartialTypeWithSinglePart // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global // ReSharper disable CheckNamespace namespace AssemblyAI; +/// +/// The options for the AssemblyAI client. +/// public partial class ClientOptions { /// diff --git a/src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs b/src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs new file mode 100644 index 0000000..7dbbd7f --- /dev/null +++ b/src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs @@ -0,0 +1,9 @@ +// ReSharper disable CheckNamespace +// ReSharper disable ClassNeverInstantiated.Global + +namespace AssemblyAI; + +/// +/// The options for one or multiple requests to the AssemblyAI API. +/// +public partial class RequestOptions; diff --git a/src/AssemblyAI/DependencyInjectionExtensions.cs b/src/AssemblyAI/DependencyInjectionExtensions.cs index 4d22e96..f7c1026 100644 --- a/src/AssemblyAI/DependencyInjectionExtensions.cs +++ b/src/AssemblyAI/DependencyInjectionExtensions.cs @@ -6,10 +6,19 @@ namespace AssemblyAI; +/// +/// Extensions to add the AssemblyAI client to the service collection. +/// public static class DependencyInjectionExtensions { private const string AssemblyAIHttpClientName = "AssemblyAI"; + /// + /// Add the AssemblyAI client to the service collection. + /// The AssemblyAI options are configured using the "AssemblyAI" section. + /// + /// The service collection + /// The service collection public static IServiceCollection AddAssemblyAIClient(this IServiceCollection services) { var optionsBuilder = services.AddOptions(); @@ -19,6 +28,12 @@ public static IServiceCollection AddAssemblyAIClient(this IServiceCollection ser return services; } + /// + /// Add the AssemblyAI client to the service collection. + /// + /// The service collection + /// The section where the AssemblyAI options are configured. + /// The service collection public static IServiceCollection AddAssemblyAIClient( this IServiceCollection services, IConfiguration namedConfigurationSection @@ -31,13 +46,19 @@ IConfiguration namedConfigurationSection return services; } + /// + /// Add the AssemblyAI client to the service collection. + /// + /// The service collection + /// Configure the client options using this callback. + /// The service collection public static IServiceCollection AddAssemblyAIClient( this IServiceCollection services, Action configureOptions ) => AddAssemblyAIClient(services, (_, options) => configureOptions(options)); - + /// public static IServiceCollection AddAssemblyAIClient( this IServiceCollection services, Action configureOptions @@ -50,7 +71,12 @@ Action configureOptions return services; } - + /// + /// Add the AssemblyAI client to the service collection. + /// + /// The service collection + /// The AssemblyAI client options. + /// The service collection public static IServiceCollection AddAssemblyAIClient( this IServiceCollection services, ClientOptions options diff --git a/src/AssemblyAI/EnumConverter.cs b/src/AssemblyAI/EnumConverter.cs index dbf44e7..6384bd2 100644 --- a/src/AssemblyAI/EnumConverter.cs +++ b/src/AssemblyAI/EnumConverter.cs @@ -2,6 +2,9 @@ namespace AssemblyAI; +/// +/// Convert an AssemblyAI enum to a string and vice versa. +/// public static class EnumConverter { /// diff --git a/src/AssemblyAI/Event.cs b/src/AssemblyAI/Event.cs index e3b1c82..761247a 100644 --- a/src/AssemblyAI/Event.cs +++ b/src/AssemblyAI/Event.cs @@ -27,16 +27,24 @@ internal async Task RaiseEvent(T eventObject) } } + /// + /// Subscribe to the event + /// public void Subscribe(Action eventHandler) { _subscribers.Add(eventHandler); } + /// public void Subscribe(Func eventHandler) { _subscribersAsync.Add(eventHandler); } + /// + /// Unsubscribe from the event + /// + /// public void Unsubscribe(Action eventHandler) { if (_subscribers.Contains(eventHandler)) @@ -45,6 +53,7 @@ public void Unsubscribe(Action eventHandler) } } + /// public void Unsubscribe(Func eventHandler) { if (_subscribersAsync.Contains(eventHandler)) @@ -53,11 +62,18 @@ public void Unsubscribe(Func eventHandler) } } + /// + /// Unsubscribe all event handlers + /// public void UnsubscribeAll() { _subscribers.Clear(); _subscribersAsync.Clear(); } - + + /// + /// Dispose of the event. + /// Unsubscribes all event handlers. + /// public void Dispose() => UnsubscribeAll(); } \ No newline at end of file diff --git a/src/AssemblyAI/Files/ExtendedFilesClient.cs b/src/AssemblyAI/Files/ExtendedFilesClient.cs index 0fe73bc..6a37b3e 100644 --- a/src/AssemblyAI/Files/ExtendedFilesClient.cs +++ b/src/AssemblyAI/Files/ExtendedFilesClient.cs @@ -1,10 +1,17 @@ namespace AssemblyAI.Files; +/// +/// Client to upload files to the AssemblyAI API. +/// public partial class FilesClient { /// /// Upload a media file to AssemblyAI's servers. /// + /// The local file to upload + /// The HTTP request options + /// + /// File uploaded to AssemblyAI public async Task UploadAsync( FileInfo audioFile, RequestOptions? options = null, @@ -23,6 +30,11 @@ public async Task UploadAsync( /// /// Upload a media file to AssemblyAI's servers. /// + /// The file stream to upload + /// Dispose the stream ASAP + /// The HTTP request options + /// + /// File uploaded to AssemblyAI public async Task UploadAsync( Stream stream, bool disposeStream, diff --git a/src/AssemblyAI/Lemur/ExtendedLemurClient.cs b/src/AssemblyAI/Lemur/ExtendedLemurClient.cs new file mode 100644 index 0000000..1a7b4ae --- /dev/null +++ b/src/AssemblyAI/Lemur/ExtendedLemurClient.cs @@ -0,0 +1,6 @@ +namespace AssemblyAI.Lemur; + +/// +/// The client to interact with the AssemblyAI LeMUR API. +/// +public partial class LemurClient; diff --git a/src/AssemblyAI/Realtime/ExtendedRealtimeClient.cs b/src/AssemblyAI/Realtime/ExtendedRealtimeClient.cs index 873e5f8..1bf4cac 100644 --- a/src/AssemblyAI/Realtime/ExtendedRealtimeClient.cs +++ b/src/AssemblyAI/Realtime/ExtendedRealtimeClient.cs @@ -2,6 +2,10 @@ namespace AssemblyAI.Realtime; +/// +/// The client to interact with the AssemblyAI Realtime HTTP API. +/// To interact with the Realtime WebSocket API, use the class. +/// public partial class RealtimeClient { /// diff --git a/src/AssemblyAI/Realtime/RealtimeTranscriber.cs b/src/AssemblyAI/Realtime/RealtimeTranscriber.cs index f0052a2..7d9cbb5 100644 --- a/src/AssemblyAI/Realtime/RealtimeTranscriber.cs +++ b/src/AssemblyAI/Realtime/RealtimeTranscriber.cs @@ -18,13 +18,20 @@ public enum RealtimeTranscriberStatus Disconnecting } +/// +/// Transcribes audio in real-time using AssemblyAI's real-time transcription service. +/// public sealed class RealtimeTranscriber : IAsyncDisposable, IDisposable, INotifyPropertyChanged { private readonly RealtimeTranscriberOptions _options; private WebSocket? _socket; private TaskCompletionSource? _sessionTerminatedTaskCompletionSource; + private SessionInformation? _sessionInformation; private RealtimeTranscriberStatus _status; + /// + /// The status of the real-time transcriber. + /// public RealtimeTranscriberStatus Status { get => _status; @@ -96,21 +103,57 @@ public bool DisablePartialTranscripts set => _options.DisablePartialTranscripts = value; } + /// + /// The event raised when the real-time transcription session begins. + /// public readonly Event SessionBegins = new(); + + /// + /// The event raised when a partial transcript is received. + /// public readonly Event PartialTranscriptReceived = new(); + + /// + /// The event raised when a final transcript is received. + /// public readonly Event FinalTranscriptReceived = new(); + + /// + /// The event raised when a partial or final transcript is received. + /// public readonly Event TranscriptReceived = new(); + + /// + /// The event raised when session information is received, right before the session is terminated. + /// public readonly Event SessionInformationReceived = new(); + + /// + /// The event raised when an error message is received. + /// public readonly Event ErrorReceived = new(); + + /// + /// The event raised when an exception occurs while listening for WebSocket messages. + /// public readonly Event ExceptionOccurred = new(); + + /// + /// The event raised when the connection with the real-time service is closed. + /// public readonly Event Closed = new(); - private SessionInformation? _sessionInformation; - public RealtimeTranscriber() + /// + /// Create a new instance of the real-time transcriber. + /// + public RealtimeTranscriber() : this(new RealtimeTranscriberOptions()) { - _options = new RealtimeTranscriberOptions(); } + /// + /// Create a new instance of the real-time transcriber. + /// + /// The options for the real-time transcription service. public RealtimeTranscriber(RealtimeTranscriberOptions options) { _options = options; @@ -293,6 +336,9 @@ private void OnSessionTerminated() _sessionTerminatedTaskCompletionSource?.TrySetResult(_sessionInformation!); } + /// + /// The reason phrases for the close codes. + /// private readonly Dictionary _closeCodeErrorMessages = new() { { 4000, "Sample rate must be a positive integer" }, @@ -317,6 +363,11 @@ private void OnSessionTerminated() { 4104, "Could not parse word boost parameter" } }; + /// + /// Method called when the connection is closed. Calls the Closed event. + /// + /// + /// private async Task OnClosed(int? code, string? reason) { Status = RealtimeTranscriberStatus.Disconnected; @@ -501,8 +552,15 @@ await _sessionTerminatedTaskCompletionSource!.Task Status = RealtimeTranscriberStatus.Disconnected; } + /// + /// PropertyChanged event is called when a property is changed. + /// public event PropertyChangedEventHandler? PropertyChanged; + /// + /// Raises the PropertyChanged event. + /// + /// The property name that's changed. private void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); @@ -523,6 +581,13 @@ private bool SetField(ref T field, T value, [CallerMemberName] string? proper /// public sealed class ClosedEventArgs { + /// + /// The close event code. + /// public int? Code { get; internal set; } + + /// + /// The close event reason phrase. + /// public string? Reason { get; internal set; } } \ No newline at end of file diff --git a/src/AssemblyAI/Realtime/RealtimeTranscriberOptions.cs b/src/AssemblyAI/Realtime/RealtimeTranscriberOptions.cs index 145f4eb..2d12b19 100644 --- a/src/AssemblyAI/Realtime/RealtimeTranscriberOptions.cs +++ b/src/AssemblyAI/Realtime/RealtimeTranscriberOptions.cs @@ -1,5 +1,8 @@ namespace AssemblyAI.Realtime; +/// +/// The options for the real-time transcriber. +/// public sealed class RealtimeTranscriberOptions { /// diff --git a/src/AssemblyAI/Transcripts/ExtendedTranscriptsClient.cs b/src/AssemblyAI/Transcripts/ExtendedTranscriptsClient.cs index c7f9efa..95da496 100644 --- a/src/AssemblyAI/Transcripts/ExtendedTranscriptsClient.cs +++ b/src/AssemblyAI/Transcripts/ExtendedTranscriptsClient.cs @@ -9,6 +9,9 @@ namespace AssemblyAI.Transcripts; +/// +/// The client to interact with the AssemblyAI Transcripts API. +/// public class ExtendedTranscriptsClient : TranscriptsClient { private readonly RawClient _client; @@ -20,12 +23,27 @@ internal ExtendedTranscriptsClient(RawClient client, AssemblyAIClient assemblyAI _assemblyAIClient = assemblyAIClient; } + /// + /// Create a transcript from a local file. + /// + /// The audio file to transcribe + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public Task SubmitAsync( FileInfo audioFile, RequestOptions? options = null, CancellationToken cancellationToken = default ) => SubmitAsync(audioFile, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Create a transcript from a local file. + /// + /// The audio file to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public async Task SubmitAsync( FileInfo audioFile, TranscriptOptionalParams transcriptParams, @@ -38,12 +56,27 @@ public async Task SubmitAsync( return await SubmitAsync(uploadedFile, transcriptParams, options, cancellationToken).ConfigureAwait(false); } + /// + /// Create a transcript from a file stream. + /// + /// The audio file stream to transcribe + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public Task SubmitAsync( Stream audioFileStream, RequestOptions? options = null, CancellationToken cancellationToken = default ) => SubmitAsync(audioFileStream, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Create a transcript from a file stream. + /// + /// The audio file stream to transcribe + /// Dispose the stream as soon as possible + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public Task SubmitAsync( Stream audioFileStream, bool disposeStream, @@ -51,6 +84,14 @@ public Task SubmitAsync( CancellationToken cancellationToken = default ) => SubmitAsync(audioFileStream, disposeStream, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Create a transcript from a file stream. + /// + /// The audio file stream to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public Task SubmitAsync( Stream audioFileStream, TranscriptOptionalParams transcriptParams, @@ -58,6 +99,16 @@ public Task SubmitAsync( CancellationToken cancellationToken = default ) => SubmitAsync(audioFileStream, false, transcriptParams, options, cancellationToken); + + /// + /// Create a transcript from a file stream. + /// + /// The audio file stream to transcribe + /// Dispose the stream as soon as possible + /// The transcript parameters + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public async Task SubmitAsync( Stream audioFileStream, bool disposeStream, @@ -72,12 +123,27 @@ public async Task SubmitAsync( return await SubmitAsync(fileUpload, transcriptParams, options, cancellationToken).ConfigureAwait(false); } + /// + /// Create a transcript from an audio file URI. + /// + /// The URI to the audio file to transcribe + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public Task SubmitAsync( Uri audioFileUrl, RequestOptions? options = null, CancellationToken cancellationToken = default ) => SubmitAsync(audioFileUrl, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Create a transcript from an audio file URI. + /// + /// The URI to the audio file to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public async Task SubmitAsync( Uri audioFileUrl, TranscriptOptionalParams transcriptParams, @@ -89,12 +155,27 @@ public async Task SubmitAsync( .ConfigureAwait(false); } + /// + /// Create a transcript from a file uploaded to AssemblyAI. + /// + /// The file uploaded to AssemblyAI + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public Task SubmitAsync( UploadedFile file, RequestOptions? options = null, CancellationToken cancellationToken = default ) => SubmitAsync(file, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Create a transcript from a file uploaded to AssemblyAI. + /// + /// The file uploaded to AssemblyAI + /// The transcript parameters + /// HTTP request options + /// + /// Returns a task that resolves to a queued transcript public async Task SubmitAsync( UploadedFile file, TranscriptOptionalParams transcriptParams, @@ -106,12 +187,27 @@ public async Task SubmitAsync( .ConfigureAwait(false); } + /// + /// Transcribe a local file + /// + /// The local file to transcribe + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( FileInfo audioFile, RequestOptions? options = null, CancellationToken cancellationToken = default ) => TranscribeAsync(audioFile, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Transcribe a local file + /// + /// The local file to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public async Task TranscribeAsync( FileInfo audioFile, TranscriptOptionalParams transcriptParams, @@ -128,12 +224,27 @@ public async Task TranscribeAsync( .ConfigureAwait(false); } + /// + /// Transcribe a file stream. + /// + /// The audio file stream to transcribe + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( Stream audioFileStream, RequestOptions? options = null, CancellationToken cancellationToken = default ) => TranscribeAsync(audioFileStream, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Transcribe a file stream. + /// + /// The audio file stream to transcribe + /// Dispose the stream as soon as possible + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( Stream audioFileStream, bool disposeStream, @@ -141,6 +252,14 @@ public Task TranscribeAsync( CancellationToken cancellationToken = default ) => TranscribeAsync(audioFileStream, disposeStream, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Transcribe a file stream. + /// + /// The audio file stream to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public async Task TranscribeAsync( Stream audioFileStream, TranscriptOptionalParams transcriptParams, @@ -154,6 +273,15 @@ public async Task TranscribeAsync( .ConfigureAwait(false); } + /// + /// Transcribe a file stream. + /// + /// The audio file stream to transcribe + /// The transcript parameters + /// Dispose the stream as soon as possible + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public async Task TranscribeAsync( Stream audioFileStream, bool disposeStream, @@ -172,12 +300,27 @@ public async Task TranscribeAsync( return await TranscribeAsync(uploadedFile, transcriptParams, options, cancellationToken).ConfigureAwait(false); } + /// + /// Transcribe an audio file via its public URI. + /// + /// The URI to the audio file to transcribe + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( Uri audioFileUrl, RequestOptions? options = null, CancellationToken cancellationToken = default ) => TranscribeAsync(audioFileUrl, new TranscriptOptionalParams(), options, cancellationToken); + /// + /// Transcribe an audio file via its public URI. + /// + /// The URI to the audio file to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( Uri audioFileUrl, TranscriptOptionalParams transcriptParams, @@ -185,12 +328,28 @@ public Task TranscribeAsync( CancellationToken cancellationToken = default ) => TranscribeAsync(CreateParams(audioFileUrl, transcriptParams), options, cancellationToken); + /// + /// Transcribe a file uploaded to AssemblyAI. + /// + /// The file uploaded to AssemblyAI to transcribe + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( UploadedFile file, RequestOptions? options = null, CancellationToken cancellationToken = default ) => TranscribeAsync(file, new TranscriptOptionalParams(), options, cancellationToken); + + /// + /// Transcribe a file uploaded to AssemblyAI. + /// + /// The file uploaded to AssemblyAI to transcribe + /// The transcript parameters + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public Task TranscribeAsync( UploadedFile file, TranscriptOptionalParams transcriptParams, @@ -198,6 +357,13 @@ public Task TranscribeAsync( CancellationToken cancellationToken = default ) => TranscribeAsync(CreateParams(file.UploadUrl, transcriptParams), options, cancellationToken); + /// + /// Transcribe an audio file via its public URI. + /// + /// The transcript parameters + /// HTTP request options + /// + /// A task that resolves to a transcript with status "completed" or "error". public async Task TranscribeAsync( TranscriptParams transcriptParams, RequestOptions? options = null, @@ -216,7 +382,7 @@ public async Task TranscribeAsync( /// The transcript ID /// How frequently the transcript is polled. Defaults to 3s. /// How long to wait until the timeout exception thrown. Defaults to infinite. - /// + /// HTTP request options /// Cancellation token /// The transcript with status "completed" or "error" public async Task WaitUntilReady( @@ -257,9 +423,16 @@ public async Task WaitUntilReady( return transcript; } + /// + /// Create transcript parameters from an audio file URL and optional parameters. + /// + /// The audio file URL to transcribe + /// The optional transcript parameters + /// The transcript parameters private static TranscriptParams CreateParams(Uri audioFileUrl, TranscriptOptionalParams optionalTranscriptParams) => CreateParams(audioFileUrl.ToString(), optionalTranscriptParams); + /// private static TranscriptParams CreateParams(string audioFileUrl, TranscriptOptionalParams optionalTranscriptParams) { var json = JsonUtils.Serialize(optionalTranscriptParams); @@ -269,20 +442,25 @@ private static TranscriptParams CreateParams(string audioFileUrl, TranscriptOpti return transcriptParams; } + /// - /// Get the transcript resource. The transcript is ready when the "status" is "completed". + /// Retrieve a list of transcripts you created. + /// Transcripts are sorted from newest to oldest. The previous URL always points to a page with older transcripts. /// - public Task ListAsync( - RequestOptions? options = null, CancellationToken cancellationToken = default) + /// HTTP request options + /// + /// A list of transcripts you created + public Task ListAsync(RequestOptions? options = null, CancellationToken cancellationToken = default) => ListAsync(new ListTranscriptParams(), options, cancellationToken); - + /// /// Retrieve a list of transcripts you created. /// Transcripts are sorted from newest to oldest. The previous URL always points to a page with older transcripts. /// /// The next or previous page URL to query the transcript list. - /// - /// Cancellation token + /// HTTP request options + /// + /// A list of transcripts you created public async Task ListAsync(string listUrl, RequestOptions? options = null, CancellationToken cancellationToken = default) @@ -338,6 +516,7 @@ public async Task ListAsync(string listUrl, /// /// Export your transcript in SRT or VTT format to use with a video player for subtitles and closed captions. /// + /// A task that resolves to a string of the subtitles public Task GetSubtitlesAsync( string transcriptId, SubtitleFormat subtitleFormat, @@ -349,6 +528,7 @@ public Task GetSubtitlesAsync( /// /// Export your transcript in SRT or VTT format to use with a video player for subtitles and closed captions. /// + /// A task that resolves to a string of the subtitles public Task GetSubtitlesAsync( string transcriptId, SubtitleFormat subtitleFormat, @@ -364,6 +544,7 @@ public Task GetSubtitlesAsync( /// /// Retrieve the redacted audio file. /// + /// A task that resolves to a stream of the redacted audio file public async Task GetRedactedAudioFileAsync( string transcriptId, RequestOptions? options = null, diff --git a/src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs b/src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs index 74fffbf..23fef2d 100644 --- a/src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs +++ b/src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs @@ -3,7 +3,7 @@ namespace AssemblyAI.Transcripts; /// -/// Exception thrown when a transcript status is not completed. +/// Exception thrown when a transcript status is not "completed". /// public class TranscriptNotCompletedStatusException : Exception { diff --git a/src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs b/src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs index 4e5f77e..1c057bd 100644 --- a/src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs +++ b/src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs @@ -6,11 +6,11 @@ namespace AssemblyAI.Transcripts; public static class TranscriptExtensions { /// - /// Throws an exception if the transcript status is not completed. + /// Throws an exception if the transcript status is not "completed". /// /// The transcript /// - /// The exception is thrown if the transcript status is not completed. + /// The exception is thrown if the transcript status is not "completed". /// The exception contains the transcript, so you can access the status and error message. /// public static void EnsureStatusCompleted(this Transcript transcript) diff --git a/src/AssemblyAI/UserAgent.cs b/src/AssemblyAI/UserAgent.cs index fb5e19a..b001f7e 100644 --- a/src/AssemblyAI/UserAgent.cs +++ b/src/AssemblyAI/UserAgent.cs @@ -4,31 +4,57 @@ namespace AssemblyAI; +/// +/// The AssemblyAI user agent. +/// public class UserAgent { + /// + /// The default AssemblyAI user agent. + /// public static readonly UserAgent Default = CreateDefaultUserAgent(); private readonly Dictionary _userAgent; + /// + /// Create a new instance of the class. + /// public UserAgent() : this(new Dictionary()) { } + /// + /// Create a new instance of the class from a dictionary. + /// + /// public UserAgent(Dictionary userAgent) { _userAgent = userAgent; } + /// + /// Create a new instance of the class by merging two user agents. + /// + /// User agent A + /// User agent B public UserAgent(UserAgent a, UserAgent b) { _userAgent = Merge(a._userAgent, b._userAgent) as Dictionary; } + /// + /// Get or set a user agent item by key. + /// + /// The name of the user agent item public UserAgentItem? this[string index] { get => _userAgent[index]; set => _userAgent[index] = value; } + /// + /// Convert the AssemblyAI user agent to a string. + /// + /// The AssemblyAI user agent section public string ToAssemblyAIUserAgentString() { var sb = new System.Text.StringBuilder("AssemblyAI/1.0 ("); @@ -38,6 +64,10 @@ public string ToAssemblyAIUserAgentString() return sb.ToString(); } + /// + /// Create the default AssemblyAI user agent. + /// + /// private static UserAgent CreateDefaultUserAgent() { var defaultUserAgent = new Dictionary(); @@ -55,6 +85,11 @@ private static UserAgent CreateDefaultUserAgent() #if NET462_OR_GREATER #else + /// + /// Parse the framework description into a name and version. + /// + /// + /// private static (string Name, string Version) ParseFrameworkDescription(string frameworkDescription) { string name; @@ -90,6 +125,12 @@ private static (string Name, string Version) ParseFrameworkDescription(string fr } #endif + /// + /// Merge two user agents dictionaries. + /// + /// User agent dictionary A + /// User agent dictionary B + /// private static Dictionary Merge( Dictionary a, Dictionary b @@ -113,6 +154,11 @@ private static Dictionary Merge( } } +/// +/// An item in the AssemblyAI user agent. +/// +/// The user agent item name +/// The user agent item version public class UserAgentItem(string name, string version) { public string Name { get; set; } = name;