5

I was very happy to see the google code: google-api-ruby-client project, because it meant to me that Ruby people can polish code with the Google API-s.

For now though I'm stumped because the only example given uses Buzz and from my experiments, the Google Translate (v2) api must behave quite differently to Buzz in the google-api-ruby-client.

I was intrigued by the 'Explorer' demo example -- But it isn't much of an explorer as far as I can see. All it does is call up a Buzz service and then pokes about in things it ALREADY knows about Buzz the services. To me, an explorer ought to let you 'discover' the services and the methods/functions exposed without necessarily knowing them already.

I'd love to hear of Ruby command line and desktop applications using this: google-api-ruby-client for services other than Buzz and in particular the Translate api (I'm less interested in the existing Ruby gems using the translate service at this point).

thanks ... will

Bob Aman
  • 32,839
  • 9
  • 71
  • 95
will
  • 4,799
  • 8
  • 54
  • 90

6 Answers6

9

Code for making calls to the translate API looks like this:

require 'google/api_client'
client = Google::APIClient.new(:key => YOUR_DEVELOPER_KEY)
translate = client.discovered_api('translate', 'v2')
result = client.execute(
  :api_method => translate.translations.list,
  :parameters => {
    'format' => 'text',
    'source' => 'en',
    'target' => 'es',
    'q' => 'The quick brown fox jumped over the lazy dog.'
  }
)
Bob Aman
  • 32,839
  • 9
  • 71
  • 95
  • Hi Bob -- Thanks for that, yes the first part works with your example. However I've got a challenge from the SSL code now. It won't validate the Host certificate. I saw this when testing with CURL, but at least with CURL you can set-up a CERT file. Do you have a config option for the GoogleApi? – will Mar 04 '11 at 13:19
  • Eh? That sounds like a problem with your environment. What exactly is the error? – Bob Aman Mar 04 '11 at 18:14
  • ERROR ......... c:/bin/ruby/v1.9/lib/ruby/1.9.1/net/http.rb:678:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server cer tificate B: **certificate verify failed** (OpenSSL::SSL::SSLError) – will Mar 07 '11 at 14:54
  • I'm sure it is in the environment. What I am not succeeding in finding is HOW to specify the CRT (certificate) file for Ruby. I've seen lots and lots and lots of '(non-)_advice_' to not-check-certificates. I wonder, "do these people also disconnect the brakes on their cars?" Anyway if you can point me to a programmer documentation for Ruby (not rdoc APIs) that would be helpful. – will Mar 07 '11 at 15:00
  • If curl fails too, it's probably either a system-level certificate you're missing or you're running into a certificate being served up by an SNI mechanism, which Ruby won't support until Ruby 1.9.3. You can check by making the request directly in your browser. If that fails too, you're probably missing a root CA somehow. I haven't the foggiest idea how to fix that on Windows. – Bob Aman Mar 07 '11 at 18:40
  • cURL and _All_ browsers work _great_ with the **Google API**. Both with raw URI-s and my _javascript_ app. My purpose was to convert that app to Ruby for some further desktop automation. Whatever you use, you need the CA certificates. They are not packaged with anything. I used the [CA Extract](http://curl.haxx.se/docs/caextract.html) procedure to extract the certificates Firefox uses. – will Mar 07 '11 at 21:21
  • * I should add, that the _default_ Ruby::OpenSSL is (or was) to [NOT verify certificates](http://www.rubyinside.com/how-to-cure-nethttps-risky-default-https-behavior-4010.html) (see below). That may be OK for a prototyping exercise and for testing (it is a bit _quicker_). In real-life(_tm_) its more like driving _without brakes_. – will Mar 07 '11 at 21:33
  • Yes, I completely agree, and by default, the Google API client turns verification on. Could you please verify that manually making the call to set `ca_file` fixes your issue? If it does, I'll go ahead and update the client to make it easier for you to set that. – Bob Aman Mar 08 '11 at 02:39
  • Fair enough. Please see: **[Ruby OpenSSL Set-up or Configuration for Your Application Code](http://stackoverflow.com/questions/5233169/ruby-openssl-set-up-or-configuration-for-your-application-code)** – will Mar 08 '11 at 13:48
  • -- Personally I don't think an API layer needs to expose detail of the Remote Operations, Session Layer or Services Layer via the Gem. I was just going to mail direct. However, your contact page is turned off. – will Mar 08 '11 at 13:51
  • You know what? I completely forgot about this, but I already made this configurable: You can either set a `CA_FILE` environment variable, or just put the certificate bundle at `~/.cacert.pem`. – Bob Aman Mar 10 '11 at 22:56
  • Hi Bob. Please take a look at my Bug report: Issue #06 ([Execute FAIL-s SSL-VERIFY for Google Translate](http://code.google.com/p/google-api-ruby-client/issues/detail?id=6)) as noted below. It seems the SSL works great to begin with. I stuck in some 'peek' code to investigate. (That stuff is included with bug description #06). I will investigate the CA_FILE setting option too. Thanks a bunch of banannas @mate. – will Mar 11 '11 at 16:20
  • Thanks for the CA_FILE setting. I rather think the idea of an environment variable needs to be in something like OpenSSL or Net or HttpAdapter, not in a middleware (services) layer myself. I've now scanned all of Ruby 1.8, 1.9 JRuby 1.3 and 1.6. Nothing at the session or transport layer level appears to be loading a certificate authority from an environment variable or a file. There is no "~/.cacert.pem" file on Windows. – will Mar 14 '11 at 10:48
  • Well, the new implementation of `httpadapter` resolves this all much more neatly. – Bob Aman Mar 14 '11 at 20:04
  • It seems this code no longer works. I get an error "ArgumentError: Missing access token." on execute method. Is simple key still supported? – Jeremy Mar 18 '12 at 16:22
  • @Jeremy: Client has changed pretty significantly since I answered this question. I'll update the answer. – Bob Aman Mar 24 '12 at 10:47
3

I posted up full code and detail for auth issues and workarounds (using an api key) at the code abode - google-api-client for ruby

After installing the gem, getting a Google API Key, and setting up a custom search account (with its prefs widened to all web pages).... I could trawl google search results in irb with the following (copy paste into irb, then inspect response when finished):

  require 'openssl'
  OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

  require 'google/api_client'
  client = Google::APIClient.new(:key => 'your-api-key', :authorization => nil)
  search = client.discovered_api('customsearch')

  response = client.execute(
    :api_method => search.cse.list,
    :parameters => {
      'q' => 'the hoff',
      'key' => 'your-api-key',
      'cx' => 'your-custom-search-id'
    }
  )

This is to get server access to the google api and bypass all the oauth stuff. THE MOST IMPORTANT BIT was the :authorization param when constructing he client.... this ensures the api key is used when calling, in preference to oauth. Without it you will get 401 Unauthorized response status everytime.

Ben
  • 1,203
  • 13
  • 8
  • This part helped me get over the SSL error: require 'openssl' OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE – thekingoftruth Sep 09 '13 at 09:25
  • Yeah - definitely not production worthy that line tho... a bit dangerous. To get around it you'll probably need to update your certificates cd /etc/ssl/certs sudo wget http://curl.haxx.se/ca/cacert.pem – Ben Sep 11 '13 at 05:48
3

I recently tackled this in a Rails 5 project and here is how I got it to work. I recognize this is using a newer Google Gem - but hopefully people will find this more recent answer and find it useful.

First you will need to enable the translation API in the Google Console - and I also created a service account here. I walked through a wizard here and got my json credentials file (see below).

First:

/Gemfile

gem 'google-cloud-translate'

I added the ENV setting to an initializer file. I also added a project string... took me a while to figure out. Make sure to set 'google-project-name' on the second line to your google console project name!

/config/initializers/my_project_name_init.rb

ENV['GOOGLE_APPLICATION_CREDENTIALS'] = Rails.root.to_s + '/cert/my_project-translation-credentials.json'
GOOGLE_TRANSLATE_PROJECT_STRING = "projects/google-project-name/locations/us-central1"

After this it's fairly easy. I added a simple method to a model:

require "google/cloud/translate"
client   = Google::Cloud::Translate.new
response = client.translate_text(["Let's go surfing"], 'fr', GOOGLE_TRANSLATE_PROJECT_STRING)
translation = response.translations&.first&.translated_text

I know this is a sophomoric answer - but I hope this saves someone a lot of time. It took me way too long to get to this, google's docs are outdated, redundent and just awful...

Eskim0
  • 775
  • 7
  • 17
  • Thanks for this, the Google::Cloud::Translate.new doesn't seem to play nice anymore but the ENV in the initializer got me out a hole as it just wasn't seeing the server env. – Stewart McEwen Feb 03 '21 at 08:22
0

Thanks to Bob, I'm one step forward.

I'm now finding trouble with the .CRT certificates file. I have a CA-bundle I got from the CA-bundle generator available on the cURL site (http://curl.haxx.se/ca).

Read also: How to Cure NetHhttps Risky Default HTTPS Behavior

I think the next question needs to be about finding the bundle for OpenSSL.

w.

will
  • 4,799
  • 8
  • 54
  • 90
0

Hi (all) interested folks,

More progress. I put a bug report for Google-API-Ruby-client for part of this problem. The short version is that for Translate (at least) the Google-API-Ruby-client fails under SSL::VERIFY_PEER and succeeds when SSL::VERIFY_NONE is used.

In a nut shell there's one problem to fix and two enhancements needed.

  1. An API-client interface layer should report an Error or Warning when the underlying layers (as can be known or detected) invalidate security, identity-privacy and data integrity.
  2. Report on relevant configuration information for the underlying service used (e.g. was SSL used? Was it VERIFY_PEER or VERIFY_NONE? What is the fully qualified URI to give the error? For me, I think that info can do to a log-file of sorts and be 'Requested' by an Option on the service class (class methods) and by the instance variable.
  3. Provide diagnostics with your Gem design and extend diagnostics into your own code (e.g. metrics like: number of network 'execute' calls made, number of bytes in and bytes out).
will
  • 4,799
  • 8
  • 54
  • 90
  • 1
    Explanation: The bug is definitely in [Google-API-Ruby-client](http://code.google.com/p/google-api-ruby-client/), the SSL works on the first call and not on the **execute( )** method. – will Mar 11 '11 at 16:10
  • Supplemental hint: One might use the info. (Ruby examples) in the bug report to test without SSL on the API-calls. That's definitely NOT for production code with 'real users' in the wide-world. – will Mar 11 '11 at 16:14
0

I have a solution here (http://jjinux.blogspot.com/2012/02/ruby-working-around-ssl-errors-on-os-x.html) that monkey patches Net::HTTP#use_ssl= in order to use the operating system's root certificates.

Shannon -jj Behrens
  • 4,910
  • 2
  • 19
  • 24