1

我正在努力将 Google Cloud Speech Api 与 ruby​​ 客户端(v0.22.2)一起使用。

我可以执行长时间运行的作业,如果我使用可以得到结果

job.wait_until_done!

但这会在很长一段时间内锁定服务器。

根据 API 文档,我真正需要的只是操作名称(id)。

有没有办法从操作名称创建一个作业对象并以这种方式检索它?我似乎无法创建一个功能性的新作业对象,例如使用来自@grpc_op 的 id

我想做的是:

speech = Google::Cloud::Speech.new(auth_credentials)
job = speech.recognize_job file, options

saved_job = job.to_json #Or some element of that object such that I can retrieve it.

Later, I want to do something like....
job_object = Google::Cloud::Speech::Job.new(saved_job)

job.reload!

job.done?

job.results

真的希望这对某人有意义。与谷歌的 ruby​​ 客户端进行了相当多的斗争,因为一切似乎都被翻译成比使用 API 所需的对象复杂得多的对象。我在这里缺少一些技巧吗?

4

2 回答 2

1

您可以将此功能修补到您正在使用的版本,但我建议升级到google-cloud-speech 0.24.0或更高版本。使用那些更新的版本,您可以使用Operation#idProject#operation完成此操作。

require "google/cloud/speech"

speech = Google::Cloud::Speech.new

audio = speech.audio "path/to/audio.raw",
                     encoding: :linear16,
                     language: "en-US",
                     sample_rate: 16000

op = audio.process
# get the operation's id
id = op.id #=> "1234567890"

# construct a new operation object from the id
op2 = speech.operation id

# verify the jobs are the same
op.id == op2.id #=> true

op2.done? #=> false
op2.wait_until_done!
op2.done? #=> true

results = op2.results

更新由于您无法升级,您可以使用GoogleCloudPlatform/google-cloud-ruby#1214中描述的解决方法将此功能修补到旧版本:

require "google/cloud/speech"

# Add monkey-patches
module Google
  Module Cloud
    Module Speech
      class Job
        def id
          @grpc.name
        end
      end
      class Project
        def job id
          Job.from_grpc(OpenStruct.new(name: id), speech.service).refresh!
        end
      end
    end
  end
end

# Use the new monkey-patched methods
speech = Google::Cloud::Speech.new

audio = speech.audio "path/to/audio.raw",
                     encoding: :linear16,
                     language: "en-US",
                     sample_rate: 16000

job = audio.recognize_job
# get the job's id
id = job.id #=> "1234567890"

# construct a new operation object from the id
job2 = speech.job id

# verify the jobs are the same
job.id == job2.id #=> true

job2.done? #=> false
job2.wait_until_done!
job2.done? #=> true

results = job2.results
于 2017-09-01T15:58:03.273 回答
0

行。有一个非常丑陋的方式来解决这个问题。

从 job 对象中获取 Operation 的 id

operation_id = job.grpc.grpc_op.name

获取访问令牌以手动使用 RestAPI

json_key_io = StringIO.new(ENV["GOOGLE_CLOUD_SPEECH_JSON_KEY"])
authorisation = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io:json_key_io,
  scope:"https://www.googleapis.com/auth/cloud-platform"
)
token = authorisation.fetch_access_token!

进行 api 调用以检索操作详细信息。

这将返回一个 "done" => true 参数,一旦结果进入并显示结果。如果 "done" => true 不存在,那么您将不得不稍后再次轮询,直到它存在。

HTTParty.get(
  "https://speech.googleapis.com/v1/operations/#{operation_id}",
  headers: {"Authorization" => "Bearer #{token['access_token']}"}
)

必须有更好的方法来做到这一点。语音 API 似乎是一个如此明显的用例。

谷歌的任何人都可以解释一种更简单/更清洁的方法吗?

于 2017-08-31T14:20:28.197 回答