+
+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.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.IntegrationTests/LemurTests.cs b/src/AssemblyAI.IntegrationTests/LemurTests.cs
index 8977d4a..37502d9 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.AnthropicClaude2_1,
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(() =>
{
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.UnitTests/AssemblyAI.UnitTests.csproj b/src/AssemblyAI.UnitTests/AssemblyAI.UnitTests.csproj
index f4966e9..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
@@ -26,7 +26,10 @@
-
+
+
+ FernGenerated\%(RecursiveDir)%(Filename)%(Extension)
+
@@ -36,4 +39,9 @@
all
+
+
+
+
+
\ No newline at end of file
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
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
new file mode 100644
index 0000000..9aa6220
--- /dev/null
+++ b/src/AssemblyAI/AssemblyAI.Custom.props
@@ -0,0 +1,60 @@
+
+
+
+ net462;net8.0;net7.0;net6.0;netstandard2.0
+ enable
+ 12
+ enable
+ AssemblyAI
+ AssemblyAI
+ AssemblyAI
+ $(Version)
+ 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.git
+ https://www.assemblyai.com/favicon.png
+ icon.png
+ README.md
+ true
+ true
+ true
+ snupkg
+ git
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_Parameter1>AssemblyAI.UnitTests
+
+
+
\ No newline at end of file
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/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/Core/StringEnumSerializer.cs b/src/AssemblyAI/Core/EnumSerializer.cs
similarity index 94%
rename from src/AssemblyAI/Core/StringEnumSerializer.cs
rename to src/AssemblyAI/Core/EnumSerializer.cs
index 9b53fef..6710643 100644
--- a/src/AssemblyAI/Core/StringEnumSerializer.cs
+++ b/src/AssemblyAI/Core/EnumSerializer.cs
@@ -4,13 +4,13 @@
namespace AssemblyAI.Core;
-internal class StringEnumSerializer : JsonConverter
+internal class EnumSerializer : JsonConverter
where TEnum : struct, System.Enum
{
private readonly Dictionary _enumToString = new();
private readonly Dictionary _stringToEnum = new();
- public StringEnumSerializer()
+ public EnumSerializer()
{
var type = typeof(TEnum);
var values = Enum.GetValues(type);
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/JsonConfiguration.cs b/src/AssemblyAI/Core/JsonConfiguration.cs
index 7606b88..7d75fe4 100644
--- a/src/AssemblyAI/Core/JsonConfiguration.cs
+++ b/src/AssemblyAI/Core/JsonConfiguration.cs
@@ -1,34 +1,26 @@
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);
}
///
@@ -42,7 +34,7 @@ public static class JsonUtils
/// Object to serialize
/// Type of the object to serialize
/// The object serialized as JSON
- public static string Serialize(T obj)
+ public static string Serialize(T obj)
=> JsonSerializer.Serialize(obj, JsonOptions.JsonSerializerOptions);
///
@@ -51,7 +43,7 @@ public static string Serialize(T obj)
/// Object to serialize
/// Type of the object to serialize
/// The object serialized as JSON
- public static JsonDocument SerializeToDocument(T obj)
+ public static JsonDocument SerializeToDocument(T obj)
=> JsonSerializer.SerializeToDocument(obj, JsonOptions.JsonSerializerOptions);
///
@@ -60,7 +52,7 @@ public static JsonDocument SerializeToDocument(T obj)
/// Object to serialize
/// Type of the object to serialize
/// The object serialized as JSON
- public static JsonElement SerializeToElement(T obj)
+ public static JsonElement SerializeToElement(T obj)
=> JsonSerializer.SerializeToElement(obj, JsonOptions.JsonSerializerOptions);
///
@@ -78,7 +70,7 @@ public static JsonElement SerializeToElement(T obj)
/// The JSON string
/// The type to deserialize the JSON to
/// The deserialized object of type T
- public static T Deserialize(string json)
+ public static T Deserialize(string json)
=> JsonSerializer.Deserialize(json, JsonOptions.JsonSerializerOptions)!;
///
@@ -87,7 +79,7 @@ public static T Deserialize(string json)
/// The JSON string
/// The type to deserialize the JSON to
/// The deserialized object of type T
- public static T Deserialize(JsonDocument json)
+ public static T Deserialize(JsonDocument json)
=> json.Deserialize(JsonOptions.JsonSerializerOptions)!;
///
@@ -96,7 +88,7 @@ public static T Deserialize(JsonDocument json)
/// The JSON string
/// The type to deserialize the JSON to
/// The deserialized object of type T
- public static T Deserialize(JsonElement json)
+ public static T Deserialize(JsonElement json)
=> json.Deserialize(JsonOptions.JsonSerializerOptions)!;
///
@@ -105,6 +97,6 @@ public static T Deserialize(JsonElement json)
/// The JSON string
/// The type to deserialize the JSON to
/// The deserialized object of type T
- public static T Deserialize(JsonNode json)
+ public static T Deserialize(JsonNode json)
=> json.Deserialize(JsonOptions.JsonSerializerOptions)!;
}
\ No newline at end of file
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/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/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/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..cf87e74 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")]
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..7fae161 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
@@ -302,7 +303,7 @@ public async Task GetSubtitlesAsync(
new RawClient.JsonApiRequest
{
BaseUrl = _client.Options.BaseUrl,
- Method = HttpMethod.Get,
+ Method = HttpMethod.Get,
Path = $"v2/transcript/{transcriptId}/{subtitleFormat.Stringify()}",
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/ContentSafetyLabelsResult.cs b/src/AssemblyAI/Transcripts/Types/ContentSafetyLabelsResult.cs
index da73443..a785a55 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
@@ -13,6 +13,9 @@ public record ContentSafetyLabelsResult
[JsonPropertyName("status")]
public 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/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/TopicDetectionModelResult.cs b/src/AssemblyAI/Transcripts/Types/TopicDetectionModelResult.cs
index fa7d26f..b41d7ad 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
@@ -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/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")]
diff --git a/src/AssemblyAI/UserAgent.cs b/src/AssemblyAI/UserAgent.cs
index b001f7e..625616d 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
///
@@ -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