From 279d248f38212327aec0064cfe7f3343507ea46a Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 28 Feb 2024 01:49:50 -0500 Subject: [PATCH 1/5] Update README.md add client.transcripts.list_by_url --- .fernignore | 1 + .gitignore | 1 + README.md | 52 ++++++++------- .../transcripts/list_by_url_client.rb | 63 +++++++++++++++++++ 4 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 lib/assemblyai/transcripts/list_by_url_client.rb diff --git a/.fernignore b/.fernignore index 8e38637..daf8cad 100644 --- a/.fernignore +++ b/.fernignore @@ -6,5 +6,6 @@ test/ lib/assemblyai.rb lib/assemblyai/transcripts/polling_client.rb +lib/assemblyai/transcripts/listing_client.rb lib/assemblyai/transcripts/types/polling_options.rb diff --git a/.gitignore b/.gitignore index a97c182..56ddb42 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /tmp/ *.gem .env +/.idea diff --git a/README.md b/README.md index f8134b0..b6b3e77 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,9 @@ gem install assemblyai Import the AssemblyAI package and create an AssemblyAI object with your API key: ```ruby -require "assemblyai" +require 'assemblyai' -client = AssemblyAI::Client.new(api_key: "YOUR_API_KEY") +client = AssemblyAI::Client.new(api_key: 'YOUR_API_KEY') ``` You can now use the `client` object to interact with the AssemblyAI API. @@ -48,8 +48,8 @@ You can now use the `client` object to interact with the AssemblyAI API. ```ruby transcript = client.transcripts.transcribe( - audio_url: "https://storage.googleapis.com/aai-web-samples/espn-bears.m4a", -); + audio_url: 'https://storage.googleapis.com/aai-web-samples/espn-bears.m4a', +) ``` `transcribe` queues a transcription job and polls it until the `status` is `completed` or `error`. @@ -57,22 +57,21 @@ You can configure the polling interval and polling timeout using these options: ```ruby transcript = client.transcripts.transcribe( - audio_url: "https://storage.googleapis.com/aai-web-samples/espn-bears.m4a", - AssemblyAI::Transcripts::PollingInterval.new( - // How frequently the transcript is polled in ms. Defaults to 3000. + audio_url: 'https://storage.googleapis.com/aai-web-samples/espn-bears.m4a', + polling_options: AssemblyAI::Transcripts::PollingOptions.new( + # How frequently the transcript is polled in ms. Defaults to 3000. interval: 1000, - // How long to wait in ms until the "Polling timeout" error is thrown. Defaults to infinite (-1). - timeout: 5000, + # How long to wait in ms until the 'Polling timeout' error is thrown. Defaults to infinite (-1). + timeout: 5000 ) -); +) ``` If you don't want to wait until the transcript is ready, you can use `submit`: ```ruby -# Transcribe file at remote URL transcript = client.transcripts.submit( - audio_url: "https://storage.googleapis.com/aai-web-samples/espn-bears.m4a" + audio_url: 'https://storage.googleapis.com/aai-web-samples/espn-bears.m4a' ) ``` @@ -92,6 +91,17 @@ This will return a page of transcripts you created. page = client.transcripts.list ``` +You can also paginate over all pages. + +```ruby +next_page_url = nil +loop do + page = client.transcripts.list_by_url(url: next_page_url) + next_page_url = page.page_details.next_url + break if next_page_url.nil? +end +``` + ## Delete a transcript ```ruby @@ -106,10 +116,10 @@ Custom Summary: ```ruby response = client.lemur.summary( - transcript_ids: ["0d295578-8c75-421a-885a-2c487f188927"], - answer_format: "one sentence", + transcript_ids: ['0d295578-8c75-421a-885a-2c487f188927'], + answer_format: 'one sentence', context: { - "speakers": ["Alex", "Bob"] + 'speakers': ['Alex', 'Bob'] } ) ``` @@ -118,11 +128,11 @@ Question & Answer: ```ruby response = client.lemur.question_answer( - transcript_ids: ["0d295578-8c75-421a-885a-2c487f188927"], + transcript_ids: ['0d295578-8c75-421a-885a-2c487f188927'], questions: [ { - question: "What are they discussing?", - answer_format: "text" + question: 'What are they discussing?', + answer_format: 'text' } ] ) @@ -132,7 +142,7 @@ Action Items: ```ruby response = client.lemur.action_items( - transcript_ids: ["0d295578-8c75-421a-885a-2c487f188927"] + transcript_ids: ['0d295578-8c75-421a-885a-2c487f188927'] ) ``` @@ -140,7 +150,7 @@ Custom Task: ```ruby response = client.lemur.task( - transcript_ids: ["0d295578-8c75-421a-885a-2c487f188927"], - prompt: "Write a haiku about this conversation." + transcript_ids: ['0d295578-8c75-421a-885a-2c487f188927'], + prompt: 'Write a haiku about this conversation.' ) ``` diff --git a/lib/assemblyai/transcripts/list_by_url_client.rb b/lib/assemblyai/transcripts/list_by_url_client.rb new file mode 100644 index 0000000..a8d0092 --- /dev/null +++ b/lib/assemblyai/transcripts/list_by_url_client.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require_relative "../../requests" +require_relative "types/transcript_status" +require_relative "types/transcript_list" +require_relative "types/transcript_language_code" +require_relative "types/transcript_boost_param" +require_relative "types/redact_pii_audio_quality" +require_relative "types/pii_policy" +require_relative "types/substitution_policy" +require_relative "types/transcript_custom_spelling" +require_relative "types/summary_model" +require_relative "types/summary_type" +require_relative "types/transcript" +require_relative "types/subtitle_format" +require_relative "types/sentences_response" +require_relative "types/paragraphs_response" +require_relative "types/word_search_response" +require_relative "types/redacted_audio_response" +require_relative "types/polling_options" +require "async" + +module AssemblyAI + # Retrieve a list of transcripts you created + # + # @param url [String] The URL to retrieve the transcript list from + # @param request_options [RequestOptions] + # @return [Transcripts::TranscriptList] + def list_by_url(url: nil, request_options: nil) + if url.nil? + url = "/v2/transcript" + end + response = @request_client.conn.get(url) do |req| + req.options.timeout = request_options.timeout_in_seconds unless request_options&.timeout_in_seconds.nil? + req.headers["Authorization"] = request_options.api_key unless request_options&.api_key.nil? + req.headers = { **req.headers, **(request_options&.additional_headers || {}) }.compact + end + Transcripts::TranscriptList.from_json(json_object: response.body) + end + + # :nodoc: + class AsyncTranscriptsClient + + # Retrieve a list of transcripts you created + # + # @param url [String] The URL to retrieve the transcript list from + # @param request_options [RequestOptions] + # @return [Transcripts::TranscriptList] + def list_by_url(url: nil, request_options: nil) + Async do + if url.nil? + url = "/v2/transcript" + end + response = @request_client.conn.get(url) do |req| + req.options.timeout = request_options.timeout_in_seconds unless request_options&.timeout_in_seconds.nil? + req.headers["Authorization"] = request_options.api_key unless request_options&.api_key.nil? + req.headers = { **req.headers, **(request_options&.additional_headers || {}) }.compact + end + Transcripts::TranscriptList.from_json(json_object: response.body) + end + end + end +end From 5831b92bf72a31e069e6aa54906c72713d389b33 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 28 Feb 2024 01:54:41 -0500 Subject: [PATCH 2/5] Remove unused requires --- lib/assemblyai/transcripts/list_by_url_client.rb | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/assemblyai/transcripts/list_by_url_client.rb b/lib/assemblyai/transcripts/list_by_url_client.rb index a8d0092..564fe61 100644 --- a/lib/assemblyai/transcripts/list_by_url_client.rb +++ b/lib/assemblyai/transcripts/list_by_url_client.rb @@ -1,23 +1,7 @@ # frozen_string_literal: true require_relative "../../requests" -require_relative "types/transcript_status" require_relative "types/transcript_list" -require_relative "types/transcript_language_code" -require_relative "types/transcript_boost_param" -require_relative "types/redact_pii_audio_quality" -require_relative "types/pii_policy" -require_relative "types/substitution_policy" -require_relative "types/transcript_custom_spelling" -require_relative "types/summary_model" -require_relative "types/summary_type" -require_relative "types/transcript" -require_relative "types/subtitle_format" -require_relative "types/sentences_response" -require_relative "types/paragraphs_response" -require_relative "types/word_search_response" -require_relative "types/redacted_audio_response" -require_relative "types/polling_options" require "async" module AssemblyAI From 5e7777ae863d75bd987094d01ff24ce94d72b77e Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 28 Feb 2024 01:58:48 -0500 Subject: [PATCH 3/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6b3e77..8ebdf2a 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ # AssemblyAI Ruby SDK -The Ruby SDK provides classes and methods to serialize and deserialize the types for the AssemblyAI APIs. -In the future the SDK will include clients to call the API too. +The AssemblyAI Ruby SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async, audio intelligence models, as well as the latest LeMUR models. +We're working on adding real-time transcription to the Ruby SDK. # Documentation From 8eac017e50ea9d9a91111c729bad891ab3d61155 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:54:32 -0500 Subject: [PATCH 4/5] Nest list_by_url inside TranscriptsClient --- .../transcripts/list_by_url_client.rb | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/assemblyai/transcripts/list_by_url_client.rb b/lib/assemblyai/transcripts/list_by_url_client.rb index 564fe61..c380671 100644 --- a/lib/assemblyai/transcripts/list_by_url_client.rb +++ b/lib/assemblyai/transcripts/list_by_url_client.rb @@ -5,21 +5,25 @@ require "async" module AssemblyAI - # Retrieve a list of transcripts you created - # - # @param url [String] The URL to retrieve the transcript list from - # @param request_options [RequestOptions] - # @return [Transcripts::TranscriptList] - def list_by_url(url: nil, request_options: nil) - if url.nil? - url = "/v2/transcript" - end - response = @request_client.conn.get(url) do |req| - req.options.timeout = request_options.timeout_in_seconds unless request_options&.timeout_in_seconds.nil? - req.headers["Authorization"] = request_options.api_key unless request_options&.api_key.nil? - req.headers = { **req.headers, **(request_options&.additional_headers || {}) }.compact + + # :nodoc: + class TranscriptsClient + # Retrieve a list of transcripts you created + # + # @param url [String] The URL to retrieve the transcript list from + # @param request_options [RequestOptions] + # @return [Transcripts::TranscriptList] + def list_by_url(url: nil, request_options: nil) + if url.nil? + url = "/v2/transcript" + end + response = @request_client.conn.get(url) do |req| + req.options.timeout = request_options.timeout_in_seconds unless request_options&.timeout_in_seconds.nil? + req.headers["Authorization"] = request_options.api_key unless request_options&.api_key.nil? + req.headers = { **req.headers, **(request_options&.additional_headers || {}) }.compact + end + Transcripts::TranscriptList.from_json(json_object: response.body) end - Transcripts::TranscriptList.from_json(json_object: response.body) end # :nodoc: From 88fffba0167d856c42d51f0f29fa369d59d731c0 Mon Sep 17 00:00:00 2001 From: armandobelardo Date: Wed, 28 Feb 2024 16:57:19 -0500 Subject: [PATCH 5/5] add tests, example docs and missing import --- lib/assemblyai.rb | 1 + .../transcripts/list_by_url_client.rb | 14 ++++++++- test/test_assemblyai.rb | 31 ++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/assemblyai.rb b/lib/assemblyai.rb index ccd7bf5..adf77dd 100644 --- a/lib/assemblyai.rb +++ b/lib/assemblyai.rb @@ -6,6 +6,7 @@ require_relative "assemblyai/files/client" require_relative "assemblyai/transcripts/client" require_relative "assemblyai/transcripts/polling_client" +require_relative "assemblyai/transcripts/list_by_url_client" require_relative "assemblyai/realtime/client" require_relative "assemblyai/lemur/client" diff --git a/lib/assemblyai/transcripts/list_by_url_client.rb b/lib/assemblyai/transcripts/list_by_url_client.rb index c380671..2ab2769 100644 --- a/lib/assemblyai/transcripts/list_by_url_client.rb +++ b/lib/assemblyai/transcripts/list_by_url_client.rb @@ -8,11 +8,16 @@ module AssemblyAI # :nodoc: class TranscriptsClient - # Retrieve a list of transcripts you created + # Retrieve a list of transcripts you created, this is used for pagination to easily retrieve the next page of transcripts # # @param url [String] The URL to retrieve the transcript list from # @param request_options [RequestOptions] # @return [Transcripts::TranscriptList] + # + # @example Retrieve the next page of results + # client = AssemblyAI::Client.new(api_key: "YOUR_API_KEY") + # transcript_list = client.transcripts.list(limit: 1) + # client.transcripts.list_by_url(url: transcript_list.page_details.next_url) def list_by_url(url: nil, request_options: nil) if url.nil? url = "/v2/transcript" @@ -34,6 +39,13 @@ class AsyncTranscriptsClient # @param url [String] The URL to retrieve the transcript list from # @param request_options [RequestOptions] # @return [Transcripts::TranscriptList] + # + # @example Retrieve the next page of results + # client = AssemblyAI::AsyncClient.new(api_key: "YOUR_API_KEY") + # Sync do + # transcript_list = client.transcripts.list(limit: 1).wait + # client.transcripts.list_by_url(url: transcript_list.page_details.next_url) + # end def list_by_url(url: nil, request_options: nil) Async do if url.nil? diff --git a/test/test_assemblyai.rb b/test/test_assemblyai.rb index 56635a5..f03457b 100644 --- a/test/test_assemblyai.rb +++ b/test/test_assemblyai.rb @@ -5,12 +5,35 @@ # Basic AssemblyAI tests class TestAssemblyAI < Minitest::Test + def test_pagination + client = AssemblyAI::Client.new(api_key: "YOUR API KEY") + transcript_list = client.transcripts.list + + count = 0 + client.transcripts.list.transcripts.each do |transcript| + assert !transcript.id.nil? + count += 1 + end + assert count.positive? + + while transcript_list.page_details.next_url + transcript_list = client.transcripts.list_by_url(url: transcript_list.page_details.next_url) + + count = 0 + client.transcripts.list.transcripts.each do |transcript| + assert !transcript.id.nil? + count += 1 + end + assert count.positive? + end + end + def test_polling - client = AssemblyAI::Client.new(api_key: "YOUR_API_KEY") + client = AssemblyAI::Client.new(api_key: "YOUR API KEY") transcript = client.transcripts.transcribe(audio_url: "https://storage.googleapis.com/aai-web-samples/espn-bears.m4a") assert transcript.status == AssemblyAI::Transcripts::TranscriptStatus::COMPLETED - client = AssemblyAI::AsyncClient.new(api_key: "YOUR_API_KEY") + client = AssemblyAI::AsyncClient.new(api_key: "YOUR API KEY") Sync do transcript_task = client.transcripts.transcribe(audio_url: "https://storage.googleapis.com/aai-web-samples/espn-bears.m4a") assert transcript_task.is_a? Async::Task @@ -21,7 +44,7 @@ def test_polling def test_transcribe # Transcribe - client = AssemblyAI::Client.new(api_key: "YOUR_API_KEY") + client = AssemblyAI::Client.new(api_key: "YOUR API KEY") transcript_submission = client.transcripts.submit(audio_url: "https://storage.googleapis.com/aai-web-samples/espn-bears.m4a") assert !transcript_submission.id.nil? @@ -37,7 +60,7 @@ def test_transcribe end def test_lemur - client = AssemblyAI::Client.new(api_key: "YOUR_API_KEY") + client = AssemblyAI::Client.new(api_key: "YOUR API KEY") assert !client.lemur.summary(transcript_ids: ["369849ed-b5a1-4add-9dde-ac936d3e7b99"]).response.nil? assert !client.lemur.question_answer(transcript_ids: ["369849ed-b5a1-4add-9dde-ac936d3e7b99"], questions: [{question: "What are they discussing?", answer_format: "text"}]).response.nil?