+
+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.
+
+
+Get the transcript split by sentences. The API will attempt to semantically segment the transcript into sentences to create more reader-friendly transcripts.
+
+
+Get the transcript split by paragraphs. The API will attempt to semantically segment your transcript into paragraphs to create more reader-friendly transcripts.
+
+
+Custom Summary allows you to distill a piece of audio into a few impactful sentences.
+You can give the model context to obtain more targeted results while outputting the results in a variety of formats described in human language.
+
+
+
+
+
+#### 🔌 Usage
+
+
+
+
+
+
+
+```csharp
+await client.Lemur.SummaryAsync(
+ new LemurSummaryParams
+ {
+ TranscriptIds = new List() { "47b95ba5-8889-44d8-bc80-5de38306e582" },
+ Context = "This is an interview about wildfires.",
+ FinalModel = LemurModel.AnthropicClaude35Sonnet,
+ MaxOutputSize = 3000,
+ Temperature = 0f,
+ }
+);
+```
+
+
+Question & Answer allows you to ask free-form questions about a single transcript or a group of transcripts.
+The questions can be any whose answers you find useful, such as judging whether a caller is likely to become a customer or whether all items on a meeting's agenda were covered.
+
+
+
+
+
+#### 🔌 Usage
+
+
+
+
+
+
+
+```csharp
+await client.Lemur.QuestionAnswerAsync(
+ new LemurQuestionAnswerParams
+ {
+ TranscriptIds = new List() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
+ Context = "This is an interview about wildfires.",
+ FinalModel = LemurModel.AnthropicClaude35Sonnet,
+ MaxOutputSize = 3000,
+ Temperature = 0f,
+ Questions = new List()
+ {
+ new LemurQuestion
+ {
+ Question = "Where are there wildfires?",
+ AnswerFormat = "List of countries in ISO 3166-1 alpha-2 format",
+ AnswerOptions = new List() { "US", "CA" },
+ },
+ new LemurQuestion
+ {
+ Question = "Is global warming affecting wildfires?",
+ AnswerOptions = new List() { "yes", "no" },
+ },
+ },
+ }
+);
+```
+
+
+Delete the data for a previously submitted LeMUR request.
+The LLM response data, as well as any context provided in the original request will be removed.
+
+
+**requestId:** `string` — The ID of the LeMUR request whose data you want to delete. This would be found in the response of the original request.
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AssemblyAI/AssemblyAI.Custom.props b/src/AssemblyAI/AssemblyAI.Custom.props
new file mode 100644
index 0000000..70df284
--- /dev/null
+++ b/src/AssemblyAI/AssemblyAI.Custom.props
@@ -0,0 +1,20 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/AssemblyAI/Core/EnumSerializer.cs b/src/AssemblyAI/Core/EnumSerializer.cs
new file mode 100644
index 0000000..ef9a1ff
--- /dev/null
+++ b/src/AssemblyAI/Core/EnumSerializer.cs
@@ -0,0 +1,53 @@
+using System.Runtime.Serialization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace AssemblyAI.Core;
+
+internal class EnumSerializer : JsonConverter
+ where TEnum : struct, System.Enum
+{
+ private readonly Dictionary _enumToString = new();
+ private readonly Dictionary _stringToEnum = new();
+
+ public EnumSerializer()
+ {
+ var type = typeof(TEnum);
+ var values = Enum.GetValues(type);
+
+ foreach (var value in values)
+ {
+ var enumValue = (TEnum)value;
+ var enumMember = type.GetMember(enumValue.ToString())[0];
+ var attr = enumMember
+ .GetCustomAttributes(typeof(EnumMemberAttribute), false)
+ .Cast()
+ .FirstOrDefault();
+
+ var stringValue =
+ attr?.Value
+ ?? value.ToString()
+ ?? throw new Exception("Unexpected null enum toString value");
+
+ _enumToString.Add(enumValue, stringValue);
+ _stringToEnum.Add(stringValue, enumValue);
+ }
+ }
+
+ public override TEnum Read(
+ ref Utf8JsonReader reader,
+ System.Type typeToConvert,
+ JsonSerializerOptions options
+ )
+ {
+ var stringValue =
+ reader.GetString()
+ ?? throw new Exception("The JSON value could not be read as a string.");
+ return _stringToEnum.TryGetValue(stringValue, out var enumValue) ? enumValue : default;
+ }
+
+ public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(_enumToString[value]);
+ }
+}
diff --git a/src/AssemblyAI/Core/Extensions.cs b/src/AssemblyAI/Core/Extensions.cs
index 167b9e5..a1c7fef 100644
--- a/src/AssemblyAI/Core/Extensions.cs
+++ b/src/AssemblyAI/Core/Extensions.cs
@@ -4,11 +4,11 @@ namespace AssemblyAI.Core;
internal static class Extensions
{
- internal static string Stringify(this Enum value)
+ public static string Stringify(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
var attribute = (EnumMemberAttribute)
- Attribute.GetCustomAttribute(field!, typeof(EnumMemberAttribute))!;
+ Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute));
return attribute?.Value ?? value.ToString();
}
}
diff --git a/src/AssemblyAI/Core/IRequestOptions.cs b/src/AssemblyAI/Core/IRequestOptions.cs
new file mode 100644
index 0000000..cf3ef5a
--- /dev/null
+++ b/src/AssemblyAI/Core/IRequestOptions.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Net.Http;
+
+#nullable enable
+
+namespace AssemblyAI.Core;
+
+internal interface IRequestOptions
+{
+ ///
+ /// The Base URL for the API.
+ ///
+ public string? BaseUrl { get; init; }
+
+ ///
+ /// The http client used to make requests.
+ ///
+ public HttpClient? HttpClient { get; init; }
+
+ ///
+ /// The http headers sent with the request.
+ ///
+ internal Headers Headers { get; init; }
+
+ ///
+ /// The http client used to make requests.
+ ///
+ public int? MaxRetries { get; init; }
+
+ ///
+ /// The timeout for the request.
+ ///
+ public TimeSpan? Timeout { get; init; }
+}
diff --git a/src/AssemblyAI/Core/OneOfSerializer.cs b/src/AssemblyAI/Core/OneOfSerializer.cs
index c4c18fd..786b12d 100644
--- a/src/AssemblyAI/Core/OneOfSerializer.cs
+++ b/src/AssemblyAI/Core/OneOfSerializer.cs
@@ -5,10 +5,9 @@
namespace AssemblyAI.Core;
-internal class OneOfSerializer : JsonConverter
- where TOneOf : IOneOf
+internal class OneOfSerializer : JsonConverter
{
- public override TOneOf? Read(
+ public override IOneOf? Read(
ref Utf8JsonReader reader,
System.Type typeToConvert,
JsonSerializerOptions options
@@ -17,14 +16,14 @@ JsonSerializerOptions options
if (reader.TokenType is JsonTokenType.Null)
return default;
- foreach (var (type, cast) in s_types)
+ foreach (var (type, cast) in GetOneOfTypes(typeToConvert))
{
try
{
var readerCopy = reader;
var result = JsonSerializer.Deserialize(ref readerCopy, type, options);
reader.Skip();
- return (TOneOf)cast.Invoke(null, [result])!;
+ return (IOneOf)cast.Invoke(null, [result])!;
}
catch (JsonException) { }
}
@@ -34,20 +33,18 @@ JsonSerializerOptions options
);
}
- private static readonly (System.Type type, MethodInfo cast)[] s_types = GetOneOfTypes();
-
- public override void Write(Utf8JsonWriter writer, TOneOf value, JsonSerializerOptions options)
+ public override void Write(Utf8JsonWriter writer, IOneOf value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value.Value, options);
}
- private static (System.Type type, MethodInfo cast)[] GetOneOfTypes()
+ private static (System.Type type, MethodInfo cast)[] GetOneOfTypes(System.Type typeToConvert)
{
- var casts = typeof(TOneOf)
+ var casts = typeToConvert
.GetRuntimeMethods()
.Where(m => m.IsSpecialName && m.Name == "op_Implicit")
.ToArray();
- var type = typeof(TOneOf);
+ var type = typeToConvert;
while (type != null)
{
if (
@@ -62,6 +59,11 @@ private static (System.Type type, MethodInfo cast)[] GetOneOfTypes()
type = type.BaseType;
}
- throw new InvalidOperationException($"{typeof(TOneOf)} isn't OneOf or OneOfBase");
+ throw new InvalidOperationException($"{type} isn't OneOf or OneOfBase");
+ }
+
+ public override bool CanConvert(System.Type typeToConvert)
+ {
+ return typeof(IOneOf).IsAssignableFrom(typeToConvert);
}
}
diff --git a/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs b/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs
index 9bdec3e..148f07b 100644
--- a/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs
+++ b/src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs
@@ -1,13 +1,6 @@
-// ReSharper disable CheckNamespace
namespace AssemblyAI;
-///
-/// Available AssemblyAI API environments
-///
-public static class AssemblyAIClientEnvironment
+public class AssemblyAIClientEnvironment
{
- ///
- /// The default base URL for the AssemblyAI API.
- ///
- public const string Default = "https://api.assemblyai.com";
+ public static string Default = "https://api.assemblyai.com";
}
diff --git a/src/AssemblyAI/Core/Public/ClientOptions.cs b/src/AssemblyAI/Core/Public/ClientOptions.cs
index 8241f7a..a12c55f 100644
--- a/src/AssemblyAI/Core/Public/ClientOptions.cs
+++ b/src/AssemblyAI/Core/Public/ClientOptions.cs
@@ -1,6 +1,8 @@
+using System;
using System.Net.Http;
using AssemblyAI.Core;
-// ReSharper disable CheckNamespace
+
+#nullable enable
namespace AssemblyAI;
@@ -9,25 +11,40 @@ public partial class ClientOptions
///
/// The Base URL for the API.
///
- public string BaseUrl { get; set; } = AssemblyAIClientEnvironment.Default;
+ public string BaseUrl { get; init; } = AssemblyAIClientEnvironment.Default;
///
/// The http client used to make requests.
///
- public HttpClient HttpClient { get; set; } = new();
+ public HttpClient HttpClient { get; init; } = new HttpClient();
///
- /// The amount to retry sending the HTTP request if it fails.
+ /// The http client used to make requests.
///
- public int MaxRetries { get; set; } = 2;
+ public int MaxRetries { get; init; } = 2;
///
/// The timeout for the request.
///
- public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
+ public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(30);
///
/// The http headers sent with the request.
///
internal Headers Headers { get; init; } = new();
+
+ ///
+ /// Clones this and returns a new instance
+ ///
+ internal ClientOptions Clone()
+ {
+ return new ClientOptions
+ {
+ BaseUrl = BaseUrl,
+ HttpClient = HttpClient,
+ MaxRetries = MaxRetries,
+ Timeout = Timeout,
+ Headers = new Headers(new Dictionary(Headers)),
+ };
+ }
}
diff --git a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
deleted file mode 100644
index 291f27b..0000000
--- a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// ReSharper disable PartialTypeWithSinglePart
-// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
-// ReSharper disable CheckNamespace
-
-namespace AssemblyAI;
-
-///
-/// The options for the AssemblyAI client.
-///
-public partial class ClientOptions
-{
- ///
- /// The AssemblyAI API key
- ///
- public required string ApiKey { get; set; }
-
- ///
- /// The AssemblyAI user agent
- ///
- public UserAgent UserAgent { get; set; } = new();
-}
\ No newline at end of file
diff --git a/src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs b/src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs
deleted file mode 100644
index 7dbbd7f..0000000
--- a/src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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/Core/Public/RequestOptions.cs b/src/AssemblyAI/Core/Public/RequestOptions.cs
index 688540f..bf56473 100644
--- a/src/AssemblyAI/Core/Public/RequestOptions.cs
+++ b/src/AssemblyAI/Core/Public/RequestOptions.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI;
-public partial class RequestOptions
+public partial class RequestOptions : IRequestOptions
{
///
/// The Base URL for the API.
@@ -31,5 +31,5 @@ public partial class RequestOptions
///
/// The http headers sent with the request.
///
- internal Headers Headers { get; init; } = new();
+ Headers IRequestOptions.Headers { get; init; } = new();
}
diff --git a/src/AssemblyAI/Core/Public/Version.cs b/src/AssemblyAI/Core/Public/Version.cs
new file mode 100644
index 0000000..93e43c9
--- /dev/null
+++ b/src/AssemblyAI/Core/Public/Version.cs
@@ -0,0 +1,6 @@
+namespace AssemblyAI;
+
+internal class Version
+{
+ public const string Current = "1.2.1";
+}
diff --git a/src/AssemblyAI/Core/RawClient.cs b/src/AssemblyAI/Core/RawClient.cs
index 82444ad..63e6e93 100644
--- a/src/AssemblyAI/Core/RawClient.cs
+++ b/src/AssemblyAI/Core/RawClient.cs
@@ -1,4 +1,5 @@
using System.Net.Http;
+using System.Net.Http.Headers;
using System.Text;
using System.Threading;
@@ -11,8 +12,11 @@ namespace AssemblyAI.Core;
///
internal class RawClient(ClientOptions clientOptions)
{
+ private const int InitialRetryDelayMs = 1000;
+ private const int MaxRetryDelayMs = 60000;
+
///
- /// The http client used to make requests.
+ /// The client options applied on every request.
///
public readonly ClientOptions Options = clientOptions;
@@ -21,36 +25,13 @@ public async Task MakeRequestAsync(
CancellationToken cancellationToken = default
)
{
- var url = BuildUrl(request);
- var httpRequest = new HttpRequestMessage(request.Method, url);
- if (request.ContentType != null)
- {
- request.Headers.Add("Content-Type", request.ContentType);
- }
- SetHeaders(httpRequest, Options.Headers);
- SetHeaders(httpRequest, request.Headers);
- SetHeaders(httpRequest, request.Options?.Headers ?? new());
+ // Apply the request timeout.
+ var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ var timeout = request.Options?.Timeout ?? Options.Timeout;
+ cts.CancelAfter(timeout);
- // Add the request body to the request
- if (request is JsonApiRequest jsonRequest)
- {
- if (jsonRequest.Body != null)
- {
- httpRequest.Content = new StringContent(
- JsonUtils.Serialize(jsonRequest.Body),
- Encoding.UTF8,
- "application/json"
- );
- }
- }
- else if (request is StreamApiRequest { Body: not null } streamRequest)
- {
- httpRequest.Content = new StreamContent(streamRequest.Body);
- }
- // Send the request
- var httpClient = request.Options?.HttpClient ?? Options.HttpClient;
- var response = await httpClient.SendAsync(httpRequest, cancellationToken);
- return new ApiResponse { StatusCode = (int)response.StatusCode, Raw = response };
+ // Send the request.
+ return await SendWithRetriesAsync(request, cts.Token);
}
public record BaseApiRequest
@@ -67,7 +48,7 @@ public record BaseApiRequest
public Headers Headers { get; init; } = new();
- public RequestOptions? Options { get; init; }
+ public IRequestOptions? Options { get; init; }
}
///
@@ -96,19 +77,70 @@ public record ApiResponse
public required HttpResponseMessage Raw { get; init; }
}
- private void SetHeaders(HttpRequestMessage httpRequest, Headers headers)
+ private async Task SendWithRetriesAsync(
+ BaseApiRequest request,
+ CancellationToken cancellationToken
+ )
{
- foreach (var header in headers)
+ var httpClient = request.Options?.HttpClient ?? Options.HttpClient;
+ var maxRetries = request.Options?.MaxRetries ?? Options.MaxRetries;
+ var response = await httpClient.SendAsync(BuildHttpRequest(request), cancellationToken);
+ for (var i = 0; i < maxRetries; i++)
{
- var value = header.Value?.Match(str => str, func => func.Invoke());
- if (value != null)
+ if (!ShouldRetry(response))
{
- httpRequest.Headers.TryAddWithoutValidation(header.Key, value);
+ break;
}
+ var delayMs = Math.Min(InitialRetryDelayMs * (int)Math.Pow(2, i), MaxRetryDelayMs);
+ await System.Threading.Tasks.Task.Delay(delayMs, cancellationToken);
+ response = await httpClient.SendAsync(BuildHttpRequest(request), cancellationToken);
}
+ return new ApiResponse { StatusCode = (int)response.StatusCode, Raw = response };
}
- private string BuildUrl(BaseApiRequest request)
+ private static bool ShouldRetry(HttpResponseMessage response)
+ {
+ var statusCode = (int)response.StatusCode;
+ return statusCode is 408 or 429 or >= 500;
+ }
+
+ private HttpRequestMessage BuildHttpRequest(BaseApiRequest request)
+ {
+ var url = BuildUrl(request);
+ var httpRequest = new HttpRequestMessage(request.Method, url);
+ switch (request)
+ {
+ // Add the request body to the request.
+ case JsonApiRequest jsonRequest:
+ {
+ if (jsonRequest.Body != null)
+ {
+ httpRequest.Content = new StringContent(
+ JsonUtils.Serialize(jsonRequest.Body),
+ Encoding.UTF8,
+ "application/json"
+ );
+ }
+ break;
+ }
+ case StreamApiRequest { Body: not null } streamRequest:
+ httpRequest.Content = new StreamContent(streamRequest.Body);
+ break;
+ }
+ if (request.ContentType != null)
+ {
+ httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(
+ request.ContentType
+ );
+ }
+ SetHeaders(httpRequest, Options.Headers);
+ SetHeaders(httpRequest, request.Headers);
+ SetHeaders(httpRequest, request.Options?.Headers ?? new Headers());
+
+ return httpRequest;
+ }
+
+ private static string BuildUrl(BaseApiRequest request)
{
var baseUrl = request.Options?.BaseUrl ?? request.BaseUrl;
var trimmedBaseUrl = baseUrl.TrimEnd('/');
@@ -139,7 +171,19 @@ private string BuildUrl(BaseApiRequest request)
return current;
}
);
- url = url.Substring(0, url.Length - 1);
+ url = url[..^1];
return url;
}
+
+ private static void SetHeaders(HttpRequestMessage httpRequest, Headers headers)
+ {
+ foreach (var header in headers)
+ {
+ var value = header.Value?.Match(str => str, func => func.Invoke());
+ if (value != null)
+ {
+ httpRequest.Headers.TryAddWithoutValidation(header.Key, value);
+ }
+ }
+ }
}
diff --git a/src/AssemblyAI/Files/FilesClient.cs b/src/AssemblyAI/Files/FilesClient.cs
index 91ae90b..28bf90c 100644
--- a/src/AssemblyAI/Files/FilesClient.cs
+++ b/src/AssemblyAI/Files/FilesClient.cs
@@ -33,6 +33,7 @@ public async Task UploadAsync(
Method = HttpMethod.Post,
Path = "v2/upload",
Body = request,
+ ContentType = "application/octet-stream",
Options = options,
},
cancellationToken
diff --git a/src/AssemblyAI/Lemur/ExtendedLemurClient.cs b/src/AssemblyAI/Lemur/ExtendedLemurClient.cs
deleted file mode 100644
index 1a7b4ae..0000000
--- a/src/AssemblyAI/Lemur/ExtendedLemurClient.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace AssemblyAI.Lemur;
-
-///
-/// The client to interact with the AssemblyAI LeMUR API.
-///
-public partial class LemurClient;
diff --git a/src/AssemblyAI/Lemur/LemurClient.cs b/src/AssemblyAI/Lemur/LemurClient.cs
index 36b72b0..130f8a1 100644
--- a/src/AssemblyAI/Lemur/LemurClient.cs
+++ b/src/AssemblyAI/Lemur/LemurClient.cs
@@ -26,7 +26,7 @@ internal LemurClient(RawClient client)
/// await client.Lemur.TaskAsync(
/// new LemurTaskParams
/// {
- /// TranscriptIds = new List() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
+ /// TranscriptIds = new List<string>() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
/// Context = "This is an interview about wildfires.",
/// FinalModel = LemurModel.AnthropicClaude35Sonnet,
/// MaxOutputSize = 3000,
@@ -49,6 +49,7 @@ public async Task TaskAsync(
Method = HttpMethod.Post,
Path = "lemur/v3/generate/task",
Body = request,
+ ContentType = "application/json",
Options = options,
},
cancellationToken
@@ -82,7 +83,7 @@ public async Task TaskAsync(
/// await client.Lemur.SummaryAsync(
/// new LemurSummaryParams
/// {
- /// TranscriptIds = new List() { "47b95ba5-8889-44d8-bc80-5de38306e582" },
+ /// TranscriptIds = new List<string>() { "47b95ba5-8889-44d8-bc80-5de38306e582" },
/// Context = "This is an interview about wildfires.",
/// FinalModel = LemurModel.AnthropicClaude35Sonnet,
/// MaxOutputSize = 3000,
@@ -104,6 +105,7 @@ public async Task SummaryAsync(
Method = HttpMethod.Post,
Path = "lemur/v3/generate/summary",
Body = request,
+ ContentType = "application/json",
Options = options,
},
cancellationToken
@@ -137,23 +139,23 @@ public async Task SummaryAsync(
/// await client.Lemur.QuestionAnswerAsync(
/// new LemurQuestionAnswerParams
/// {
- /// TranscriptIds = new List() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
+ /// TranscriptIds = new List<string>() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
/// Context = "This is an interview about wildfires.",
/// FinalModel = LemurModel.AnthropicClaude35Sonnet,
/// MaxOutputSize = 3000,
/// Temperature = 0f,
- /// Questions = new List()
+ /// Questions = new List<LemurQuestion>()
/// {
/// new LemurQuestion
/// {
/// Question = "Where are there wildfires?",
/// AnswerFormat = "List of countries in ISO 3166-1 alpha-2 format",
- /// AnswerOptions = new List() { "US", "CA" },
+ /// AnswerOptions = new List<string>() { "US", "CA" },
/// },
/// new LemurQuestion
/// {
/// Question = "Is global warming affecting wildfires?",
- /// AnswerOptions = new List() { "yes", "no" },
+ /// AnswerOptions = new List<string>() { "yes", "no" },
/// },
/// },
/// }
@@ -173,6 +175,7 @@ public async Task QuestionAnswerAsync(
Method = HttpMethod.Post,
Path = "lemur/v3/generate/question-answer",
Body = request,
+ ContentType = "application/json",
Options = options,
},
cancellationToken
@@ -205,7 +208,7 @@ public async Task QuestionAnswerAsync(
/// await client.Lemur.ActionItemsAsync(
/// new LemurActionItemsParams
/// {
- /// TranscriptIds = new List() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
+ /// TranscriptIds = new List<string>() { "64nygnr62k-405c-4ae8-8a6b-d90b40ff3cce" },
/// Context = "This is an interview about wildfires.",
/// FinalModel = LemurModel.AnthropicClaude35Sonnet,
/// MaxOutputSize = 3000,
@@ -228,6 +231,7 @@ public async Task ActionItemsAsync(
Method = HttpMethod.Post,
Path = "lemur/v3/generate/action-items",
Body = request,
+ ContentType = "application/json",
Options = options,
},
cancellationToken
diff --git a/src/AssemblyAI/Lemur/Requests/LemurActionItemsParams.cs b/src/AssemblyAI/Lemur/Requests/LemurActionItemsParams.cs
index b2a08a1..8e892fb 100644
--- a/src/AssemblyAI/Lemur/Requests/LemurActionItemsParams.cs
+++ b/src/AssemblyAI/Lemur/Requests/LemurActionItemsParams.cs
@@ -11,7 +11,6 @@ public record LemurActionItemsParams
///
/// How you want the action items to be returned. This can be any text.
/// Defaults to "Bullet Points".
- ///
///
[JsonPropertyName("answer_format")]
public string? AnswerFormat { get; set; }
@@ -34,7 +33,6 @@ public record LemurActionItemsParams
/// Context to provide the model. This can be a string or a free-form JSON value.
///
[JsonPropertyName("context")]
- [JsonConverter(typeof(OneOfSerializer>))]
public OneOf? Context { get; set; }
///
diff --git a/src/AssemblyAI/Lemur/Requests/LemurQuestionAnswerParams.cs b/src/AssemblyAI/Lemur/Requests/LemurQuestionAnswerParams.cs
index dbdf8ef..40a5b04 100644
--- a/src/AssemblyAI/Lemur/Requests/LemurQuestionAnswerParams.cs
+++ b/src/AssemblyAI/Lemur/Requests/LemurQuestionAnswerParams.cs
@@ -32,7 +32,6 @@ public record LemurQuestionAnswerParams
/// Context to provide the model. This can be a string or a free-form JSON value.
///
[JsonPropertyName("context")]
- [JsonConverter(typeof(OneOfSerializer>))]
public OneOf? Context { get; set; }
///
diff --git a/src/AssemblyAI/Lemur/Requests/LemurSummaryParams.cs b/src/AssemblyAI/Lemur/Requests/LemurSummaryParams.cs
index 1c946e4..35e4633 100644
--- a/src/AssemblyAI/Lemur/Requests/LemurSummaryParams.cs
+++ b/src/AssemblyAI/Lemur/Requests/LemurSummaryParams.cs
@@ -10,7 +10,6 @@ public record LemurSummaryParams
{
///
/// How you want the summary to be returned. This can be any text. Examples: "TLDR", "bullet points"
- ///
///
[JsonPropertyName("answer_format")]
public string? AnswerFormat { get; set; }
@@ -33,7 +32,6 @@ public record LemurSummaryParams
/// Context to provide the model. This can be a string or a free-form JSON value.
///
[JsonPropertyName("context")]
- [JsonConverter(typeof(OneOfSerializer>))]
public OneOf? Context { get; set; }
///
diff --git a/src/AssemblyAI/Lemur/Requests/LemurTaskParams.cs b/src/AssemblyAI/Lemur/Requests/LemurTaskParams.cs
index bc38010..2901d5d 100644
--- a/src/AssemblyAI/Lemur/Requests/LemurTaskParams.cs
+++ b/src/AssemblyAI/Lemur/Requests/LemurTaskParams.cs
@@ -32,7 +32,6 @@ public record LemurTaskParams
/// Context to provide the model. This can be a string or a free-form JSON value.
///
[JsonPropertyName("context")]
- [JsonConverter(typeof(OneOfSerializer>))]
public OneOf? Context { get; set; }
///
diff --git a/src/AssemblyAI/Lemur/Types/LemurBaseParams.cs b/src/AssemblyAI/Lemur/Types/LemurBaseParams.cs
index d757dd1..138ebfc 100644
--- a/src/AssemblyAI/Lemur/Types/LemurBaseParams.cs
+++ b/src/AssemblyAI/Lemur/Types/LemurBaseParams.cs
@@ -26,7 +26,6 @@ public record LemurBaseParams
/// Context to provide the model. This can be a string or a free-form JSON value.
///
[JsonPropertyName("context")]
- [JsonConverter(typeof(OneOfSerializer>))]
public OneOf? Context { get; set; }
///
diff --git a/src/AssemblyAI/Lemur/Types/LemurModel.cs b/src/AssemblyAI/Lemur/Types/LemurModel.cs
index bf1b231..941b238 100644
--- a/src/AssemblyAI/Lemur/Types/LemurModel.cs
+++ b/src/AssemblyAI/Lemur/Types/LemurModel.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Lemur;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum LemurModel
{
[EnumMember(Value = "anthropic/claude-3-5-sonnet")]
@@ -27,10 +27,6 @@ public enum LemurModel
[EnumMember(Value = "anthropic/claude-2")]
AnthropicClaude2_0,
- [EnumMember(Value = "anthropic/claude-2")]
- [Obsolete("Use AnthropicClaude2_0")]
- AnthropicClaude2,
-
[EnumMember(Value = "default")]
Default,
diff --git a/src/AssemblyAI/Lemur/Types/LemurQuestion.cs b/src/AssemblyAI/Lemur/Types/LemurQuestion.cs
index 59ac5fc..0fca4e2 100644
--- a/src/AssemblyAI/Lemur/Types/LemurQuestion.cs
+++ b/src/AssemblyAI/Lemur/Types/LemurQuestion.cs
@@ -18,7 +18,6 @@ public record LemurQuestion
/// Any context about the transcripts you wish to provide. This can be a string or any object.
///
[JsonPropertyName("context")]
- [JsonConverter(typeof(OneOfSerializer>))]
public OneOf? Context { get; set; }
///
diff --git a/src/AssemblyAI/Realtime/RealtimeClient.cs b/src/AssemblyAI/Realtime/RealtimeClient.cs
index d06e881..b9e1c4f 100644
--- a/src/AssemblyAI/Realtime/RealtimeClient.cs
+++ b/src/AssemblyAI/Realtime/RealtimeClient.cs
@@ -40,6 +40,7 @@ public async Task CreateTemporaryTokenAsync(
Method = HttpMethod.Post,
Path = "v2/realtime/token",
Body = request,
+ ContentType = "application/json",
Options = options,
},
cancellationToken
diff --git a/src/AssemblyAI/Realtime/Types/AudioEncoding.cs b/src/AssemblyAI/Realtime/Types/AudioEncoding.cs
index e15f895..617d74b 100644
--- a/src/AssemblyAI/Realtime/Types/AudioEncoding.cs
+++ b/src/AssemblyAI/Realtime/Types/AudioEncoding.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Realtime;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum AudioEncoding
{
[EnumMember(Value = "pcm_s16le")]
diff --git a/src/AssemblyAI/Realtime/Types/FinalTranscript.cs b/src/AssemblyAI/Realtime/Types/FinalTranscript.cs
index 4816900..89e3a43 100644
--- a/src/AssemblyAI/Realtime/Types/FinalTranscript.cs
+++ b/src/AssemblyAI/Realtime/Types/FinalTranscript.cs
@@ -20,7 +20,7 @@ public record FinalTranscript
public required bool Punctuated { get; set; }
///
- /// Whether the text is formatted, for example Dollar -> $
+ /// Whether the text is formatted, for example Dollar -> $
///
[JsonPropertyName("text_formatted")]
public required bool TextFormatted { get; set; }
diff --git a/src/AssemblyAI/Realtime/Types/MessageType.cs b/src/AssemblyAI/Realtime/Types/MessageType.cs
index e315ba9..b1e7925 100644
--- a/src/AssemblyAI/Realtime/Types/MessageType.cs
+++ b/src/AssemblyAI/Realtime/Types/MessageType.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Realtime;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum MessageType
{
[EnumMember(Value = "SessionBegins")]
diff --git a/src/AssemblyAI/Realtime/Types/RealtimeTranscriptType.cs b/src/AssemblyAI/Realtime/Types/RealtimeTranscriptType.cs
index 67b92f8..fa64fcb 100644
--- a/src/AssemblyAI/Realtime/Types/RealtimeTranscriptType.cs
+++ b/src/AssemblyAI/Realtime/Types/RealtimeTranscriptType.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Realtime;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum RealtimeTranscriptType
{
[EnumMember(Value = "PartialTranscript")]
diff --git a/src/AssemblyAI/Transcripts/TranscriptsClient.cs b/src/AssemblyAI/Transcripts/TranscriptsClient.cs
index eec587d..a1c69a5 100644
--- a/src/AssemblyAI/Transcripts/TranscriptsClient.cs
+++ b/src/AssemblyAI/Transcripts/TranscriptsClient.cs
@@ -110,13 +110,13 @@ public async Task ListAsync(
/// AutoHighlights = true,
/// AudioStartFrom = 10,
/// AudioEndAt = 280,
- /// WordBoost = new List() { "aws", "azure", "google cloud" },
+ /// WordBoost = new List<string>() { "aws", "azure", "google cloud" },
/// BoostParam = TranscriptBoostParam.High,
/// FilterProfanity = true,
/// RedactPii = true,
/// RedactPiiAudio = true,
/// RedactPiiAudioQuality = RedactPiiAudioQuality.Mp3,
- /// RedactPiiPolicies = new List()
+ /// RedactPiiPolicies = new List<PiiPolicy>()
/// {
/// PiiPolicy.UsSocialSecurityNumber,
/// PiiPolicy.CreditCardNumber,
@@ -126,11 +126,11 @@ public async Task ListAsync(
/// SpeakersExpected = 2,
/// ContentSafety = true,
/// IabCategories = true,
- /// CustomSpelling = new List()
+ /// CustomSpelling = new List<TranscriptCustomSpelling>()
/// {
/// new TranscriptCustomSpelling
/// {
- /// From = new List() { "dicarlo" },
+ /// From = new List<string>() { "dicarlo" },
/// To = "Decarlo",
/// },
/// },
@@ -142,7 +142,7 @@ public async Task ListAsync(
/// SummaryModel = SummaryModel.Informative,
/// SummaryType = SummaryType.Bullets,
/// CustomTopics = true,
- /// Topics = new List() { "topics" },
+ /// Topics = new List<string>() { "topics" },
/// AudioUrl = "https://assembly.ai/wildfires.mp3",
/// }
/// );
@@ -161,6 +161,7 @@ public async Task SubmitAsync(
Method = HttpMethod.Post,
Path = "v2/transcript",
Body = request,
+ ContentType = "application/json",
Options = options,
},
cancellationToken
@@ -303,7 +304,7 @@ public async Task GetSubtitlesAsync(
{
BaseUrl = _client.Options.BaseUrl,
Method = HttpMethod.Get,
- Path = $"v2/transcript/{transcriptId}/{subtitleFormat.Stringify()}",
+ Path = $"v2/transcript/{transcriptId}/{subtitleFormat}",
Query = _query,
Options = options,
},
diff --git a/src/AssemblyAI/Transcripts/Types/AudioIntelligenceModelStatus.cs b/src/AssemblyAI/Transcripts/Types/AudioIntelligenceModelStatus.cs
index 84b0259..b5c3f15 100644
--- a/src/AssemblyAI/Transcripts/Types/AudioIntelligenceModelStatus.cs
+++ b/src/AssemblyAI/Transcripts/Types/AudioIntelligenceModelStatus.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum AudioIntelligenceModelStatus
{
[EnumMember(Value = "success")]
diff --git a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
index 86fb05d..8aa0b8c 100644
--- a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
+++ b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
@@ -23,7 +23,7 @@ public record ContentSafetyLabel
/// How severely the topic is discussed in the section, from 0 to 1
///
[JsonPropertyName("severity")]
- public required double? Severity { get; set; }
+ public required double Severity { get; set; }
public override string ToString()
{
diff --git a/src/AssemblyAI/Transcripts/Types/EntityType.cs b/src/AssemblyAI/Transcripts/Types/EntityType.cs
index 98f95bc..21f9f17 100644
--- a/src/AssemblyAI/Transcripts/Types/EntityType.cs
+++ b/src/AssemblyAI/Transcripts/Types/EntityType.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum EntityType
{
[EnumMember(Value = "account_number")]
diff --git a/src/AssemblyAI/Transcripts/Types/PiiPolicy.cs b/src/AssemblyAI/Transcripts/Types/PiiPolicy.cs
index 441d1f0..d277e3f 100644
--- a/src/AssemblyAI/Transcripts/Types/PiiPolicy.cs
+++ b/src/AssemblyAI/Transcripts/Types/PiiPolicy.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum PiiPolicy
{
[EnumMember(Value = "account_number")]
diff --git a/src/AssemblyAI/Transcripts/Types/RedactPiiAudioQuality.cs b/src/AssemblyAI/Transcripts/Types/RedactPiiAudioQuality.cs
index 6b59661..3df5fe9 100644
--- a/src/AssemblyAI/Transcripts/Types/RedactPiiAudioQuality.cs
+++ b/src/AssemblyAI/Transcripts/Types/RedactPiiAudioQuality.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum RedactPiiAudioQuality
{
[EnumMember(Value = "mp3")]
diff --git a/src/AssemblyAI/Transcripts/Types/Sentiment.cs b/src/AssemblyAI/Transcripts/Types/Sentiment.cs
index 9748841..6841a5c 100644
--- a/src/AssemblyAI/Transcripts/Types/Sentiment.cs
+++ b/src/AssemblyAI/Transcripts/Types/Sentiment.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum Sentiment
{
[EnumMember(Value = "POSITIVE")]
diff --git a/src/AssemblyAI/Transcripts/Types/SpeechModel.cs b/src/AssemblyAI/Transcripts/Types/SpeechModel.cs
index ea981fd..defb060 100644
--- a/src/AssemblyAI/Transcripts/Types/SpeechModel.cs
+++ b/src/AssemblyAI/Transcripts/Types/SpeechModel.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum SpeechModel
{
[EnumMember(Value = "best")]
diff --git a/src/AssemblyAI/Transcripts/Types/SubstitutionPolicy.cs b/src/AssemblyAI/Transcripts/Types/SubstitutionPolicy.cs
index b29eeb6..632c992 100644
--- a/src/AssemblyAI/Transcripts/Types/SubstitutionPolicy.cs
+++ b/src/AssemblyAI/Transcripts/Types/SubstitutionPolicy.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum SubstitutionPolicy
{
[EnumMember(Value = "entity_name")]
diff --git a/src/AssemblyAI/Transcripts/Types/SubtitleFormat.cs b/src/AssemblyAI/Transcripts/Types/SubtitleFormat.cs
index ebe6a8f..5c5fad3 100644
--- a/src/AssemblyAI/Transcripts/Types/SubtitleFormat.cs
+++ b/src/AssemblyAI/Transcripts/Types/SubtitleFormat.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum SubtitleFormat
{
[EnumMember(Value = "srt")]
diff --git a/src/AssemblyAI/Transcripts/Types/SummaryModel.cs b/src/AssemblyAI/Transcripts/Types/SummaryModel.cs
index d935aa2..86cfbcb 100644
--- a/src/AssemblyAI/Transcripts/Types/SummaryModel.cs
+++ b/src/AssemblyAI/Transcripts/Types/SummaryModel.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum SummaryModel
{
[EnumMember(Value = "informative")]
diff --git a/src/AssemblyAI/Transcripts/Types/SummaryType.cs b/src/AssemblyAI/Transcripts/Types/SummaryType.cs
index 4145146..25632e8 100644
--- a/src/AssemblyAI/Transcripts/Types/SummaryType.cs
+++ b/src/AssemblyAI/Transcripts/Types/SummaryType.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum SummaryType
{
[EnumMember(Value = "bullets")]
diff --git a/src/AssemblyAI/Transcripts/Types/TopicDetectionResultLabelsItem.cs b/src/AssemblyAI/Transcripts/Types/TopicDetectionResultLabelsItem.cs
index b9cc515..2c1ff25 100644
--- a/src/AssemblyAI/Transcripts/Types/TopicDetectionResultLabelsItem.cs
+++ b/src/AssemblyAI/Transcripts/Types/TopicDetectionResultLabelsItem.cs
@@ -14,7 +14,7 @@ public record TopicDetectionResultLabelsItem
public required double Relevance { get; set; }
///
- /// The IAB taxonomical label for the label of the detected topic, where > denotes supertopic/subtopic relationship
+ /// The IAB taxonomical label for the label of the detected topic, where > denotes supertopic/subtopic relationship
///
[JsonPropertyName("label")]
public required string Label { get; set; }
diff --git a/src/AssemblyAI/Transcripts/Types/Transcript.cs b/src/AssemblyAI/Transcripts/Types/Transcript.cs
index 93294f0..c20869d 100644
--- a/src/AssemblyAI/Transcripts/Types/Transcript.cs
+++ b/src/AssemblyAI/Transcripts/Types/Transcript.cs
@@ -5,7 +5,7 @@
namespace AssemblyAI.Transcripts;
-public partial record Transcript
+public record Transcript
{
///
/// The unique identifier of your transcript
diff --git a/src/AssemblyAI/Transcripts/Types/TranscriptBoostParam.cs b/src/AssemblyAI/Transcripts/Types/TranscriptBoostParam.cs
index 6f1ca95..47cdf2f 100644
--- a/src/AssemblyAI/Transcripts/Types/TranscriptBoostParam.cs
+++ b/src/AssemblyAI/Transcripts/Types/TranscriptBoostParam.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum TranscriptBoostParam
{
[EnumMember(Value = "low")]
diff --git a/src/AssemblyAI/Transcripts/Types/TranscriptLanguageCode.cs b/src/AssemblyAI/Transcripts/Types/TranscriptLanguageCode.cs
index 31f39d4..172e0f6 100644
--- a/src/AssemblyAI/Transcripts/Types/TranscriptLanguageCode.cs
+++ b/src/AssemblyAI/Transcripts/Types/TranscriptLanguageCode.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum TranscriptLanguageCode
{
[EnumMember(Value = "en")]
diff --git a/src/AssemblyAI/Transcripts/Types/TranscriptReadyStatus.cs b/src/AssemblyAI/Transcripts/Types/TranscriptReadyStatus.cs
index 999ae77..bcf7d89 100644
--- a/src/AssemblyAI/Transcripts/Types/TranscriptReadyStatus.cs
+++ b/src/AssemblyAI/Transcripts/Types/TranscriptReadyStatus.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum TranscriptReadyStatus
{
[EnumMember(Value = "completed")]
diff --git a/src/AssemblyAI/Transcripts/Types/TranscriptStatus.cs b/src/AssemblyAI/Transcripts/Types/TranscriptStatus.cs
index 9b253d0..6554b48 100644
--- a/src/AssemblyAI/Transcripts/Types/TranscriptStatus.cs
+++ b/src/AssemblyAI/Transcripts/Types/TranscriptStatus.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Transcripts;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum TranscriptStatus
{
[EnumMember(Value = "queued")]
From e37be5941fcd0f9603401725d2e84126c9a45ae6 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 10:15:32 -0500
Subject: [PATCH 02/15] Undo undesired changes
---
.fernignore | 6 ++++++
src/AssemblyAI/Core/Extensions.cs | 4 ++--
.../Public/AssemblyAIClientEnvironment.cs | 11 ++++++++--
src/AssemblyAI/Core/Public/ClientOptions.cs | 14 ++++++-------
.../Core/Public/ExtendedClientOptions.cs | 21 +++++++++++++++++++
.../Core/Public/ExtendedRequestOptions.cs | 9 ++++++++
src/AssemblyAI/Lemur/ExtendedLemurClient.cs | 6 ++++++
src/AssemblyAI/Lemur/Types/LemurModel.cs | 6 +++++-
8 files changed, 64 insertions(+), 13 deletions(-)
create mode 100644 src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
create mode 100644 src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs
create mode 100644 src/AssemblyAI/Lemur/ExtendedLemurClient.cs
diff --git a/.fernignore b/.fernignore
index 58ffc1e..76a3cde 100644
--- a/.fernignore
+++ b/.fernignore
@@ -10,6 +10,10 @@ icon.png
src/AssemblyAI.sln
src/AssemblyAI/AssemblyAI.csproj
src/AssemblyAI/Core/JsonConfiguration.cs
+src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs
+src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
+src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs
+src/AssemblyAI/Core/Public/ClientOptions.cs
src/AssemblyAI/Core/Public/ApiException.cs
src/AssemblyAI/Core/Public/AssemblyAIException.cs
src/AssemblyAI/Core/StringEnumSerializer.cs
@@ -27,6 +31,8 @@ src/AssemblyAI/Transcripts/Types/TranscriptParamsMapper.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsCloner.cs
src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs
src/AssemblyAI/Lemur/Types/LemurResponse.cs
+src/AssemblyAI/Lemur/Types/LemurModel.cs
+src/AssemblyAI/Lemur/ExtendedLemurClient.cs
src/AssemblyAI/Realtime/RealtimeTranscriber.cs
src/AssemblyAI/Realtime/WebsocketClient
src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
diff --git a/src/AssemblyAI/Core/Extensions.cs b/src/AssemblyAI/Core/Extensions.cs
index a1c7fef..167b9e5 100644
--- a/src/AssemblyAI/Core/Extensions.cs
+++ b/src/AssemblyAI/Core/Extensions.cs
@@ -4,11 +4,11 @@ namespace AssemblyAI.Core;
internal static class Extensions
{
- public static string Stringify(this Enum value)
+ internal static string Stringify(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
var attribute = (EnumMemberAttribute)
- Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute));
+ Attribute.GetCustomAttribute(field!, typeof(EnumMemberAttribute))!;
return attribute?.Value ?? value.ToString();
}
}
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 a12c55f..77cbe0f 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;
@@ -11,22 +9,22 @@ public partial class ClientOptions
///
/// The Base URL for the API.
///
- public string BaseUrl { get; init; } = AssemblyAIClientEnvironment.Default;
+ public string BaseUrl { get; set; } = AssemblyAIClientEnvironment.Default;
///
/// The http client used to make requests.
///
- public HttpClient HttpClient { get; init; } = new HttpClient();
+ public HttpClient HttpClient { get; set; } = new();
///
- /// The http client used to make requests.
+ /// The amount to retry sending the HTTP request if it fails.
///
- public int MaxRetries { get; init; } = 2;
+ public int MaxRetries { get; set; } = 2;
///
/// The timeout for the request.
///
- public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(30);
+ public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
///
/// The http headers sent with the request.
diff --git a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
new file mode 100644
index 0000000..291f27b
--- /dev/null
+++ b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
@@ -0,0 +1,21 @@
+// ReSharper disable PartialTypeWithSinglePart
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+// ReSharper disable CheckNamespace
+
+namespace AssemblyAI;
+
+///
+/// The options for the AssemblyAI client.
+///
+public partial class ClientOptions
+{
+ ///
+ /// The AssemblyAI API key
+ ///
+ public required string ApiKey { get; set; }
+
+ ///
+ /// The AssemblyAI user agent
+ ///
+ public UserAgent UserAgent { get; set; } = new();
+}
\ No newline at end of file
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/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/Lemur/Types/LemurModel.cs b/src/AssemblyAI/Lemur/Types/LemurModel.cs
index 941b238..bf1b231 100644
--- a/src/AssemblyAI/Lemur/Types/LemurModel.cs
+++ b/src/AssemblyAI/Lemur/Types/LemurModel.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Lemur;
-[JsonConverter(typeof(EnumSerializer))]
+[JsonConverter(typeof(StringEnumSerializer))]
public enum LemurModel
{
[EnumMember(Value = "anthropic/claude-3-5-sonnet")]
@@ -27,6 +27,10 @@ public enum LemurModel
[EnumMember(Value = "anthropic/claude-2")]
AnthropicClaude2_0,
+ [EnumMember(Value = "anthropic/claude-2")]
+ [Obsolete("Use AnthropicClaude2_0")]
+ AnthropicClaude2,
+
[EnumMember(Value = "default")]
Default,
From 8b93441d38753e5c683e2b09247aacfc2d73e7a7 Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Tue, 21 Jan 2025 15:21:52 +0000
Subject: [PATCH 03/15] SDK regeneration
---
src/AssemblyAI/Core/Extensions.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/AssemblyAI/Core/Extensions.cs b/src/AssemblyAI/Core/Extensions.cs
index 167b9e5..a1c7fef 100644
--- a/src/AssemblyAI/Core/Extensions.cs
+++ b/src/AssemblyAI/Core/Extensions.cs
@@ -4,11 +4,11 @@ namespace AssemblyAI.Core;
internal static class Extensions
{
- internal static string Stringify(this Enum value)
+ public static string Stringify(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
var attribute = (EnumMemberAttribute)
- Attribute.GetCustomAttribute(field!, typeof(EnumMemberAttribute))!;
+ Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute));
return attribute?.Value ?? value.ToString();
}
}
From 43cb2b0c94aae58e13bc6ca478b667cd8bd055b9 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 10:28:26 -0500
Subject: [PATCH 04/15] Use generated version file for User Agent
---
src/AssemblyAI/Core/CustomConstants.cs | 10 ----------
src/AssemblyAI/UserAgent.cs | 6 +++---
2 files changed, 3 insertions(+), 13 deletions(-)
delete mode 100644 src/AssemblyAI/Core/CustomConstants.cs
diff --git a/src/AssemblyAI/Core/CustomConstants.cs b/src/AssemblyAI/Core/CustomConstants.cs
deleted file mode 100644
index 353dc84..0000000
--- a/src/AssemblyAI/Core/CustomConstants.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-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.2.0";
-}
\ No newline at end of file
diff --git a/src/AssemblyAI/UserAgent.cs b/src/AssemblyAI/UserAgent.cs
index b001f7e..bfbc81f 100644
--- a/src/AssemblyAI/UserAgent.cs
+++ b/src/AssemblyAI/UserAgent.cs
@@ -40,7 +40,7 @@ public UserAgent(UserAgent a, UserAgent b)
{
_userAgent = Merge(a._userAgent, b._userAgent) as Dictionary;
}
-
+
///
/// Get or set a user agent item by key.
///
@@ -71,7 +71,7 @@ public string ToAssemblyAIUserAgentString()
private static UserAgent CreateDefaultUserAgent()
{
var defaultUserAgent = new Dictionary();
- defaultUserAgent["sdk"] = new UserAgentItem("CSharp", CustomConstants.Version);
+ defaultUserAgent["sdk"] = new UserAgentItem("CSharp", Version.Current);
#if NET462_OR_GREATER
defaultUserAgent["runtime_env"] = new UserAgentItem(".NET Framework", $"{Environment.Version}");
#else
@@ -82,7 +82,7 @@ private static UserAgent CreateDefaultUserAgent()
return new UserAgent(defaultUserAgent);
}
-
+
#if NET462_OR_GREATER
#else
///
From 858ec6211c467fae3bd6db4605139b1b5edfd2f9 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 10:28:56 -0500
Subject: [PATCH 05/15] remove more files frm fern ignore temporarily
---
.fernignore | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/.fernignore b/.fernignore
index 76a3cde..2a80fcd 100644
--- a/.fernignore
+++ b/.fernignore
@@ -5,50 +5,30 @@ LICENSE
assemblyai.png
icon.png
.gitignore
-.github/workflows/ci.yml
.github/workflows/publish-reference.yml
src/AssemblyAI.sln
-src/AssemblyAI/AssemblyAI.csproj
-src/AssemblyAI/Core/JsonConfiguration.cs
src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs
src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs
src/AssemblyAI/Core/Public/ClientOptions.cs
src/AssemblyAI/Core/Public/ApiException.cs
src/AssemblyAI/Core/Public/AssemblyAIException.cs
-src/AssemblyAI/Core/StringEnumSerializer.cs
-src/AssemblyAI/Core/CustomConstants.cs
-src/AssemblyAI/Types/Error.cs
src/AssemblyAI/UserAgent.cs
src/AssemblyAI/Event.cs
-src/AssemblyAI/AssemblyAIClient.cs
src/AssemblyAI/DependencyInjectionExtensions.cs
-src/AssemblyAI/EnumConverter.cs
src/AssemblyAI/Files/ExtendedFilesClient.cs
src/AssemblyAI/Transcripts/ExtendedTranscriptsClient.cs
src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsMapper.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsCloner.cs
src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs
-src/AssemblyAI/Lemur/Types/LemurResponse.cs
-src/AssemblyAI/Lemur/Types/LemurModel.cs
src/AssemblyAI/Lemur/ExtendedLemurClient.cs
src/AssemblyAI/Realtime/RealtimeTranscriber.cs
src/AssemblyAI/Realtime/WebsocketClient
-src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
src/AssemblyAI/Realtime/ExtendedRealtimeClient.cs
src/AssemblyAI/Realtime/RealtimeTranscriberOptions.cs
-src/AssemblyAI/Realtime/Types/TerminateSession.cs
-src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
-src/AssemblyAI/Realtime/Types/Realtime.cs
-src/AssemblyAI.Test
src/AssemblyAI.UnitTests
src/AssemblyAI.IntegrationTests
docfx
-
-# TODO: remove these ignores when AssemblyAI fixes the API
-src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
-src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
-
Samples
From a422b94684c46e217c73065635b9d07db1717371 Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Tue, 21 Jan 2025 15:31:21 +0000
Subject: [PATCH 06/15] SDK regeneration
---
.github/workflows/ci.yml | 42 +++----
.../AssemblyAI.Test.Custom.props | 7 ++
src/AssemblyAI.Test/AssemblyAI.Test.csproj | 33 +++++
.../Core/EnumSerializerTests.cs | 61 ++++++++++
src/AssemblyAI.Test/Core/RawClientTests.cs | 113 ++++++++++++++++++
src/AssemblyAI.Test/TestClient.cs | 8 ++
src/AssemblyAI/AssemblyAI.csproj | 91 ++------------
src/AssemblyAI/AssemblyAIClient.cs | 82 ++++++-------
src/AssemblyAI/Core/JsonConfiguration.cs | 110 +++--------------
src/AssemblyAI/Core/StringEnumSerializer.cs | 60 ----------
src/AssemblyAI/EnumConverter.cs | 27 -----
src/AssemblyAI/Lemur/Types/LemurModel.cs | 6 +-
src/AssemblyAI/Lemur/Types/LemurResponse.cs | 21 ----
.../Realtime/Types/ForceEndUtterance.cs | 20 ++++
src/AssemblyAI/Realtime/Types/Realtime.cs | 17 +++
.../Realtime/Types/RealtimeTranscript.cs | 19 ---
.../Realtime/Types/TerminateSession.cs | 20 ++++
.../Types/ContentSafetyLabelsResult.cs | 12 +-
.../Types/TopicDetectionModelResult.cs | 9 +-
src/AssemblyAI/Types/Error.cs | 23 ++++
20 files changed, 399 insertions(+), 382 deletions(-)
create mode 100644 src/AssemblyAI.Test/AssemblyAI.Test.Custom.props
create mode 100644 src/AssemblyAI.Test/AssemblyAI.Test.csproj
create mode 100644 src/AssemblyAI.Test/Core/EnumSerializerTests.cs
create mode 100644 src/AssemblyAI.Test/Core/RawClientTests.cs
create mode 100644 src/AssemblyAI.Test/TestClient.cs
delete mode 100644 src/AssemblyAI/Core/StringEnumSerializer.cs
delete mode 100644 src/AssemblyAI/EnumConverter.cs
delete mode 100644 src/AssemblyAI/Lemur/Types/LemurResponse.cs
create mode 100644 src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
create mode 100644 src/AssemblyAI/Realtime/Types/Realtime.cs
delete mode 100644 src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
create mode 100644 src/AssemblyAI/Realtime/Types/TerminateSession.cs
create mode 100644 src/AssemblyAI/Types/Error.cs
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 86fbd20..810c2ca 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,16 +4,16 @@ on: [push]
jobs:
compile:
- name: Compile
runs-on: ubuntu-latest
- env:
- DOTNET_NOLOGO: true
+
steps:
- name: Checkout repo
- uses: actions/checkout@v4
+ uses: actions/checkout@v3
+
+ - uses: actions/checkout@master
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.x
@@ -24,29 +24,19 @@ jobs:
- name: Build Release
run: dotnet build src -c Release /p:ContinuousIntegrationBuild=true
- tests:
- strategy:
- fail-fast: false
- matrix:
- framework: [net462, net6.0]
- os: [ubuntu-latest, windows-latest]
- exclude:
- - os: ubuntu-latest
- framework: net462
- name: Run Tests on ${{ matrix.os }} with ${{ matrix.framework }}
+ unit-tests:
runs-on: ubuntu-latest
+
steps:
- name: Checkout repo
- uses: actions/checkout@v4
+ uses: actions/checkout@v3
- uses: actions/checkout@master
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v1
with:
- dotnet-version: |
- 8.x
- 6.x
+ dotnet-version: 8.x
- name: Install tools
run: |
@@ -54,24 +44,20 @@ jobs:
- name: Run Tests
run: |
- dotnet test src --framework ${{ matrix.framework }}
- env:
- ASSEMBLYAI_API_KEY: ${{ secrets.ASSEMBLYAI_API_KEY }}
- TEST_TRANSCRIPT_ID: ${{ secrets.TEST_TRANSCRIPT_ID }}
- TEST_TRANSCRIPT_IDS: ${{ secrets.TEST_TRANSCRIPT_IDS }}
+ dotnet test src
+
publish:
- name: Publish to NuGet
needs: [compile]
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Checkout repo
- uses: actions/checkout@v4
+ uses: actions/checkout@v3
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.x
diff --git a/src/AssemblyAI.Test/AssemblyAI.Test.Custom.props b/src/AssemblyAI.Test/AssemblyAI.Test.Custom.props
new file mode 100644
index 0000000..55e683b
--- /dev/null
+++ b/src/AssemblyAI.Test/AssemblyAI.Test.Custom.props
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/src/AssemblyAI.Test/AssemblyAI.Test.csproj b/src/AssemblyAI.Test/AssemblyAI.Test.csproj
new file mode 100644
index 0000000..44d0560
--- /dev/null
+++ b/src/AssemblyAI.Test/AssemblyAI.Test.csproj
@@ -0,0 +1,33 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/AssemblyAI.Test/Core/EnumSerializerTests.cs b/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
new file mode 100644
index 0000000..32fdcb7
--- /dev/null
+++ b/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Runtime.Serialization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using AssemblyAI.Core;
+using NUnit.Framework;
+
+namespace AssemblyAI.Test.Core
+{
+ [TestFixture]
+ public class StringEnumSerializerTests
+ {
+ private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
+
+ private const DummyEnum KnownEnumValue2 = DummyEnum.KnownValue2;
+ private const string KnownEnumValue2String = "known_value2";
+
+ private static readonly string JsonWithKnownEnum2 = $$"""
+ {
+ "enum_property": "{{KnownEnumValue2String}}"
+ }
+ """;
+
+ [Test]
+ public void ShouldParseKnownEnumValue2()
+ {
+ var obj = JsonSerializer.Deserialize(JsonWithKnownEnum2, JsonOptions);
+ Assert.That(obj, Is.Not.Null);
+ Assert.That(obj.EnumProperty, Is.EqualTo(KnownEnumValue2));
+ }
+
+ [Test]
+ public void ShouldSerializeKnownEnumValue2()
+ {
+ var json = JsonSerializer.SerializeToElement(
+ new DummyObject { EnumProperty = KnownEnumValue2 },
+ JsonOptions
+ );
+ TestContext.Out.WriteLine("Serialized JSON: \n" + json);
+ var enumString = json.GetProperty("enum_property").GetString();
+ Assert.That(enumString, Is.Not.Null);
+ Assert.That(enumString, Is.EqualTo(KnownEnumValue2String));
+ }
+ }
+
+ public class DummyObject
+ {
+ [JsonPropertyName("enum_property")]
+ public DummyEnum EnumProperty { get; set; }
+ }
+
+ [JsonConverter(typeof(EnumSerializer))]
+ public enum DummyEnum
+ {
+ [EnumMember(Value = "known_value1")]
+ KnownValue1,
+
+ [EnumMember(Value = "known_value2")]
+ KnownValue2,
+ }
+}
diff --git a/src/AssemblyAI.Test/Core/RawClientTests.cs b/src/AssemblyAI.Test/Core/RawClientTests.cs
new file mode 100644
index 0000000..d9a8d70
--- /dev/null
+++ b/src/AssemblyAI.Test/Core/RawClientTests.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Net.Http;
+using AssemblyAI.Core;
+using FluentAssertions;
+using NUnit.Framework;
+using WireMock.Server;
+using SystemTask = System.Threading.Tasks.Task;
+using WireMockRequest = WireMock.RequestBuilders.Request;
+using WireMockResponse = WireMock.ResponseBuilders.Response;
+
+namespace AssemblyAI.Test.Core
+{
+ [TestFixture]
+ public class RawClientTests
+ {
+ private WireMockServer _server;
+ private HttpClient _httpClient;
+ private RawClient _rawClient;
+ private string _baseUrl;
+ private const int _maxRetries = 3;
+
+ [SetUp]
+ public void SetUp()
+ {
+ _server = WireMockServer.Start();
+ _baseUrl = _server.Url ?? "";
+ _httpClient = new HttpClient { BaseAddress = new Uri(_baseUrl) };
+ _rawClient = new RawClient(
+ new ClientOptions() { HttpClient = _httpClient, MaxRetries = _maxRetries }
+ );
+ }
+
+ [Test]
+ [TestCase(408)]
+ [TestCase(429)]
+ [TestCase(500)]
+ [TestCase(504)]
+ public async SystemTask MakeRequestAsync_ShouldRetry_OnRetryableStatusCodes(int statusCode)
+ {
+ _server
+ .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
+ .InScenario("Retry")
+ .WillSetStateTo("Server Error")
+ .RespondWith(WireMockResponse.Create().WithStatusCode(statusCode));
+
+ _server
+ .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
+ .InScenario("Retry")
+ .WhenStateIs("Server Error")
+ .WillSetStateTo("Success")
+ .RespondWith(WireMockResponse.Create().WithStatusCode(statusCode));
+
+ _server
+ .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
+ .InScenario("Retry")
+ .WhenStateIs("Success")
+ .RespondWith(WireMockResponse.Create().WithStatusCode(200).WithBody("Success"));
+
+ var request = new RawClient.BaseApiRequest
+ {
+ BaseUrl = _baseUrl,
+ Method = HttpMethod.Get,
+ Path = "/test",
+ };
+
+ var response = await _rawClient.MakeRequestAsync(request);
+ Assert.That(response.StatusCode, Is.EqualTo(200));
+
+ var content = await response.Raw.Content.ReadAsStringAsync();
+ Assert.That(content, Is.EqualTo("Success"));
+
+ Assert.That(_server.LogEntries.Count, Is.EqualTo(_maxRetries));
+ }
+
+ [Test]
+ [TestCase(400)]
+ [TestCase(409)]
+ public async SystemTask MakeRequestAsync_ShouldRetry_OnNonRetryableStatusCodes(
+ int statusCode
+ )
+ {
+ _server
+ .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
+ .InScenario("Retry")
+ .WillSetStateTo("Server Error")
+ .RespondWith(
+ WireMockResponse.Create().WithStatusCode(statusCode).WithBody("Failure")
+ );
+
+ var request = new RawClient.BaseApiRequest
+ {
+ BaseUrl = _baseUrl,
+ Method = HttpMethod.Get,
+ Path = "/test",
+ };
+
+ var response = await _rawClient.MakeRequestAsync(request);
+ Assert.That(response.StatusCode, Is.EqualTo(statusCode));
+
+ var content = await response.Raw.Content.ReadAsStringAsync();
+ Assert.That(content, Is.EqualTo("Failure"));
+
+ Assert.That(_server.LogEntries.Count, Is.EqualTo(1));
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ _server.Dispose();
+ _httpClient.Dispose();
+ }
+ }
+}
diff --git a/src/AssemblyAI.Test/TestClient.cs b/src/AssemblyAI.Test/TestClient.cs
new file mode 100644
index 0000000..c8c868b
--- /dev/null
+++ b/src/AssemblyAI.Test/TestClient.cs
@@ -0,0 +1,8 @@
+using NUnit.Framework;
+
+#nullable enable
+
+namespace AssemblyAI.Test;
+
+[TestFixture]
+public class TestClient { }
diff --git a/src/AssemblyAI/AssemblyAI.csproj b/src/AssemblyAI/AssemblyAI.csproj
index 2213c92..593c6d6 100644
--- a/src/AssemblyAI/AssemblyAI.csproj
+++ b/src/AssemblyAI/AssemblyAI.csproj
@@ -1,109 +1,44 @@
+
net462;net8.0;net7.0;net6.0;netstandard2.0enable
- false12enable
- AssemblyAI
- AssemblyAI
- AssemblyAI
- 1.2.0
- 1.2.0.0
- 1.2.0.0
- 1.2.0
- AssemblyAI C# .NET SDK
- AssemblyAI
- The AssemblyAI C# .NET SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, audio intelligence models, as well as the latest LeMUR models.
- Copyright 2024 (c) AssemblyAI, Inc. All rights reserved.
- ASR;Speech-To-Text;STT;Speech;AI;AssemblyAI
- AssemblyAI
- AssemblyAI
- Library
- MIT
- https://github.com/AssemblyAI/assemblyai-csharp-sdk
- https://github.com/AssemblyAI/assemblyai-csharp-sdk.git
- https://www.assemblyai.com/favicon.png
- icon.png
+ 1.2.1
+ $(Version)
+ $(Version)README.md
- true
- true
- true
- snupkg
- git
-
-
- true
-
-
-
-
-
-
-
-
+ https://github.com/AssemblyAI/assemblyai-csharp-sdktrue
-
-
-
-
-
+
-
-
+
+ runtime; build; native; contentfiles; analyzers; buildtransitiveall
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
- <_Parameter1>AssemblyAI.UnitTests
+ <_Parameter1>AssemblyAI.Test
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/AssemblyAI/AssemblyAIClient.cs b/src/AssemblyAI/AssemblyAIClient.cs
index 6f14267..1da89d8 100644
--- a/src/AssemblyAI/AssemblyAIClient.cs
+++ b/src/AssemblyAI/AssemblyAIClient.cs
@@ -1,63 +1,49 @@
-using System.Net.Http;
using AssemblyAI.Core;
using AssemblyAI.Files;
using AssemblyAI.Lemur;
using AssemblyAI.Realtime;
using AssemblyAI.Transcripts;
+#nullable enable
namespace AssemblyAI;
-///
-/// The client to interact with the AssemblyAI API.
-///
-public class AssemblyAIClient
+public partial 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
- })
- {
- }
+ private RawClient _client;
- ///
- /// Create a new instance of the class.
- ///
- /// The AssemblyAI client options
- /// Thrown if ClientOptions.ApiKey is null or empty.
- public AssemblyAIClient(ClientOptions clientOptions)
+ public AssemblyAIClient(string? apiKey = null, ClientOptions? clientOptions = null)
{
- if (string.IsNullOrEmpty(clientOptions.ApiKey))
+ var defaultHeaders = new Headers(
+ new Dictionary()
+ {
+ { "Authorization", apiKey },
+ { "X-Fern-Language", "C#" },
+ { "X-Fern-SDK-Name", "AssemblyAI" },
+ { "X-Fern-SDK-Version", Version.Current },
+ { "User-Agent", "AssemblyAI/1.2.1" },
+ }
+ );
+ clientOptions ??= new ClientOptions();
+ foreach (var header in defaultHeaders)
{
- throw new ArgumentException("AssemblyAI API Key is required.");
+ if (!clientOptions.Headers.ContainsKey(header.Key))
+ {
+ clientOptions.Headers[header.Key] = header.Value;
+ }
}
-
- // ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
- clientOptions.HttpClient ??= new HttpClient();
- clientOptions.Headers.Add("Authorization", clientOptions.ApiKey);
- clientOptions.Headers.Add("User-Agent", new UserAgent(UserAgent.Default, clientOptions.UserAgent).ToAssemblyAIUserAgentString());
- var client = new RawClient(clientOptions);
-
- Files = new FilesClient(client);
- Transcripts = new ExtendedTranscriptsClient(client, this);
- Realtime = new RealtimeClient(client);
- Lemur = new LemurClient(client);
+ _client = new RawClient(clientOptions);
+ Files = new FilesClient(_client);
+ Transcripts = new TranscriptsClient(_client);
+ Realtime = new RealtimeClient(_client);
+ Lemur = new LemurClient(_client);
}
-}
\ No newline at end of file
+
+ public FilesClient Files { get; init; }
+
+ public TranscriptsClient Transcripts { get; init; }
+
+ public RealtimeClient Realtime { get; init; }
+
+ public LemurClient Lemur { get; init; }
+}
diff --git a/src/AssemblyAI/Core/JsonConfiguration.cs b/src/AssemblyAI/Core/JsonConfiguration.cs
index 7606b88..769365f 100644
--- a/src/AssemblyAI/Core/JsonConfiguration.cs
+++ b/src/AssemblyAI/Core/JsonConfiguration.cs
@@ -1,110 +1,36 @@
using System.Text.Json;
-using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
-using AssemblyAI.Lemur;
-using OneOf;
namespace AssemblyAI.Core;
-///
-/// The JSON options used by the AssemblyAI SDK.
-///
-internal static class JsonOptions
+internal static partial class JsonOptions
{
- ///
- /// The JSON options used by the AssemblyAI SDK.
- ///
- internal static readonly JsonSerializerOptions JsonSerializerOptions;
+ public static readonly JsonSerializerOptions JsonSerializerOptions;
static JsonOptions()
{
- JsonSerializerOptions = new JsonSerializerOptions
+ var options = new JsonSerializerOptions
{
- Converters =
- {
- new DateTimeSerializer(),
- new OneOfSerializer>()
- },
+ Converters = { new DateTimeSerializer(), new OneOfSerializer() },
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
+ ConfigureJsonSerializerOptions(options);
+ JsonSerializerOptions = options;
}
+
+ static partial void ConfigureJsonSerializerOptions(JsonSerializerOptions defaultOptions);
}
-///
-/// Utilities class for JSON serialization and deserialization.
-///
-public static class JsonUtils
+internal static class JsonUtils
{
- ///
- /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
- ///
- /// Object to serialize
- /// Type of the object to serialize
- /// The object serialized as JSON
- public static string Serialize(T obj)
- => JsonSerializer.Serialize(obj, JsonOptions.JsonSerializerOptions);
-
- ///
- /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
- ///
- /// Object to serialize
- /// Type of the object to serialize
- /// The object serialized as JSON
- public static JsonDocument SerializeToDocument(T obj)
- => JsonSerializer.SerializeToDocument(obj, JsonOptions.JsonSerializerOptions);
-
- ///
- /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
- ///
- /// Object to serialize
- /// Type of the object to serialize
- /// The object serialized as JSON
- public static JsonElement SerializeToElement(T obj)
- => JsonSerializer.SerializeToElement(obj, JsonOptions.JsonSerializerOptions);
-
- ///
- /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
- ///
- /// Object to serialize
- /// Type of the object to serialize
- /// The object serialized as JSON
- public static JsonNode? SerializeToNode(T obj)
- => JsonSerializer.SerializeToNode(obj, JsonOptions.JsonSerializerOptions);
-
- ///
- /// Deserialize a JSON string to an object using the AssemblyAI SDKs JSON options.
- ///
- /// The JSON string
- /// The type to deserialize the JSON to
- /// The deserialized object of type T
- public static T Deserialize(string json)
- => JsonSerializer.Deserialize(json, JsonOptions.JsonSerializerOptions)!;
-
- ///
- /// Deserialize a JSON document to an object using the AssemblyAI SDKs JSON options.
- ///
- /// The JSON string
- /// The type to deserialize the JSON to
- /// The deserialized object of type T
- public static T Deserialize(JsonDocument json)
- => json.Deserialize(JsonOptions.JsonSerializerOptions)!;
-
- ///
- /// Deserialize a JSON element to an object using the AssemblyAI SDKs JSON options.
- ///
- /// The JSON string
- /// The type to deserialize the JSON to
- /// The deserialized object of type T
- public static T Deserialize(JsonElement json)
- => json.Deserialize(JsonOptions.JsonSerializerOptions)!;
+ public static string Serialize(T obj)
+ {
+ return JsonSerializer.Serialize(obj, JsonOptions.JsonSerializerOptions);
+ }
- ///
- /// Deserialize a JSON node to an object using the AssemblyAI SDKs JSON options.
- ///
- /// The JSON string
- /// The type to deserialize the JSON to
- /// The deserialized object of type T
- public static T Deserialize(JsonNode json)
- => json.Deserialize(JsonOptions.JsonSerializerOptions)!;
-}
\ No newline at end of file
+ public static T Deserialize(string json)
+ {
+ return JsonSerializer.Deserialize(json, JsonOptions.JsonSerializerOptions)!;
+ }
+}
diff --git a/src/AssemblyAI/Core/StringEnumSerializer.cs b/src/AssemblyAI/Core/StringEnumSerializer.cs
deleted file mode 100644
index 9b53fef..0000000
--- a/src/AssemblyAI/Core/StringEnumSerializer.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System.Runtime.Serialization;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace AssemblyAI.Core;
-
-internal class StringEnumSerializer : JsonConverter
- where TEnum : struct, System.Enum
-{
- private readonly Dictionary _enumToString = new();
- private readonly Dictionary _stringToEnum = new();
-
- public StringEnumSerializer()
- {
- var type = typeof(TEnum);
- var values = Enum.GetValues(type);
-
- foreach (var value in values)
- {
- var enumValue = (TEnum)value;
- var enumMember = type.GetMember(enumValue.ToString())[0];
- var attr = enumMember
- .GetCustomAttributes(typeof(EnumMemberAttribute), false)
- .Cast()
- .FirstOrDefault();
-
- var stringValue =
- attr?.Value
- ?? value.ToString()
- ?? throw new Exception("Unexpected null enum toString value");
-
- if(!_enumToString.ContainsKey(enumValue))
- {
- _enumToString.Add(enumValue, stringValue);
- }
-
- if (!_stringToEnum.ContainsKey(stringValue))
- {
- _stringToEnum.Add(stringValue, enumValue);
- }
- }
- }
-
- public override TEnum Read(
- ref Utf8JsonReader reader,
- System.Type typeToConvert,
- JsonSerializerOptions options
- )
- {
- var stringValue =
- reader.GetString()
- ?? throw new Exception("The JSON value could not be read as a string.");
- return _stringToEnum.TryGetValue(stringValue, out var enumValue) ? enumValue : default;
- }
-
- public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
- {
- writer.WriteStringValue(_enumToString[value]);
- }
-}
diff --git a/src/AssemblyAI/EnumConverter.cs b/src/AssemblyAI/EnumConverter.cs
deleted file mode 100644
index 6384bd2..0000000
--- a/src/AssemblyAI/EnumConverter.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using AssemblyAI.Core;
-
-namespace AssemblyAI;
-
-///
-/// Convert an AssemblyAI enum to a string and vice versa.
-///
-public static class EnumConverter
-{
- ///
- /// Convert a string value to an enum. For example, "en_us" to TranscriptLanguageCode.EnUs.
- ///
- /// String value of the enum
- /// The enum type to convert into
- /// An enum value of the given enum type
- /// This method uses the Value property of EnumMemberAttribute on the given enum value.
- public static T ToEnum(string value) where T : Enum => JsonUtils.Deserialize($"\"{value}\"");
-
- ///
- /// Convert an enum value to a string value. For example, TranscriptLanguageCode.EnUs to "en_us".
- ///
- /// Enum value
- ///
- /// The string value of the given enum
- /// This method uses the Value property of EnumMemberAttribute on the given enum value.
- public static string ToString(T value) where T : Enum => JsonUtils.Serialize(value).Trim('"');
-}
\ No newline at end of file
diff --git a/src/AssemblyAI/Lemur/Types/LemurModel.cs b/src/AssemblyAI/Lemur/Types/LemurModel.cs
index bf1b231..941b238 100644
--- a/src/AssemblyAI/Lemur/Types/LemurModel.cs
+++ b/src/AssemblyAI/Lemur/Types/LemurModel.cs
@@ -6,7 +6,7 @@
namespace AssemblyAI.Lemur;
-[JsonConverter(typeof(StringEnumSerializer))]
+[JsonConverter(typeof(EnumSerializer))]
public enum LemurModel
{
[EnumMember(Value = "anthropic/claude-3-5-sonnet")]
@@ -27,10 +27,6 @@ public enum LemurModel
[EnumMember(Value = "anthropic/claude-2")]
AnthropicClaude2_0,
- [EnumMember(Value = "anthropic/claude-2")]
- [Obsolete("Use AnthropicClaude2_0")]
- AnthropicClaude2,
-
[EnumMember(Value = "default")]
Default,
diff --git a/src/AssemblyAI/Lemur/Types/LemurResponse.cs b/src/AssemblyAI/Lemur/Types/LemurResponse.cs
deleted file mode 100644
index 345ccc4..0000000
--- a/src/AssemblyAI/Lemur/Types/LemurResponse.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Text.Json.Serialization;
-using AssemblyAI.Core;
-using OneOf;
-
-namespace AssemblyAI.Lemur;
-
-public class LemurResponse : OneOfBase
-{
- private LemurResponse(OneOf response) : base(response)
- {
- }
-
- public static implicit operator LemurResponse(OneOf _) => new(_);
- public static implicit operator LemurResponse(LemurStringResponse _) => new(_);
- public static implicit operator LemurResponse(LemurQuestionAnswerResponse _) => new(_);
-
- public bool IsLemurStringResponse => IsT0;
- public bool IsLemurQuestionAnswerResponse => IsT1;
- public LemurStringResponse AsLemurStringResponse => AsT0;
- public LemurQuestionAnswerResponse AsLemurQuestionAnswerResponse => AsT1;
-}
\ No newline at end of file
diff --git a/src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs b/src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
new file mode 100644
index 0000000..1ceef1a
--- /dev/null
+++ b/src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
@@ -0,0 +1,20 @@
+using System.Text.Json.Serialization;
+using AssemblyAI.Core;
+
+#nullable enable
+
+namespace AssemblyAI.Realtime;
+
+public record ForceEndUtterance
+{
+ ///
+ /// A boolean value to communicate that you wish to force the end of the utterance
+ ///
+ [JsonPropertyName("force_end_utterance")]
+ public required bool ForceEndUtterance_ { get; set; }
+
+ public override string ToString()
+ {
+ return JsonUtils.Serialize(this);
+ }
+}
diff --git a/src/AssemblyAI/Realtime/Types/Realtime.cs b/src/AssemblyAI/Realtime/Types/Realtime.cs
new file mode 100644
index 0000000..a0a389b
--- /dev/null
+++ b/src/AssemblyAI/Realtime/Types/Realtime.cs
@@ -0,0 +1,17 @@
+using System.Runtime.Serialization;
+using System.Text.Json.Serialization;
+using AssemblyAI.Core;
+
+#nullable enable
+
+namespace AssemblyAI.Realtime;
+
+[JsonConverter(typeof(EnumSerializer))]
+public enum Realtime
+{
+ [EnumMember(Value = "pcm_s16le")]
+ PcmS16le,
+
+ [EnumMember(Value = "pcm_mulaw")]
+ PcmMulaw,
+}
diff --git a/src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs b/src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
deleted file mode 100644
index 9c03d21..0000000
--- a/src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using OneOf;
-
-// ReSharper disable once CheckNamespace
-namespace AssemblyAI.Realtime;
-
-public class RealtimeTranscript : OneOfBase
-{
- private RealtimeTranscript(OneOf transcript) : base(transcript)
- {
- }
-
- public static implicit operator RealtimeTranscript(PartialTranscript _) => new(_);
- public static implicit operator RealtimeTranscript(FinalTranscript _) => new(_);
-
- public bool IsPartialTranscript => IsT0;
- public bool IsFinalTranscript => IsT1;
- public PartialTranscript AsPartialTranscript => AsT0;
- public FinalTranscript AsFinalTranscript => AsT1;
-}
\ No newline at end of file
diff --git a/src/AssemblyAI/Realtime/Types/TerminateSession.cs b/src/AssemblyAI/Realtime/Types/TerminateSession.cs
new file mode 100644
index 0000000..c61ade6
--- /dev/null
+++ b/src/AssemblyAI/Realtime/Types/TerminateSession.cs
@@ -0,0 +1,20 @@
+using System.Text.Json.Serialization;
+using AssemblyAI.Core;
+
+#nullable enable
+
+namespace AssemblyAI.Realtime;
+
+public record TerminateSession
+{
+ ///
+ /// Set to true to end your streaming session forever
+ ///
+ [JsonPropertyName("terminate_session")]
+ public required bool TerminateSession_ { get; set; }
+
+ public override string ToString()
+ {
+ return JsonUtils.Serialize(this);
+ }
+}
diff --git a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
index da73443..5b5c57e 100644
--- a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Serialization;
-using AssemblyAI.Transcripts;
+using AssemblyAI.Core;
#nullable enable
@@ -11,8 +11,11 @@ public record ContentSafetyLabelsResult
/// The status of the Content Moderation model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public AudioIntelligenceModelStatus Status { get; set; }
+ public required AudioIntelligenceModelStatus Status { get; set; }
+ ///
+ /// An array of results for the Content Moderation model
+ ///
[JsonPropertyName("results")]
public IEnumerable Results { get; set; } =
new List();
@@ -29,4 +32,9 @@ public record ContentSafetyLabelsResult
[JsonPropertyName("severity_score_summary")]
public Dictionary SeverityScoreSummary { get; set; } =
new Dictionary();
+
+ public override string ToString()
+ {
+ return JsonUtils.Serialize(this);
+ }
}
diff --git a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
index fa7d26f..b7a7714 100644
--- a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
@@ -1,5 +1,5 @@
using System.Text.Json.Serialization;
-using AssemblyAI.Transcripts;
+using AssemblyAI.Core;
#nullable enable
@@ -11,7 +11,7 @@ public record TopicDetectionModelResult
/// The status of the Topic Detection model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public AudioIntelligenceModelStatus Status { get; set; }
+ public required AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Topic Detection model
@@ -25,4 +25,9 @@ public record TopicDetectionModelResult
///
[JsonPropertyName("summary")]
public Dictionary Summary { get; set; } = new Dictionary();
+
+ public override string ToString()
+ {
+ return JsonUtils.Serialize(this);
+ }
}
diff --git a/src/AssemblyAI/Types/Error.cs b/src/AssemblyAI/Types/Error.cs
new file mode 100644
index 0000000..0764cb8
--- /dev/null
+++ b/src/AssemblyAI/Types/Error.cs
@@ -0,0 +1,23 @@
+using System.Text.Json.Serialization;
+using AssemblyAI.Core;
+
+#nullable enable
+
+namespace AssemblyAI;
+
+public record Error
+{
+ ///
+ /// Error message
+ ///
+ [JsonPropertyName("error")]
+ public required string Error_ { get; set; }
+
+ [JsonPropertyName("status")]
+ public string? Status { get; set; }
+
+ public override string ToString()
+ {
+ return JsonUtils.Serialize(this);
+ }
+}
From e91c97c2890054ec7388ddc2642b960fa8687904 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 11:25:24 -0500
Subject: [PATCH 07/15] Undo undesired changes/fix solution
---
.fernignore | 28 ++++-
.github/workflows/ci.yml | 42 ++++---
.../Core/EnumSerializerTests.cs | 2 +-
src/AssemblyAI.Test/Core/RawClientTests.cs | 113 ------------------
src/AssemblyAI.Test/TestClient.cs | 8 --
.../AssemblyAI.UnitTests.csproj | 10 +-
src/AssemblyAI.sln | 10 +-
src/AssemblyAI/AssemblyAI.Custom.props | 56 +++++++--
src/AssemblyAI/AssemblyAI.csproj | 1 -
src/AssemblyAI/AssemblyAIClient.cs | 82 +++++++------
src/AssemblyAI/Core/EnumSerializer.cs | 11 +-
src/AssemblyAI/Core/JsonConfiguration.cs | 82 +++++++++++--
src/AssemblyAI/Core/Public/ClientOptions.cs | 15 ---
.../Core/Public/ExtendedClientOptions.cs | 19 +++
src/AssemblyAI/EnumConverter.cs | 27 +++++
src/AssemblyAI/Lemur/Types/LemurModel.cs | 4 +
src/AssemblyAI/Lemur/Types/LemurResponse.cs | 21 ++++
.../Realtime/Types/ForceEndUtterance.cs | 20 ----
src/AssemblyAI/Realtime/Types/Realtime.cs | 17 ---
.../Realtime/Types/RealtimeTranscript.cs | 19 +++
.../Realtime/Types/TerminateSession.cs | 20 ----
.../Types/ContentSafetyLabelsResult.cs | 3 +-
.../Types/TopicDetectionModelResult.cs | 3 +-
src/AssemblyAI/Types/Error.cs | 23 ----
src/AssemblyAI/UserAgent.cs | 16 +++
25 files changed, 355 insertions(+), 297 deletions(-)
delete mode 100644 src/AssemblyAI.Test/Core/RawClientTests.cs
delete mode 100644 src/AssemblyAI.Test/TestClient.cs
create mode 100644 src/AssemblyAI/EnumConverter.cs
create mode 100644 src/AssemblyAI/Lemur/Types/LemurResponse.cs
delete mode 100644 src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
delete mode 100644 src/AssemblyAI/Realtime/Types/Realtime.cs
create mode 100644 src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
delete mode 100644 src/AssemblyAI/Realtime/Types/TerminateSession.cs
delete mode 100644 src/AssemblyAI/Types/Error.cs
diff --git a/.fernignore b/.fernignore
index 2a80fcd..d7bf0cc 100644
--- a/.fernignore
+++ b/.fernignore
@@ -5,29 +5,47 @@ LICENSE
assemblyai.png
icon.png
.gitignore
+.github/workflows/ci.yml
.github/workflows/publish-reference.yml
src/AssemblyAI.sln
+src/AssemblyAI/AssemblyAI.Custom.props
+src/AssemblyAI/AssemblyAIClient.cs
+src/AssemblyAI/UserAgent.cs
+src/AssemblyAI/Event.cs
+src/AssemblyAI/DependencyInjectionExtensions.cs
+src/AssemblyAI/EnumConverter.cs
+src/AssemblyAI/Types/Error.cs
+src/AssemblyAI/Core/EnumSerializer.cs
+src/AssemblyAI/Core/JsonConfiguration.cs
src/AssemblyAI/Core/Public/ExtendedRequestOptions.cs
-src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
src/AssemblyAI/Core/Public/AssemblyAIClientEnvironment.cs
src/AssemblyAI/Core/Public/ClientOptions.cs
+src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
src/AssemblyAI/Core/Public/ApiException.cs
src/AssemblyAI/Core/Public/AssemblyAIException.cs
-src/AssemblyAI/UserAgent.cs
-src/AssemblyAI/Event.cs
-src/AssemblyAI/DependencyInjectionExtensions.cs
src/AssemblyAI/Files/ExtendedFilesClient.cs
src/AssemblyAI/Transcripts/ExtendedTranscriptsClient.cs
+src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs
src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsMapper.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsCloner.cs
-src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs
+src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
+src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
src/AssemblyAI/Lemur/ExtendedLemurClient.cs
+src/AssemblyAI/Lemur/Types/LemurResponse.cs
+src/AssemblyAI/Lemur/Types/LemurModel.cs
src/AssemblyAI/Realtime/RealtimeTranscriber.cs
src/AssemblyAI/Realtime/WebsocketClient
src/AssemblyAI/Realtime/ExtendedRealtimeClient.cs
src/AssemblyAI/Realtime/RealtimeTranscriberOptions.cs
+src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
+src/AssemblyAI/Realtime/Types/TerminateSession.cs
+src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
+src/AssemblyAI/Realtime/Types/Realtime.cs
+src/AssemblyAI.Test/TestClient.cs
+src/AssemblyAI.Test/Core/RawClientTests.cs
src/AssemblyAI.UnitTests
+
src/AssemblyAI.IntegrationTests
docfx
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 810c2ca..86fbd20 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,16 +4,16 @@ on: [push]
jobs:
compile:
+ name: Compile
runs-on: ubuntu-latest
-
+ env:
+ DOTNET_NOLOGO: true
steps:
- name: Checkout repo
- uses: actions/checkout@v3
-
- - uses: actions/checkout@master
+ uses: actions/checkout@v4
- name: Setup .NET
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x
@@ -24,19 +24,29 @@ jobs:
- name: Build Release
run: dotnet build src -c Release /p:ContinuousIntegrationBuild=true
- unit-tests:
+ tests:
+ strategy:
+ fail-fast: false
+ matrix:
+ framework: [net462, net6.0]
+ os: [ubuntu-latest, windows-latest]
+ exclude:
+ - os: ubuntu-latest
+ framework: net462
+ name: Run Tests on ${{ matrix.os }} with ${{ matrix.framework }}
runs-on: ubuntu-latest
-
steps:
- name: Checkout repo
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- uses: actions/checkout@master
- name: Setup .NET
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: |
+ 8.x
+ 6.x
- name: Install tools
run: |
@@ -44,20 +54,24 @@ jobs:
- name: Run Tests
run: |
- dotnet test src
-
+ dotnet test src --framework ${{ matrix.framework }}
+ env:
+ ASSEMBLYAI_API_KEY: ${{ secrets.ASSEMBLYAI_API_KEY }}
+ TEST_TRANSCRIPT_ID: ${{ secrets.TEST_TRANSCRIPT_ID }}
+ TEST_TRANSCRIPT_IDS: ${{ secrets.TEST_TRANSCRIPT_IDS }}
publish:
+ name: Publish to NuGet
needs: [compile]
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Checkout repo
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup .NET
- uses: actions/setup-dotnet@v1
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x
diff --git a/src/AssemblyAI.Test/Core/EnumSerializerTests.cs b/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
index 32fdcb7..ad33b46 100644
--- a/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
+++ b/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
@@ -8,7 +8,7 @@
namespace AssemblyAI.Test.Core
{
[TestFixture]
- public class StringEnumSerializerTests
+ public class EnumSerializerTests
{
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
diff --git a/src/AssemblyAI.Test/Core/RawClientTests.cs b/src/AssemblyAI.Test/Core/RawClientTests.cs
deleted file mode 100644
index d9a8d70..0000000
--- a/src/AssemblyAI.Test/Core/RawClientTests.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-using System;
-using System.Net.Http;
-using AssemblyAI.Core;
-using FluentAssertions;
-using NUnit.Framework;
-using WireMock.Server;
-using SystemTask = System.Threading.Tasks.Task;
-using WireMockRequest = WireMock.RequestBuilders.Request;
-using WireMockResponse = WireMock.ResponseBuilders.Response;
-
-namespace AssemblyAI.Test.Core
-{
- [TestFixture]
- public class RawClientTests
- {
- private WireMockServer _server;
- private HttpClient _httpClient;
- private RawClient _rawClient;
- private string _baseUrl;
- private const int _maxRetries = 3;
-
- [SetUp]
- public void SetUp()
- {
- _server = WireMockServer.Start();
- _baseUrl = _server.Url ?? "";
- _httpClient = new HttpClient { BaseAddress = new Uri(_baseUrl) };
- _rawClient = new RawClient(
- new ClientOptions() { HttpClient = _httpClient, MaxRetries = _maxRetries }
- );
- }
-
- [Test]
- [TestCase(408)]
- [TestCase(429)]
- [TestCase(500)]
- [TestCase(504)]
- public async SystemTask MakeRequestAsync_ShouldRetry_OnRetryableStatusCodes(int statusCode)
- {
- _server
- .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
- .InScenario("Retry")
- .WillSetStateTo("Server Error")
- .RespondWith(WireMockResponse.Create().WithStatusCode(statusCode));
-
- _server
- .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
- .InScenario("Retry")
- .WhenStateIs("Server Error")
- .WillSetStateTo("Success")
- .RespondWith(WireMockResponse.Create().WithStatusCode(statusCode));
-
- _server
- .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
- .InScenario("Retry")
- .WhenStateIs("Success")
- .RespondWith(WireMockResponse.Create().WithStatusCode(200).WithBody("Success"));
-
- var request = new RawClient.BaseApiRequest
- {
- BaseUrl = _baseUrl,
- Method = HttpMethod.Get,
- Path = "/test",
- };
-
- var response = await _rawClient.MakeRequestAsync(request);
- Assert.That(response.StatusCode, Is.EqualTo(200));
-
- var content = await response.Raw.Content.ReadAsStringAsync();
- Assert.That(content, Is.EqualTo("Success"));
-
- Assert.That(_server.LogEntries.Count, Is.EqualTo(_maxRetries));
- }
-
- [Test]
- [TestCase(400)]
- [TestCase(409)]
- public async SystemTask MakeRequestAsync_ShouldRetry_OnNonRetryableStatusCodes(
- int statusCode
- )
- {
- _server
- .Given(WireMockRequest.Create().WithPath("/test").UsingGet())
- .InScenario("Retry")
- .WillSetStateTo("Server Error")
- .RespondWith(
- WireMockResponse.Create().WithStatusCode(statusCode).WithBody("Failure")
- );
-
- var request = new RawClient.BaseApiRequest
- {
- BaseUrl = _baseUrl,
- Method = HttpMethod.Get,
- Path = "/test",
- };
-
- var response = await _rawClient.MakeRequestAsync(request);
- Assert.That(response.StatusCode, Is.EqualTo(statusCode));
-
- var content = await response.Raw.Content.ReadAsStringAsync();
- Assert.That(content, Is.EqualTo("Failure"));
-
- Assert.That(_server.LogEntries.Count, Is.EqualTo(1));
- }
-
- [TearDown]
- public void TearDown()
- {
- _server.Dispose();
- _httpClient.Dispose();
- }
- }
-}
diff --git a/src/AssemblyAI.Test/TestClient.cs b/src/AssemblyAI.Test/TestClient.cs
deleted file mode 100644
index c8c868b..0000000
--- a/src/AssemblyAI.Test/TestClient.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using NUnit.Framework;
-
-#nullable enable
-
-namespace AssemblyAI.Test;
-
-[TestFixture]
-public class TestClient { }
diff --git a/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj b/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
index f4966e9..c55147c 100644
--- a/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
+++ b/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
@@ -26,7 +26,10 @@
-
+
+
+ FernGenerated\%(RecursiveDir)%(Filename)%(Extension)
+
@@ -36,4 +39,9 @@
all
+
+
+
+
+
\ No newline at end of file
diff --git a/src/AssemblyAI.sln b/src/AssemblyAI.sln
index 5870e21..b4139df 100644
--- a/src/AssemblyAI.sln
+++ b/src/AssemblyAI.sln
@@ -7,7 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyAI", "AssemblyAI\As
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyAI.IntegrationTests", "AssemblyAI.IntegrationTests\AssemblyAI.IntegrationTests.csproj", "{311AB518-6FCF-453B-A4B7-12E444C9479E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyAI.UnitTests", "AssemblyAI.UnitTests\AssemblyAI.UnitTests.csproj", "{F432A09F-C463-438F-AF0D-EB7951F0DBB9}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyAI.UnitTests", "AssemblyAI.UnitTests\AssemblyAI.UnitTests.csproj", "{547C3456-F649-4E68-A591-0538486F7DE3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -26,9 +26,9 @@ Global
{311AB518-6FCF-453B-A4B7-12E444C9479E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{311AB518-6FCF-453B-A4B7-12E444C9479E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{311AB518-6FCF-453B-A4B7-12E444C9479E}.Release|Any CPU.Build.0 = Release|Any CPU
- {F432A09F-C463-438F-AF0D-EB7951F0DBB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F432A09F-C463-438F-AF0D-EB7951F0DBB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F432A09F-C463-438F-AF0D-EB7951F0DBB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F432A09F-C463-438F-AF0D-EB7951F0DBB9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {547C3456-F649-4E68-A591-0538486F7DE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {547C3456-F649-4E68-A591-0538486F7DE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {547C3456-F649-4E68-A591-0538486F7DE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {547C3456-F649-4E68-A591-0538486F7DE3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/src/AssemblyAI/AssemblyAI.Custom.props b/src/AssemblyAI/AssemblyAI.Custom.props
index 70df284..9aa6220 100644
--- a/src/AssemblyAI/AssemblyAI.Custom.props
+++ b/src/AssemblyAI/AssemblyAI.Custom.props
@@ -4,17 +4,57 @@ Configure additional MSBuild properties for your project in this file:
- Step 2: Modify this file to your liking.
-->
-
\ No newline at end of file
diff --git a/src/AssemblyAI/AssemblyAI.csproj b/src/AssemblyAI/AssemblyAI.csproj
index 593c6d6..12924ae 100644
--- a/src/AssemblyAI/AssemblyAI.csproj
+++ b/src/AssemblyAI/AssemblyAI.csproj
@@ -1,4 +1,3 @@
-
diff --git a/src/AssemblyAI/AssemblyAIClient.cs b/src/AssemblyAI/AssemblyAIClient.cs
index 1da89d8..6f14267 100644
--- a/src/AssemblyAI/AssemblyAIClient.cs
+++ b/src/AssemblyAI/AssemblyAIClient.cs
@@ -1,49 +1,63 @@
+using System.Net.Http;
using AssemblyAI.Core;
using AssemblyAI.Files;
using AssemblyAI.Lemur;
using AssemblyAI.Realtime;
using AssemblyAI.Transcripts;
-#nullable enable
namespace AssemblyAI;
-public partial class AssemblyAIClient
+///
+/// The client to interact with the AssemblyAI API.
+///
+public class AssemblyAIClient
{
- private RawClient _client;
+ ///
+ 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
+ })
+ {
+ }
- public AssemblyAIClient(string? apiKey = null, ClientOptions? clientOptions = null)
+ ///
+ /// Create a new instance of the class.
+ ///
+ /// The AssemblyAI client options
+ /// Thrown if ClientOptions.ApiKey is null or empty.
+ public AssemblyAIClient(ClientOptions clientOptions)
{
- var defaultHeaders = new Headers(
- new Dictionary()
- {
- { "Authorization", apiKey },
- { "X-Fern-Language", "C#" },
- { "X-Fern-SDK-Name", "AssemblyAI" },
- { "X-Fern-SDK-Version", Version.Current },
- { "User-Agent", "AssemblyAI/1.2.1" },
- }
- );
- clientOptions ??= new ClientOptions();
- foreach (var header in defaultHeaders)
+ if (string.IsNullOrEmpty(clientOptions.ApiKey))
{
- if (!clientOptions.Headers.ContainsKey(header.Key))
- {
- clientOptions.Headers[header.Key] = header.Value;
- }
+ throw new ArgumentException("AssemblyAI API Key is required.");
}
- _client = new RawClient(clientOptions);
- Files = new FilesClient(_client);
- Transcripts = new TranscriptsClient(_client);
- Realtime = new RealtimeClient(_client);
- Lemur = new LemurClient(_client);
+
+ // ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
+ clientOptions.HttpClient ??= new HttpClient();
+ clientOptions.Headers.Add("Authorization", clientOptions.ApiKey);
+ clientOptions.Headers.Add("User-Agent", new UserAgent(UserAgent.Default, clientOptions.UserAgent).ToAssemblyAIUserAgentString());
+ var client = new RawClient(clientOptions);
+
+ Files = new FilesClient(client);
+ Transcripts = new ExtendedTranscriptsClient(client, this);
+ Realtime = new RealtimeClient(client);
+ Lemur = new LemurClient(client);
}
-
- public FilesClient Files { get; init; }
-
- public TranscriptsClient Transcripts { get; init; }
-
- public RealtimeClient Realtime { get; init; }
-
- public LemurClient Lemur { get; init; }
-}
+}
\ No newline at end of file
diff --git a/src/AssemblyAI/Core/EnumSerializer.cs b/src/AssemblyAI/Core/EnumSerializer.cs
index ef9a1ff..6710643 100644
--- a/src/AssemblyAI/Core/EnumSerializer.cs
+++ b/src/AssemblyAI/Core/EnumSerializer.cs
@@ -29,8 +29,15 @@ public EnumSerializer()
?? value.ToString()
?? throw new Exception("Unexpected null enum toString value");
- _enumToString.Add(enumValue, stringValue);
- _stringToEnum.Add(stringValue, enumValue);
+ if(!_enumToString.ContainsKey(enumValue))
+ {
+ _enumToString.Add(enumValue, stringValue);
+ }
+
+ if (!_stringToEnum.ContainsKey(stringValue))
+ {
+ _stringToEnum.Add(stringValue, enumValue);
+ }
}
}
diff --git a/src/AssemblyAI/Core/JsonConfiguration.cs b/src/AssemblyAI/Core/JsonConfiguration.cs
index 769365f..7d75fe4 100644
--- a/src/AssemblyAI/Core/JsonConfiguration.cs
+++ b/src/AssemblyAI/Core/JsonConfiguration.cs
@@ -1,4 +1,5 @@
using System.Text.Json;
+using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace AssemblyAI.Core;
@@ -22,15 +23,80 @@ static JsonOptions()
static partial void ConfigureJsonSerializerOptions(JsonSerializerOptions defaultOptions);
}
-internal static class JsonUtils
+///
+/// Utilities class for JSON serialization and deserialization.
+///
+public static class JsonUtils
{
+ ///
+ /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
+ ///
+ /// Object to serialize
+ /// Type of the object to serialize
+ /// The object serialized as JSON
public static string Serialize(T obj)
- {
- return JsonSerializer.Serialize(obj, JsonOptions.JsonSerializerOptions);
- }
+ => JsonSerializer.Serialize(obj, JsonOptions.JsonSerializerOptions);
+
+ ///
+ /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
+ ///
+ /// Object to serialize
+ /// Type of the object to serialize
+ /// The object serialized as JSON
+ public static JsonDocument SerializeToDocument(T obj)
+ => JsonSerializer.SerializeToDocument(obj, JsonOptions.JsonSerializerOptions);
+ ///
+ /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
+ ///
+ /// Object to serialize
+ /// Type of the object to serialize
+ /// The object serialized as JSON
+ public static JsonElement SerializeToElement(T obj)
+ => JsonSerializer.SerializeToElement(obj, JsonOptions.JsonSerializerOptions);
+
+ ///
+ /// Serialize an object to JSON using the AssemblyAI SDKs JSON options.
+ ///
+ /// Object to serialize
+ /// Type of the object to serialize
+ /// The object serialized as JSON
+ public static JsonNode? SerializeToNode(T obj)
+ => JsonSerializer.SerializeToNode(obj, JsonOptions.JsonSerializerOptions);
+
+ ///
+ /// Deserialize a JSON string to an object using the AssemblyAI SDKs JSON options.
+ ///
+ /// The JSON string
+ /// The type to deserialize the JSON to
+ /// The deserialized object of type T
public static T Deserialize(string json)
- {
- return JsonSerializer.Deserialize(json, JsonOptions.JsonSerializerOptions)!;
- }
-}
+ => JsonSerializer.Deserialize(json, JsonOptions.JsonSerializerOptions)!;
+
+ ///
+ /// Deserialize a JSON document to an object using the AssemblyAI SDKs JSON options.
+ ///
+ /// The JSON string
+ /// The type to deserialize the JSON to
+ /// The deserialized object of type T
+ public static T Deserialize(JsonDocument json)
+ => json.Deserialize(JsonOptions.JsonSerializerOptions)!;
+
+ ///
+ /// Deserialize a JSON element to an object using the AssemblyAI SDKs JSON options.
+ ///
+ /// The JSON string
+ /// The type to deserialize the JSON to
+ /// The deserialized object of type T
+ public static T Deserialize(JsonElement json)
+ => json.Deserialize(JsonOptions.JsonSerializerOptions)!;
+
+ ///
+ /// Deserialize a JSON node to an object using the AssemblyAI SDKs JSON options.
+ ///
+ /// The JSON string
+ /// The type to deserialize the JSON to
+ /// The deserialized object of type T
+ public static T Deserialize(JsonNode json)
+ => json.Deserialize(JsonOptions.JsonSerializerOptions)!;
+}
\ No newline at end of file
diff --git a/src/AssemblyAI/Core/Public/ClientOptions.cs b/src/AssemblyAI/Core/Public/ClientOptions.cs
index 77cbe0f..8241f7a 100644
--- a/src/AssemblyAI/Core/Public/ClientOptions.cs
+++ b/src/AssemblyAI/Core/Public/ClientOptions.cs
@@ -30,19 +30,4 @@ public partial class ClientOptions
/// The http headers sent with the request.
///
internal Headers Headers { get; init; } = new();
-
- ///
- /// Clones this and returns a new instance
- ///
- internal ClientOptions Clone()
- {
- return new ClientOptions
- {
- BaseUrl = BaseUrl,
- HttpClient = HttpClient,
- MaxRetries = MaxRetries,
- Timeout = Timeout,
- Headers = new Headers(new Dictionary(Headers)),
- };
- }
}
diff --git a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
index 291f27b..4f666e2 100644
--- a/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
+++ b/src/AssemblyAI/Core/Public/ExtendedClientOptions.cs
@@ -2,6 +2,8 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable CheckNamespace
+using AssemblyAI.Core;
+
namespace AssemblyAI;
///
@@ -18,4 +20,21 @@ public partial class ClientOptions
/// The AssemblyAI user agent
///
public UserAgent UserAgent { get; set; } = new();
+
+ ///
+ /// Clones this and returns a new instance
+ ///
+ internal ClientOptions Clone()
+ {
+ return new ClientOptions
+ {
+ ApiKey = ApiKey,
+ UserAgent = UserAgent.Clone(),
+ BaseUrl = BaseUrl,
+ HttpClient = HttpClient,
+ MaxRetries = MaxRetries,
+ Timeout = Timeout,
+ Headers = new Headers(new Dictionary(Headers)),
+ };
+ }
}
\ No newline at end of file
diff --git a/src/AssemblyAI/EnumConverter.cs b/src/AssemblyAI/EnumConverter.cs
new file mode 100644
index 0000000..6384bd2
--- /dev/null
+++ b/src/AssemblyAI/EnumConverter.cs
@@ -0,0 +1,27 @@
+using AssemblyAI.Core;
+
+namespace AssemblyAI;
+
+///
+/// Convert an AssemblyAI enum to a string and vice versa.
+///
+public static class EnumConverter
+{
+ ///
+ /// Convert a string value to an enum. For example, "en_us" to TranscriptLanguageCode.EnUs.
+ ///
+ /// String value of the enum
+ /// The enum type to convert into
+ /// An enum value of the given enum type
+ /// This method uses the Value property of EnumMemberAttribute on the given enum value.
+ public static T ToEnum(string value) where T : Enum => JsonUtils.Deserialize($"\"{value}\"");
+
+ ///
+ /// Convert an enum value to a string value. For example, TranscriptLanguageCode.EnUs to "en_us".
+ ///
+ /// Enum value
+ ///
+ /// The string value of the given enum
+ /// This method uses the Value property of EnumMemberAttribute on the given enum value.
+ public static string ToString(T value) where T : Enum => JsonUtils.Serialize(value).Trim('"');
+}
\ No newline at end of file
diff --git a/src/AssemblyAI/Lemur/Types/LemurModel.cs b/src/AssemblyAI/Lemur/Types/LemurModel.cs
index 941b238..cf87e74 100644
--- a/src/AssemblyAI/Lemur/Types/LemurModel.cs
+++ b/src/AssemblyAI/Lemur/Types/LemurModel.cs
@@ -27,6 +27,10 @@ public enum LemurModel
[EnumMember(Value = "anthropic/claude-2")]
AnthropicClaude2_0,
+ [EnumMember(Value = "anthropic/claude-2")]
+ [Obsolete("Use AnthropicClaude2_0")]
+ AnthropicClaude2,
+
[EnumMember(Value = "default")]
Default,
diff --git a/src/AssemblyAI/Lemur/Types/LemurResponse.cs b/src/AssemblyAI/Lemur/Types/LemurResponse.cs
new file mode 100644
index 0000000..345ccc4
--- /dev/null
+++ b/src/AssemblyAI/Lemur/Types/LemurResponse.cs
@@ -0,0 +1,21 @@
+using System.Text.Json.Serialization;
+using AssemblyAI.Core;
+using OneOf;
+
+namespace AssemblyAI.Lemur;
+
+public class LemurResponse : OneOfBase
+{
+ private LemurResponse(OneOf response) : base(response)
+ {
+ }
+
+ public static implicit operator LemurResponse(OneOf _) => new(_);
+ public static implicit operator LemurResponse(LemurStringResponse _) => new(_);
+ public static implicit operator LemurResponse(LemurQuestionAnswerResponse _) => new(_);
+
+ public bool IsLemurStringResponse => IsT0;
+ public bool IsLemurQuestionAnswerResponse => IsT1;
+ public LemurStringResponse AsLemurStringResponse => AsT0;
+ public LemurQuestionAnswerResponse AsLemurQuestionAnswerResponse => AsT1;
+}
\ No newline at end of file
diff --git a/src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs b/src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
deleted file mode 100644
index 1ceef1a..0000000
--- a/src/AssemblyAI/Realtime/Types/ForceEndUtterance.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Text.Json.Serialization;
-using AssemblyAI.Core;
-
-#nullable enable
-
-namespace AssemblyAI.Realtime;
-
-public record ForceEndUtterance
-{
- ///
- /// A boolean value to communicate that you wish to force the end of the utterance
- ///
- [JsonPropertyName("force_end_utterance")]
- public required bool ForceEndUtterance_ { get; set; }
-
- public override string ToString()
- {
- return JsonUtils.Serialize(this);
- }
-}
diff --git a/src/AssemblyAI/Realtime/Types/Realtime.cs b/src/AssemblyAI/Realtime/Types/Realtime.cs
deleted file mode 100644
index a0a389b..0000000
--- a/src/AssemblyAI/Realtime/Types/Realtime.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Runtime.Serialization;
-using System.Text.Json.Serialization;
-using AssemblyAI.Core;
-
-#nullable enable
-
-namespace AssemblyAI.Realtime;
-
-[JsonConverter(typeof(EnumSerializer))]
-public enum Realtime
-{
- [EnumMember(Value = "pcm_s16le")]
- PcmS16le,
-
- [EnumMember(Value = "pcm_mulaw")]
- PcmMulaw,
-}
diff --git a/src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs b/src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
new file mode 100644
index 0000000..9c03d21
--- /dev/null
+++ b/src/AssemblyAI/Realtime/Types/RealtimeTranscript.cs
@@ -0,0 +1,19 @@
+using OneOf;
+
+// ReSharper disable once CheckNamespace
+namespace AssemblyAI.Realtime;
+
+public class RealtimeTranscript : OneOfBase
+{
+ private RealtimeTranscript(OneOf transcript) : base(transcript)
+ {
+ }
+
+ public static implicit operator RealtimeTranscript(PartialTranscript _) => new(_);
+ public static implicit operator RealtimeTranscript(FinalTranscript _) => new(_);
+
+ public bool IsPartialTranscript => IsT0;
+ public bool IsFinalTranscript => IsT1;
+ public PartialTranscript AsPartialTranscript => AsT0;
+ public FinalTranscript AsFinalTranscript => AsT1;
+}
\ No newline at end of file
diff --git a/src/AssemblyAI/Realtime/Types/TerminateSession.cs b/src/AssemblyAI/Realtime/Types/TerminateSession.cs
deleted file mode 100644
index c61ade6..0000000
--- a/src/AssemblyAI/Realtime/Types/TerminateSession.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Text.Json.Serialization;
-using AssemblyAI.Core;
-
-#nullable enable
-
-namespace AssemblyAI.Realtime;
-
-public record TerminateSession
-{
- ///
- /// Set to true to end your streaming session forever
- ///
- [JsonPropertyName("terminate_session")]
- public required bool TerminateSession_ { get; set; }
-
- public override string ToString()
- {
- return JsonUtils.Serialize(this);
- }
-}
diff --git a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
index 5b5c57e..6025352 100644
--- a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
@@ -1,5 +1,6 @@
using System.Text.Json.Serialization;
using AssemblyAI.Core;
+using AssemblyAI.Transcripts;
#nullable enable
@@ -11,7 +12,7 @@ public record ContentSafetyLabelsResult
/// The status of the Content Moderation model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public required AudioIntelligenceModelStatus Status { get; set; }
+ public AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Content Moderation model
diff --git a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
index b7a7714..b094a05 100644
--- a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
+using AssemblyAI.Transcripts;
using AssemblyAI.Core;
#nullable enable
@@ -11,7 +12,7 @@ public record TopicDetectionModelResult
/// The status of the Topic Detection model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public required AudioIntelligenceModelStatus Status { get; set; }
+ public AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Topic Detection model
diff --git a/src/AssemblyAI/Types/Error.cs b/src/AssemblyAI/Types/Error.cs
deleted file mode 100644
index 0764cb8..0000000
--- a/src/AssemblyAI/Types/Error.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Text.Json.Serialization;
-using AssemblyAI.Core;
-
-#nullable enable
-
-namespace AssemblyAI;
-
-public record Error
-{
- ///
- /// Error message
- ///
- [JsonPropertyName("error")]
- public required string Error_ { get; set; }
-
- [JsonPropertyName("status")]
- public string? Status { get; set; }
-
- public override string ToString()
- {
- return JsonUtils.Serialize(this);
- }
-}
diff --git a/src/AssemblyAI/UserAgent.cs b/src/AssemblyAI/UserAgent.cs
index bfbc81f..625616d 100644
--- a/src/AssemblyAI/UserAgent.cs
+++ b/src/AssemblyAI/UserAgent.cs
@@ -152,6 +152,14 @@ private static Dictionary Merge(
return newUserAgent as Dictionary;
}
+
+ ///
+ /// Clones this and returns a new instance
+ ///
+ internal UserAgent Clone()
+ {
+ return new UserAgent(_userAgent.ToDictionary(kv => kv.Key, kv => kv.Value?.Clone()));
+ }
}
///
@@ -163,4 +171,12 @@ public class UserAgentItem(string name, string version)
{
public string Name { get; set; } = name;
public string Version { get; set; } = version;
+
+ ///
+ /// Clones this and returns a new instance
+ ///
+ internal UserAgentItem Clone()
+ {
+ return new UserAgentItem(Name, Version);
+ }
}
\ No newline at end of file
From 61dc80989b79ad9f291b255def7caf8b0091a788 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 11:44:04 -0500
Subject: [PATCH 08/15] Use non deprecated Lemur model in test
---
src/AssemblyAI.IntegrationTests/LemurTests.cs | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/AssemblyAI.IntegrationTests/LemurTests.cs b/src/AssemblyAI.IntegrationTests/LemurTests.cs
index 8977d4a..a65dbf7 100644
--- a/src/AssemblyAI.IntegrationTests/LemurTests.cs
+++ b/src/AssemblyAI.IntegrationTests/LemurTests.cs
@@ -13,7 +13,7 @@ public async Task Should_Generate_Summary()
var client = Helpers.CreateClient();
var response = await client.Lemur.SummaryAsync(new LemurSummaryParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds,
AnswerFormat = "one sentence"
}).ConfigureAwait(false);
@@ -32,7 +32,7 @@ public async Task Should_Generate_Answer()
var client = Helpers.CreateClient();
var response = await client.Lemur.QuestionAnswerAsync(new LemurQuestionAnswerParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds,
Questions = new[]
{
@@ -63,7 +63,7 @@ public async Task Should_Generate_Action_Items()
var client = Helpers.CreateClient();
var response = await client.Lemur.ActionItemsAsync(new LemurActionItemsParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds
}).ConfigureAwait(false);
@@ -81,7 +81,7 @@ public async Task Should_Generate_Task()
var client = Helpers.CreateClient();
var response = await client.Lemur.TaskAsync(new LemurTaskParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds,
Prompt = "Write a haiku about this conversation."
}).ConfigureAwait(false);
@@ -101,7 +101,7 @@ public void Should_Fail_To_Generate_Summary()
var client = Helpers.CreateClient();
var ex = Assert.ThrowsAsync(async () => await client.Lemur.SummaryAsync(new LemurSummaryParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = ["bad-id"],
AnswerFormat = "one sentence"
}).ConfigureAwait(false));
@@ -115,7 +115,7 @@ public async Task Should_Return_Response()
var client = Helpers.CreateClient();
var taskResponse = await client.Lemur.TaskAsync(new LemurTaskParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds,
Prompt = "Write a haiku about this conversation."
}).ConfigureAwait(false);
@@ -132,7 +132,7 @@ public async Task Should_Return_Response()
var qaResponse = await client.Lemur.QuestionAnswerAsync(new LemurQuestionAnswerParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds,
Questions =
[
@@ -145,7 +145,7 @@ public async Task Should_Return_Response()
}).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
-
+
var qaResponse2OneOf = await client.Lemur.GetResponseAsync(qaResponse.RequestId).ConfigureAwait(false);
var qaResponse2 = qaResponse2OneOf.AsT1;
Assert.Multiple(() =>
@@ -161,13 +161,13 @@ public async Task Should_Purge_Request_Data()
var client = Helpers.CreateClient();
var summaryResponse = await client.Lemur.SummaryAsync(new LemurSummaryParams
{
- FinalModel = LemurModel.Basic,
+ FinalModel = LemurModel.AnthropicClaude3_Haiku,
TranscriptIds = TranscriptIds,
AnswerFormat = "one sentence"
}).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
-
+
var deletionRequest = await client.Lemur.PurgeRequestDataAsync(summaryResponse.RequestId).ConfigureAwait(false);
Assert.Multiple(() =>
{
From 82384b4a857d52815a9f4e15f55a7b19d1d0ab89 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:12:57 -0500
Subject: [PATCH 09/15] Make ContentSafetyLabel.Severity nullable
---
.fernignore | 5 +++--
src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/.fernignore b/.fernignore
index d7bf0cc..8c5a672 100644
--- a/.fernignore
+++ b/.fernignore
@@ -29,8 +29,6 @@ src/AssemblyAI/Transcripts/TranscriptNotCompletedStatusException.cs
src/AssemblyAI/Transcripts/Types/TranscriptExtensions.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsMapper.cs
src/AssemblyAI/Transcripts/Types/TranscriptParamsCloner.cs
-src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
-src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
src/AssemblyAI/Lemur/ExtendedLemurClient.cs
src/AssemblyAI/Lemur/Types/LemurResponse.cs
src/AssemblyAI/Lemur/Types/LemurModel.cs
@@ -50,3 +48,6 @@ src/AssemblyAI.IntegrationTests
docfx
Samples
+
+# TODO: remove these ignores when AssemblyAI fixes the API
+src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
\ No newline at end of file
diff --git a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
index 8aa0b8c..86fb05d 100644
--- a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
+++ b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
@@ -23,7 +23,7 @@ public record ContentSafetyLabel
/// How severely the topic is discussed in the section, from 0 to 1
///
[JsonPropertyName("severity")]
- public required double Severity { get; set; }
+ public required double? Severity { get; set; }
public override string ToString()
{
From f181ba07f4fc06478f1db801211b1735dcf8e6d2 Mon Sep 17 00:00:00 2001
From: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
Date: Tue, 21 Jan 2025 17:15:04 +0000
Subject: [PATCH 10/15] SDK regeneration
---
src/AssemblyAI.Test/Core/EnumSerializerTests.cs | 2 +-
src/AssemblyAI/AssemblyAI.csproj | 1 +
src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs | 3 +--
src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs | 3 +--
4 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/AssemblyAI.Test/Core/EnumSerializerTests.cs b/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
index ad33b46..32fdcb7 100644
--- a/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
+++ b/src/AssemblyAI.Test/Core/EnumSerializerTests.cs
@@ -8,7 +8,7 @@
namespace AssemblyAI.Test.Core
{
[TestFixture]
- public class EnumSerializerTests
+ public class StringEnumSerializerTests
{
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
diff --git a/src/AssemblyAI/AssemblyAI.csproj b/src/AssemblyAI/AssemblyAI.csproj
index 12924ae..593c6d6 100644
--- a/src/AssemblyAI/AssemblyAI.csproj
+++ b/src/AssemblyAI/AssemblyAI.csproj
@@ -1,3 +1,4 @@
+
diff --git a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
index 6025352..5b5c57e 100644
--- a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
@@ -1,6 +1,5 @@
using System.Text.Json.Serialization;
using AssemblyAI.Core;
-using AssemblyAI.Transcripts;
#nullable enable
@@ -12,7 +11,7 @@ public record ContentSafetyLabelsResult
/// The status of the Content Moderation model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public AudioIntelligenceModelStatus Status { get; set; }
+ public required AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Content Moderation model
diff --git a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
index b094a05..b7a7714 100644
--- a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
@@ -1,5 +1,4 @@
using System.Text.Json.Serialization;
-using AssemblyAI.Transcripts;
using AssemblyAI.Core;
#nullable enable
@@ -12,7 +11,7 @@ public record TopicDetectionModelResult
/// The status of the Topic Detection model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public AudioIntelligenceModelStatus Status { get; set; }
+ public required AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Topic Detection model
From 174fdc2837f83bd270940a9fd550adb137cae019 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:17:03 -0500
Subject: [PATCH 11/15] undo undesired changes
---
.fernignore | 4 +++-
src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs | 2 +-
src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/.fernignore b/.fernignore
index 8c5a672..d62dbe2 100644
--- a/.fernignore
+++ b/.fernignore
@@ -50,4 +50,6 @@ docfx
Samples
# TODO: remove these ignores when AssemblyAI fixes the API
-src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
\ No newline at end of file
+src/AssemblyAI/Transcripts/Types/ContentSafetyLabel.cs
+src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
+src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
\ No newline at end of file
diff --git a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
index 5b5c57e..a785a55 100644
--- a/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
@@ -11,7 +11,7 @@ public record ContentSafetyLabelsResult
/// The status of the Content Moderation model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public required AudioIntelligenceModelStatus Status { get; set; }
+ public AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Content Moderation model
diff --git a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
index b7a7714..b41d7ad 100644
--- a/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
+++ b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
@@ -11,7 +11,7 @@ public record TopicDetectionModelResult
/// The status of the Topic Detection model. Either success, or unavailable in the rare case that the model failed.
///
[JsonPropertyName("status")]
- public required AudioIntelligenceModelStatus Status { get; set; }
+ public AudioIntelligenceModelStatus Status { get; set; }
///
/// An array of results for the Topic Detection model
From 54297f55e505b410d1320a95c9c42f79a90fe5c6 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:23:31 -0500
Subject: [PATCH 12/15] Use AnthropicClaude2_1 for Action items
---
src/AssemblyAI.IntegrationTests/LemurTests.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/AssemblyAI.IntegrationTests/LemurTests.cs b/src/AssemblyAI.IntegrationTests/LemurTests.cs
index a65dbf7..37502d9 100644
--- a/src/AssemblyAI.IntegrationTests/LemurTests.cs
+++ b/src/AssemblyAI.IntegrationTests/LemurTests.cs
@@ -63,7 +63,7 @@ public async Task Should_Generate_Action_Items()
var client = Helpers.CreateClient();
var response = await client.Lemur.ActionItemsAsync(new LemurActionItemsParams
{
- FinalModel = LemurModel.AnthropicClaude3_Haiku,
+ FinalModel = LemurModel.AnthropicClaude2_1,
TranscriptIds = TranscriptIds
}).ConfigureAwait(false);
From e21601e2116789679fa5c2d427fe80e41c0690bf Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:29:57 -0500
Subject: [PATCH 13/15] Fix GetSubtitlesAsync
---
src/AssemblyAI/Transcripts/TranscriptsClient.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/AssemblyAI/Transcripts/TranscriptsClient.cs b/src/AssemblyAI/Transcripts/TranscriptsClient.cs
index a1c69a5..7fae161 100644
--- a/src/AssemblyAI/Transcripts/TranscriptsClient.cs
+++ b/src/AssemblyAI/Transcripts/TranscriptsClient.cs
@@ -303,8 +303,8 @@ public async Task GetSubtitlesAsync(
new RawClient.JsonApiRequest
{
BaseUrl = _client.Options.BaseUrl,
- Method = HttpMethod.Get,
- Path = $"v2/transcript/{transcriptId}/{subtitleFormat}",
+ Method = HttpMethod.Get,
+ Path = $"v2/transcript/{transcriptId}/{subtitleFormat.Stringify()}",
Query = _query,
Options = options,
},
From 65fa5d4ccf8978dabc822cf443791ba322fe7009 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:39:30 -0500
Subject: [PATCH 14/15] Run tests on correct GH actions runner
---
.github/workflows/ci.yml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 86fbd20..282cbc6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,13 +28,13 @@ jobs:
strategy:
fail-fast: false
matrix:
- framework: [net462, net6.0]
+ framework: [net462, net8.0]
os: [ubuntu-latest, windows-latest]
exclude:
- os: ubuntu-latest
framework: net462
name: Run Tests on ${{ matrix.os }} with ${{ matrix.framework }}
- runs-on: ubuntu-latest
+ runs-on: ${{ matrix.os }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
@@ -44,9 +44,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: |
- 8.x
- 6.x
+ dotnet-version: 8.x
- name: Install tools
run: |
From 67283af9d3aa8e155af1be9a081fa1e83667bb25 Mon Sep 17 00:00:00 2001
From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com>
Date: Tue, 21 Jan 2025 12:43:39 -0500
Subject: [PATCH 15/15] Target net8.0 for test projects
---
.../AssemblyAI.IntegrationTests.csproj | 2 +-
src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj | 2 +-
src/AssemblyAI.UnitTests/UserAgentTests.cs | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/AssemblyAI.IntegrationTests/AssemblyAI.IntegrationTests.csproj b/src/AssemblyAI.IntegrationTests/AssemblyAI.IntegrationTests.csproj
index daa67ba..4f09e4c 100644
--- a/src/AssemblyAI.IntegrationTests/AssemblyAI.IntegrationTests.csproj
+++ b/src/AssemblyAI.IntegrationTests/AssemblyAI.IntegrationTests.csproj
@@ -1,7 +1,7 @@
- net462;net6.0
+ net462;net8.0enableenable12
diff --git a/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj b/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
index c55147c..8b39f6e 100644
--- a/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
+++ b/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
@@ -1,7 +1,7 @@
- net462;net6.0
+ net462;net8.0enableenable12
diff --git a/src/AssemblyAI.UnitTests/UserAgentTests.cs b/src/AssemblyAI.UnitTests/UserAgentTests.cs
index e7b7ca5..d0ab48b 100644
--- a/src/AssemblyAI.UnitTests/UserAgentTests.cs
+++ b/src/AssemblyAI.UnitTests/UserAgentTests.cs
@@ -15,8 +15,8 @@ public void TestDefaultUserAgent()
Assert.That(userAgentString, Does.StartWith("AssemblyAI/1.0 ("));
Assert.That(userAgentString, Does.EndWith(")"));
Assert.That(userAgentString, Does.Contain("sdk=CSharp/"));
-#if NET6_0
- Assert.That(userAgentString, Does.Contain("runtime_env=.NET/6."));
+#if NET8_0
+ Assert.That(userAgentString, Does.Contain("runtime_env=.NET/8."));
#elif NET462
Assert.That(userAgentString, Does.Contain("runtime_env=.NET Framework/4."));
#else