Coder Social home page Coder Social logo

watson-developer-cloud / ruby-sdk Goto Github PK

View Code? Open in Web Editor NEW
44.0 16.0 19.0 6.57 MB

:diamonds: Ruby SDK to use the IBM Watson services.

License: Apache License 2.0

Ruby 99.87% Shell 0.11% HTML 0.01% Dockerfile 0.01%
ibm-watson-services watson ibm-watson ruby rubygem ruby-gem hacktoberfest

ruby-sdk's Introduction

IBM Watson Ruby SDK

Build and Test Deploy and Publish Slack codecov.io Gem Version semantic-release CLA assistant

Deprecated builds

Build Status Build status

Ruby gem to quickly get started with the various IBM Watson services.

Announcements

Tone Analyzer Deprecation

​ As of this major release, 3.0.0, the Tone Analyzer api has been removed in preparation for deprecation. If you wish to continue using this sdk to make calls to Tone Analyzer until its final deprecation, you will have to use a previous version. ​ On 24 February 2022, IBM announced the deprecation of the Tone Analyzer service. The service will no longer be available as of 24 February 2023. As of 24 February 2022, you will not be able to create new instances. Existing instances will be supported until 24 February 2023. ​ As an alternative, we encourage you to consider migrating to the Natural Language Understanding service on IBM Cloud. With Natural Language Understanding, tone analysis is done by using a pre-built classifications model, which provides an easy way to detect language tones in written text. For more information, see Migrating from Watson Tone Analyzer Customer Engagement endpoint to Natural Language Understanding. ​

Natural Language Classifier Deprecation

​ As of this major release, 3.0.0, the NLC api has been removed in preparation for deprecation. If you wish to continue using this sdk to make calls to NLC until its final deprecation, you will have to use a previous version. ​ On 9 August 2021, IBM announced the deprecation of the Natural Language Classifier service. The service will no longer be available from 8 August 2022. As of 9 September 2021, you will not be able to create new instances. Existing instances will be supported until 8 August 2022. Any instance that still exists on that date will be deleted. ​ As an alternative, we encourage you to consider migrating to the Natural Language Understanding service on IBM Cloud that uses deep learning to extract data and insights from text such as keywords, categories, sentiment, emotion, and syntax, along with advanced multi-label text classification capabilities, to provide even richer insights for your business or industry. For more information, see Migrating to Natural Language Understanding.

Support for 2.7 ruby

To support 2.7 the http gem dependency is updated to 4.4.0. Since it conflicted with the dependency in the ruby-sdk-core that gem was also updated. Using 2.0.2 or above ruby sdk will require a core of 1.1.3 or above.

Updating endpoint URLs from watsonplatform.net

Watson API endpoint URLs at watsonplatform.net are changing and will not work after 26 May 2021. Update your calls to use the newer endpoint URLs. For more information, see https://cloud.ibm.com/docs/watson?topic=watson-endpoint-change.

Before you begin

Installation

Install the gem:

gem install ibm_watson

Install with development dependencies:

gem install --dev ibm_watson

Inside of your Ruby program do:

require "ibm_watson"

Examples

The examples folder has basic and advanced examples. The examples within each service assume that you already have service credentials.

Running in IBM Cloud

If you run your app in IBM Cloud, the SDK gets credentials from the VCAP_SERVICES environment variable.

Authentication

Watson services are migrating to token-based Identity and Access Management (IAM) authentication.

  • With some service instances, you authenticate to the API by using IAM.
  • In other instances, you authenticate by providing the username and password for the service instance.

Getting credentials

To find out which authentication to use, view the service credentials. You find the service credentials for authentication the same way for all Watson services:

  1. Go to the IBM Cloud Dashboard page.
  2. Either click an existing Watson service instance in your resource list or click Create resource > AI and create a service instance.
  3. Click on the Manage item in the left nav bar of your service instance.

On this page, you should be able to see your credentials for accessing your service instance.

Supplying credentials

There are two ways to supply the credentials you found above to the SDK for authentication.

Credential file (easier!)

With a credential file, you just need to put the file in the right place and the SDK will do the work of parsing and authenticating. You can get this file by clicking the Download button for the credentials in the Manage tab of your service instance.

The file downloaded will be called ibm-credentials.env. This is the name the SDK will search for and must be preserved unless you want to configure the file path (more on that later). The SDK will look for your ibm-credentials.env file in the following places (in order):

  • The top-level directory of the project you're using the SDK in
  • Your system's home directory

As long as you set that up correctly, you don't have to worry about setting any authentication options in your code. So, for example, if you created and downloaded the credential file for your Discovery instance, you just need to do the following:

discovery = DiscoveryV1(version: "2018-08-01")

And that's it!

If you're using more than one service at a time in your code and get two different ibm-credentials.env files, just put the contents together in one ibm-credentials.env file and the SDK will handle assigning credentials to their appropriate services.

If you would like to configure the location/name of your credential file, you can set an environment variable called IBM_CREDENTIALS_FILE. This will take precedence over the locations specified above. Here's how you can do that:

export IBM_CREDENTIALS_FILE="<path>"

where <path> is something like /home/user/Downloads/<file_name>.env.

Manually

If you'd prefer to set authentication values manually in your code, the SDK supports that as well. The way you'll do this depends on what type of credentials your service instance gives you.

IAM

IBM Cloud is migrating to token-based Identity and Access Management (IAM) authentication. IAM authentication uses a service API key to get an access token that is passed with the call. Access tokens are valid for approximately one hour and must be regenerated.

You supply either an IAM service API key or an access token:

  • Use the API key to have the SDK manage the lifecycle of the access token. The SDK requests an access token, ensures that the access token is valid, and refreshes it if necessary.
  • Use the access token if you want to manage the lifecycle yourself. For details, see Authenticating with IAM tokens.

Supplying the IAM API key

# In the constructor, letting the SDK manage the IAM token
authenticator = IBMWatson::Authenticators::IamAuthenticator.new(
  apikey: "<iam_apikey>",
  url: "<iam_url>" # optional - the default value is https://iam.cloud.ibm.com/identity/token
)
discovery = IBMWatson::DiscoveryV1.new(
  version: "2017-10-16",
  authenticator: authenticator
)
discover.service_url = "<service-url>" # setting service url

Supplying the access token

authenticator = IBMWatson::Authenticators::BearerTokenAuthenticator.new(
  bearer_token: "<access_token>"
)
discovery = IBMWatson::DiscoveryV1.new(version: "2017-10-16", authenticator)

Username and password

require "ibm_watson"
require "ibm_cloud_sdk_core"
include IBMWatson
# In the constructor
authenticator = IBMWatson::Authenticators::BasicAuthenticator.new(
  username: "<username>",
  password: "<password>"
)
discovery = DiscoveryV1.new(
  version: "2017-10-16",
  authenticator: authenticator
)

Sending requests asynchronously

Requests can be sent asynchronously. There are two asynchronous methods available for the user, async & await. When used, these methods return an Ivar object.

  • To call a method asynchronously, simply insert .await or .async into the call: service.translate would be service.async.translate
  • To access the response from an Ivar object called future, simply call future.value

When await is used, the request is made synchronously.

authenticator = IBMWatson::Authenticators::BasicAuthenticator.new(
  username: "<username>",
  password: "<password>"
)

speech_to_text = IBMWatson::SpeechToTextV1.new(
  authenticator: authenticator
)
audio_file = File.open(Dir.getwd + "/resources/speech.wav")
future = speech_to_text.await.recognize(
  audio: audio_file
)
p future.complete? # If the request is successful, then this will be true
output = future.value # The response is accessible at future.value

When async is used, the request is made asynchronously

authenticator = IBMWatson::Authenticators::BasicAuthenticator.new(
  username: "<username>",
  password: "<password>"
)

speech_to_text = IBMWatson::SpeechToTextV1.new(
  authenticator: authenticator
)
audio_file = File.open(Dir.getwd + "/resources/speech.wav")
future = speech_to_text.async.recognize(
  audio: audio_file
)
p future.complete? # Can be false if the request is still running
future.wait # Wait for the asynchronous call to finish
p future.complete? # If the request is successful, then this will now be true
output = future.value

Sending request headers

Custom headers can be passed in any request in the form of a Hash as a parameter to the headers chainable method. For example, to send a header called Custom-Header to a call in Watson Assistant, pass the headers as a parameter to the headers chainable method:

require "ibm_watson"
include IBMWatson

assistant = AssistantV1.new(
  authenticator: "<authenticator>"
  version: "2017-04-21"
)

response = assistant.headers(
  "Custom-Header" => "custom_value"
  ).list_workspaces

Parsing HTTP response info

HTTP requests all return DetailedResponse objects that have a result, status, and headers

require "ibm_watson"
include IBMWatson

assistant = AssistantV1.new(
  authenticator: "<authenticator>"
  version: "2017-04-21"
)

response = assistant.headers(
  "Custom-Header" => "custom_value"
  ).list_workspaces

p "Status: #{response.status}"
p "Headers: #{response.headers}"
p "Result: #{response.result}"

This would give an output of DetailedResponse having the structure:

Status: 200
Headers: "<http response headers>"
Result: "<response returned by service>"

Transaction IDs

Every SDK call returns a response with a transaction ID in the X-Global-Transaction-Id header. Together the service instance region, this ID helps support teams troubleshoot issues from relevant logs.

require "ibm_watson"
include IBMWatson

assistant = AssistantV1.new(
  authenticator: "<authenticator>"
  version: "2017-04-21"
)

begin
  response = assistant.list_workspaces
  p "Global transaction id: #{response.headers["X-Global-Transaction-Id"]}"
rescue IBMCloudSdkCore::ApiException => e
  # Global transaction on failed api call is contained in the error message
  print "Error: ##{e}"
end

However, the transaction ID isn't available when the API doesn't return a response for some reason. In that case, you can set your own transaction ID in the request. For example, replace <my-unique-transaction-id> in the following example with a unique transaction ID.

require "ibm_watson"
include IBMWatson

assistant = AssistantV1.new(
  authenticator: "<authenticator>"
  version: "2017-04-21"
)

response = assistant.headers(
  "X-Global-Transaction-Id" => "<my-unique-transaction-id>"
  ).list_workspaces

Configuring the HTTP client

To set client configs like timeout or proxy use the configure_http_client function and pass in the configurations.

require "ibm_watson/assistant_v1"
include IBMWatson

assistant = AssistantV1.new(
  authenticator: "<authenticator>"
  version: "2018-07-10"
)

assistant.configure_http_client(
  timeout: {
    # Accepts either :per_operation or :global
    per_operation: { # The individual timeouts for each operation
      read: 5,
      write: 7,
      connect: 10
    }
    # global: 30 # The total timeout time
  },
  proxy: {
    address: "bogus_address.com",
    port: 9999,
    username: "username",
    password: "password",
    headers: {
      bogus_header: true
    }
  }
)

The HTTP client can be configured to disable SSL verification. Note that this has serious security implications - only do this if you really mean to! ⚠️

To do this, pass disable_ssl_verification as true in configure_http_client(), like below:

require "ibm_watson/assistant_v1"
include IBMWatson

service = AssistantV1.new(
  version: "<version>",
  authenticator: "<authenticator>"
)

service.configure_http_client(disable_ssl_verification: true)

Using Websockets

The Speech-to-Text service supports websockets with the recognize_using_websocket method. The method accepts a custom callback class. The eventmachine loop that the websocket uses blocks the main thread by default. Here is an example of using the websockets method:

require "ibm_watson"

callback = IBMWatson::RecognizeCallback.new
audio_file = "<Audio File for Analysis>"
speech_to_text = IBMWatson::SpeechToTextV1.new(
  username: "<username>",
  password: "<password>"
)
websocket = speech_to_text.recognize_using_websocket(
  audio: audio_file,
  recognize_callback: callback,
  interim_results: true
)
thr = Thread.new do # Start the websocket inside of a thread
  websocket.start # Starts the websocket and begins sending audio to the server.
  # The `callback` processes the data from the server
end
thr.join # Wait for the thread to finish before ending the program or running other code

Note: recognize_with_websocket has been deprecated in favor of recognize_using_websocket

IBM Cloud Pak for Data(CP4D)

If your service instance is of ICP4D, below are two ways of initializing the assistant service.

Supplying the username, password, and url

The SDK will manage the token for the user

authenticator = IBMWatson::Authenticators::CloudPakForDataAuthenticator.new(
  username: "<username>",
  password: "<password>",
  url: "<authentication url>",
  disable_ssl: true
)
assistant = IBMWatson::AssistantV1.new(
  version: "<version>",
  authenticator: authenticator
)

Questions

If you have issues with the APIs or have a question about the Watson services, see Stack Overflow.

Ruby version

Tested on:

  • MRI Ruby (RVM): 2.5.1, 2.6.1
  • RubyInstaller (Windows x64): 2.5.1, 2.6.1

2.3.7 and 2.4.4 should still work but support will be deprecated in next major release.

Contributing

See CONTRIBUTING.md.

License

This library is licensed under the Apache 2.0 license.

Featured projects

Here are some projects that have been using the SDK:

We'd love to highlight cool open-source projects that use this SDK! If you'd like to get your project added to the list, feel free to make an issue linking us to it.

ruby-sdk's People

Contributors

germanattanasio avatar hsaylor avatar kingsodigie avatar lpatino10 avatar mamoonraja avatar maxnussbaum avatar mediumtaj avatar mikemosca avatar nan2iz avatar semantic-release-bot avatar watson-github-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby-sdk's Issues

SpeechToTextV1 create_job Errno::EPIPE: Broken pipe

Errno::EPIPE: Broken pipe
  File "/app/vendor/ruby-2.3.0/lib/ruby/2.3.0/openssl/buffering.rb", line 379, in syswrite_nonblock
  File "/app/vendor/ruby-2.3.0/lib/ruby/2.3.0/openssl/buffering.rb", line 379, in write_nonblock
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/timeout/per_operation.rb", line 89, in block in write
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/timeout/per_operation.rb", line 88, in loop
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/timeout/per_operation.rb", line 88, in write
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/request/writer.rb", line 99, in write
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/request/writer.rb", line 72, in block in send_request
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/request/body.rb", line 35, in each
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/request/writer.rb", line 70, in send_request
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/request/writer.rb", line 38, in stream
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/request.rb", line 115, in stream
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/connection.rb", line 76, in send_request
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/client.rb", line 70, in perform
  File "/app/vendor/bundle/ruby/2.3.0/gems/newrelic_rpm-4.0.0.332/lib/new_relic/agent/instrumentation/http.rb", line 29, in perform_with_newrelic_trace
  File "/app/vendor/bundle/ruby/2.3.0/gems/http-3.3.0/lib/http/client.rb", line 30, in request
  File "/app/vendor/bundle/ruby/2.3.0/gems/ibm_watson-0.1.2/lib/ibm_watson/watson_service.rb", line 160, in request
  File "/app/vendor/bundle/ruby/2.3.0/gems/ibm_watson-0.1.2/lib/ibm_watson/speech_to_text_v1.rb", line 148, in request
  File "/app/vendor/bundle/ruby/2.3.0/gems/ibm_watson-0.1.2/lib/ibm_watson/speech_to_text_v1.rb", line 800, in create_job

My method call looks something like...

IBMWatson::SpeechToTextV1.new(<creds>).create_job(
  audio: <very large StringIO buffer contents>,
  ...
)

Any ideas why this consistently leads to a broken pipe but only for some (perhaps large) audio files ?

List the required dependencies along with their licenses

Dependency License url
concurrent-ruby ~> 1.0 MIT https://github.com/ruby-concurrency/concurrent-ruby
eventmachine ~> 1.2 GPL-2 https://github.com/eventmachine/eventmachine/blob/master/LICENSE
faye-websocket ~> 0.10 No License ⚠️ faye/faye-websocket-node#68
http ~> 3.3 MIT
bundler ~> 1.16 MIT
codecov ~> 0.1 Apache-2.0
dotenv ~> 2.4 MIT
httplog ~> 1.0 MIT
minitest ~> 5.11 MIT
minitest-hooks ~> 1.5 MIT
minitest-reporters ~> 1.3 MIT
minitest-retry ~> 0.1 MIT
rake ~> 12.3 MIT
rubocop ~> 0.57 MIT
simplecov ~> 0.16 MIT
webmock ~> 3.4 MIT

IAMTokenManager leaks constants names

Hi everyone,

I was experiencing some unusual behaviour on a project where, by simply adding the ibm-watson gem to the Gemfile I would get several requests to fail with a 400 Bad request error message.

Digging through the code I found out that IAMTokenManager is declaring constants outside the class scope, so they are being leaked to the rest of the application.

This was causing issues for me because Faraday uses the value of CONTENT_TYPE as the header key, so my requests were sending a ill-formed Application/x-Www-Form-Urlencoded: application/x-www-form-urlencoded header.

The fix should be simple enough, since I don't think these values are referenced outside this class.

Disable Two or More Connection with Speech To Text Websocket (Real-Time) Recognition

Two or more connection with speech to text websocket (Real-Time) recognition using ruby-sdk is disable. (Single connection is enable.)

I researched the reason of this issue, and discover two things.
1. From second connection, "action:start" parameter is not sent for starting real-time recognition.

  1. By modifying (comment out) below code, two or more connection is enable.
    websocket/speech_to_text_websocket_listener.rb l78
#before
EM&.reactor_thread&.join
#after
#EM&.reactor_thread&.join

Why does two or more connection disable? In addition, please fix it to enable real-time recognition of two or more connection.

Unauthorized error for NaturalLanguageUnderstandingV1

Description
After using IAM keys (from "Manage" page) and JSON creds (from "Service Credentials" file) I still get IBMCloudSdkCore::ApiException (Error: Unauthorized, Code: 401, Information: {}) error.

To Reproduce
Steps to reproduce the behavior:

iam_api_creds = {
  iam_url: "https://gateway.watsonplatform.net/natural-language-understanding/api",
  iam_apikey: "XXXXXXX",
  version: "2019-07-12"
}

json_service_creds = {
  apikey: "XXXXXXX",
  iam_apikey_description: "Auto-generated for key XXXXXXX",
  iam_apikey_name: "Auto-generated service credentials",
  iam_role_crn: "crn:v1:bluemix:public:iam::::serviceRole:Manager",
  iam_serviceid_crn: "crn:v1:bluemix:public:iam-identity::a/XXXXXXX::serviceid:ServiceId-XXXXXXX-51d4-429e-95b1-XXXXXXX",
  url: "https://gateway.watsonplatform.net/natural-language-understanding/api"
}

natural_language_understanding = IBMWatson::NaturalLanguageUnderstandingV1.new(iam_api_creds)

response = natural_language_understanding.analyze(
  text: "Bruce Banner is the Hulk and Bruce Wayne is BATMAN!", features: { "entities" => {} }
).result # Getting IBMCloudSdkCore::ApiException#Unauthorized exception here

natural_language_understanding = IBMWatson::NaturalLanguageUnderstandingV1.new(json_service_creds)

response = natural_language_understanding.analyze(
  text: "Bruce Banner is the Hulk and Bruce Wayne is BATMAN!", features: { "entities" => {} }
).result # Getting IBMCloudSdkCore::ApiException#Unauthorized exception here

Expected behavior
Result of NLP processing.

Actual behavior
Getting following error

IBMCloudSdkCore::ApiException (Error: Unauthorized, Code: 401, Information: {})

Desktop (please complete the following information):

  • Mac OS X 10.13.6
  • Ruby 2.5.1
  • I've tried with 0.12.0, 0.17.1 and 0.19.1 watson-developer-cloud/ruby-sdk versions

Additional context
Approximately half of a year I got this running with version 0.12

v1 Goals

IBM Watson Ruby SDK is still in beta, We planning to release v1 in September and goal of this issue is to establish timeline add goals for the v1 release.

Breaking Changes

  • Move the core out of the SDK #58
  • Update all dependencies
  • WebSocket Library changes (under investigation), related to faye/faye-websocket-ruby#115
  • Disable SSL authentication for Speech Websockets
  • #49
  • #40
  • #50

Would welcome some community feedback on some of these goals - do people want these things? Are there other implementations/packages we should be looking at? Any comments are appreciated!

Question about IAM authenticator token renewal

Hi -
I'm using version 1.1.2 of ruby-sdk-core in a rails app alonside version 2.1 of ruby-sdk to access the NLU API and I could use a tip on authenticator lifecycle if you have a minute. I'm not sure if this is a bug or I'm just doing it wrong (likely the latter:)) In a rails app on service startup, I initialize an IBMWatson::Authenticators::IamAuthenticator and keep a reference to it:

        config.authenticator = IBMWatson::Authenticators::IamAuthenticator.new(
          apikey: config.service_access_key
        )

which goes fine. Then, as requests come into the app, as part of handling each request I initialize a new Watson API client object, and pass it the reference to the IamAuthenticator object:

      @watson = IBMWatson::NaturalLanguageUnderstandingV1.new(
        authenticator: @configuration.authenticator,
        version: "2020-08-01"
      )
      @watson.service_url = @configuration.service_url
      @watson.configure_http_client(timeout: { global: @configuration.timeout } )

which also works great at first. But then at some point I start getting 401s back. This has been happening fairly regularly. I think it's after a period of inactivity - the time span between a successful attempt at 2:08PM and the next attempt (which failed) at 3:13PM was over an hour. Here's a log entry (apologies for my json format):

E, [2021-07-01T15:44:31.726112 #76077] ERROR -- : [a57cdfe7-a5c2-47d2-8eb7-7005dbdb7eb9] Error: Unauthorized, Code: 401, Information: {"trace"=>"ba11b8d2-802c-46a8-b910-43b37b4a03ec", "more_info"=>"https://cloud.ibm.com/docs/watson?topic=watson-authorization-error"}, X-dp-watson-tran-id: ba11b8d2-802c-46a8-b910-43b37b4a03ec, X-global-transaction-id: ba11b8d2-802c-46a8-b910-43b37b4a03ec

It won't work again until I restart the service. I think I read that the authenticator would renew the token as needed which I interpreted as meaning I don't ever need to re-initialize an authenticator as part of normal operation. But should I be? I could just wrap the client requests in a handler that renews the authenticator if there's a 401 but I want to make sure I'm not doing something wrong here.

Thanks for any insight!

Issue with Ngrok and desactivating SSL

Hi,

I have an error on parsing an API response error.

`<TITLE>Access Denied</TITLE>

Access Denied

You don't have permission to access "http://api.eu-gb.assistant.watson.cloud.ibm.com/v2/assistants/fa41d158-9382-4da6-9db8-7c47fb92e141/sessions/e9283ba2-2cc3-450d-9688-0450c8d5856c/message?" on this server.


Reference #18.be3e2217.1674809815.1927c3e

'`

json-2.3.1/lib/json/common.rb:263:in parse' ibm_cloud_sdk_core/api_exception.rb:15:in initialize'
ibm_cloud_sdk_core/base_service.rb:113:in new' ibm_cloud_sdk_core/base_service.rb:113:in request'

Service Status

OK

Describe the bug

When trying to access to Watson API, we have an error unmanaged by the gem

To Reproduce

Use Ngrok, lauch a console and call the message function

Expected behavior

We expect to parse correctly the message

Actual behavior

JSON::ParserError: 784: unexpected token at '

Screenshots

Desktop (please complete the following information):

  • OS: Linux Ubuntu 20.04.5 LTS
  • Ruby Version : 2.6.6

Additional context

Speaker labels unavailable

When using real-time recognition using websocket, my application sends below request parameters including "speaker_labels: true," to Watson STT.
However, my application cannot receive "speaker" (speaker ID) from Watson STT.

ws = speech_to_text.recognize_using_websocket(
  recognize_callback: mycallback,
  content_type: "audio/l16;rate=44100",
  chunk_data: true,
  model: 'ja-JP BroadbandModel',
  language_customization_id: nil,
  acoustic_customization_id: nil,
  interim_results: true,
  timestamps: true,
  inactivity_timeout: -1,
  speaker_labels: true,
  profanity_filter: true
)

Please research and fix its issue.

Cannot Delete Custom Words of Full-Size (Double Byte) Alphanumeric.

Ruby-sdk cannot delete custom word of Full-size (double byte) alphanumeric.
I research this issue, and discover to change Full-size alphanumeric to Half-size alphanumeric for normalization.

Base Model: ja-JP_BroadbandModel
Target word example: ABC

Please research and fix its issue.

Tone Analyzer: Invalid JSON input

Describe the bug
Can not call Tone Analyzer API

To Reproduce
Steps to reproduce the behavior:

authenticator = IBMWatson::Authenticators::IamAuthenticator.new(apikey: "API KEY")
service = IBMWatson::ToneAnalyzerV3.new(version: "2017-09-21", authenticator: authenticator)
service.service_url = "https://api.us-south.tone-analyzer.watson.cloud.ibm.com/instances/<some_id>/v3/tone_chat?version=2017-09-21"
text = "Team, I know that times are tough! Product sales have been disappointing for the past three quarters. We have a competitive product, but we need to do a better job of selling it!"
tone = service.tone( tone_input: {text: text},  content_type: "application/json")

Expected behavior
Can call API successfully

Actual behavior
A clear and concise description of what you expected to happen.

IBMCloudSdkCore::ApiException (Error: Invalid JSON input at line 1, column 10, Code: 400, Information: {"sub_code"=>"C00012"}, X-dp-watson-tran-id: 9d10aa5e-888a-4a0f-b2f9-688a2d51abf6, X-global-transaction-id: 9d10aa5e-888a-4a0f-b2f9-688a2d51abf6)

Desktop (please complete the following information):

  • OS: Mac Catalina
  • Ruby Version: ruby-2.6.6

** Additional Context**

  1. I follow the document here https://cloud.ibm.com/apidocs/tone-analyzer?code=ruby#sync and here https://github.com/watson-developer-cloud/ruby-sdk/blob/master/examples/tone_analyzer_v3.rb
  2. It seems API doesn't support "text/plain" anymore also.

Speech to text not working with websockets

Describe the bug
Speech to text is not working with websockets. Works fine with synchronous recognize.

To Reproduce
Here is the code:

#!/usr/bin/env ruby

require "ibm_watson/speech_to_text_v1"
require "ibm_watson/websocket/recognize_callback"
require "ibm_watson/authenticators"
require "json"

authenticator = IBMWatson::Authenticators::IamAuthenticator.new(
  apikey: ENV['API_KEY']
)

speech_to_text = IBMWatson::SpeechToTextV1.new(
  authenticator: authenticator
)

speech_to_text.service_url = ENV['API_URL']

File.open(Dir.getwd + "/resources/speech.wav") do |audio_file|
  recognition = speech_to_text.recognize(
    audio: audio_file,
    content_type: "audio/wav",
    timestamps: true,
    word_confidence: true
  ).result
  puts JSON.pretty_generate(recognition)
end

# Example using websockets
class MyRecognizeCallback < IBMWatson::RecognizeCallback
  def initialize
    super
  end

  def on_transcription(transcript:)
    puts JSON.pretty_generate(transcript)
  end

  def on_connected
    puts "Connection was successful"
  end

  def on_error(error:)
    puts "Error received: #{error}"
    puts "Error message: #{error.message}"
  end

  def on_inactivity_timeout(error:)
    puts "Inactivity timeout: #{error}"
  end

  def on_listening
    puts "Service is listening"
  end

  def on_transcription_complete
    puts "Transcription completed"
  end

  def on_hypothesis(hypothesis:)
    puts hypothesis.to_s
  end

  def on_data(data:)
    puts data.to_s
  end
end

mycallback = MyRecognizeCallback.new
File.open(Dir.getwd + "/resources/speech.wav") do |audio_file|
  speech_to_text.recognize_using_websocket(
    audio: audio_file,
    recognize_callback: mycallback,
    content_type: "audio/wav"
  ).start
end

Expected behavior
I am expecting to see a successful connected message from the recognize callback.

Actual behavior

Error received: #<Faye::WebSocket::API::ErrorEvent:0x00000000029eaa28>
Error message: Error during WebSocket handshake: Unexpected response code: 401

Desktop (please complete the following information):

  • Docker
  • ruby-2.4.3
  • ibm_cloud_sdk_core-1.1.1
  • ibm_watson-1.2.0

Additional context
By adding the authentication step before sending websocket request I was able to make it work:

diff --git a/lib/ibm_watson/speech_to_text_v1.rb b/lib/ibm_watson/speech_to_text_v1.rb
index 7451924..ba3c20a 100644
--- a/lib/ibm_watson/speech_to_text_v1.rb
+++ b/lib/ibm_watson/speech_to_text_v1.rb
@@ -567,6 +567,7 @@ module IBMWatson

       require_relative("./websocket/speech_to_text_websocket_listener.rb")
       headers = {}
+      @authenticator.authenticate(headers)
       headers = conn.default_options.headers.to_hash unless conn.default_options.headers.to_hash.empty?
       service_url = @service_url.gsub("https:", "wss:")
       params = {

Thanks!

Authentication fails using ibm-credentials.env file

Describe the bug
Authentication always fails when trying to use the downloaded ibm-credentials.env file.

To Reproduce
Create a IBM_CREDENTIALS_FILE environment variable and point to the downloaded credentials file. Simple create a service using only the version parameter, and it will fail to authenticate.

Expected behavior
No authentication errors.

Problem Resolution
The bug is pretty simple to fix. The ibm_cloud_sdk_core uses the display_name parameter to load the authentication variables from the file. If this parameter is not set, then the credentials file is not loaded.

All of the initialization routines in this package set the display_name parameter AFTER the call to super, so the value is never passed to the super class (ibm_cloud_sdk_core). The display_name parameter needs to be set before calling super.

As a side comment, even though this fixes the loading and parsing of the credentials file, code is missing from the base_service module to actually use the apikey and url read from the credentials file. It looks like this functionality was never actually finished.

Has Occured TypeError in STT Real-Time Recognition.

We discover to have occured TypeError in STT real-time recognition, and disconnect websocket connection. Error logs as below.

TypeError - [82, 73, 70, 70, 32, 64, 1, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, 0, 1, 0, 68, 172, 0, 0, 136, 88, 1, 0, 2, 0, 16, 0, 100, 97, 116, 97, 0, 64, 1, 0, 0, 0, 0, ... 0, 0, 0] is not a symbol nor a string]: 
/home/centos/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/ibm_watson-0.10.0/lib/ibm_watson/websocket/speech_to_text_websocket_listener.rb:156:in `send_chunk' | /home/centos/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/ibm_watson-0.10.0/lib/ibm_watson/websocket/speech_to_text_websocket_listener.rb:119:in `send_audio' | /home/centos/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/ibm_watson-0.10.0/lib/ibm_watson/websocket/speech_to_text_websocket_listener.rb:136:in `block in send_audio' | /home/centos/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run_machine' | /home/centos/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/eventmachine-1.2.7/lib/eventmachine.rb:195:in `run'

Please research its issue.

Returns LoadError (cannot load such file -- ibm_watson/authenticators):

I am trying to test out watson NLU features, and I keep getting this error:

LoadError (cannot load such file -- ibm_watson/authenticators):
  
app/controllers/concerns/watson.rb:2:in `<module:Watson>'
app/controllers/concerns/watson.rb:1:in `<main>'
app/controllers/messages_controller.rb:2:in `<class:MessagesController>'
app/controllers/messages_controller.rb:1:in `<main>'
Started POST "/messages" for ::1 at 2020-01-16 14:57:36 -0500

My ruby version is 2.6.2 and I am running on Rails 6.0.1

Please help

the code is as follows:

require "ibm_watson/authenticators"
    require "ibm_watson/natural_language_understanding_v1"
    include IBMWatson

    def parse_messages()
        authenticator = IBMWatson::Authenticators::IamAuthenticator.new(
            apikey: ENV['API_KEY'],
        )
         
        natural_language_understanding = NaturalLanguageUnderstandingV1.new(
            version: "2019-07-12",
            authenticator: authenticator
        )
        natural_language_understanding.service_url = ENV['API_URL']
        response = natural_language_understanding.analyze(
            url: "www.ibm.com",
            features: {categories: {limit:3}}
        )
        puts JSON.pretty_generate(response.result)
    end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.