Skip to content

Instantly share code, notes, and snippets.

@barmstrong
Created June 17, 2011 03:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save barmstrong/1030817 to your computer and use it in GitHub Desktop.
Save barmstrong/1030817 to your computer and use it in GitHub Desktop.
Ruby file to use the Google Prediction API, with a very hacked OAuth2
# Ruby file to use the Google Prediction API, with a very hacked OAuth2
# You'll want to replace all the custom variables including..
# 1. Your google storage bucket name
# 2. Your google storage access credentials (note that gstore only works with "legacy" google storage access so you'll need to enabled this)
# 3. Your OAuth credentials which you setup from here https://code.google.com/apis/console/ by selecting "API Access"
# Note that I choose "Create client ID" and then "Installed Application".
#
# This script is intended to be run as a regular background process (like a cron job) to process data. It has no access to a browser and no web server to expose a callback url. Hence the hacking of OAuth2. This seems completely wrong to me but I haven't gotten any other authentication with the API to work. If anyone knows a better way please post a comment!
#
# Calling 'GooglePredict.run' from the console or 'script/runner "GooglePredict.run"' from your rails app directory should run it.
#
# The first time you run it it will print out a URL on the console, you'll need to copy/paste this into a browser and allow the app. Copy the code it gives you and assign this string to the 'code' variable instead of leaving it as null.
#
# Run the script a second time and you'll get another print statement with the token_hash. Assign this as a hash to the token_hash variable instead of leaving it null.
#
# The third time you run it you should be authenticated with OAuth2. For right now it seems to give you a token which expires in 1 hour. Still trying to figure out a way to extend this since without a longer token it's not very useful as a background task. Hope it helps!
require 'gstore'
require 'fastercsv'
require 'google/api_client'
require 'yaml'
class GooglePredict
BUCKET = "A-GOOGLE-STORAGE-BUCKET-NAME"
def self.run
csv_string = FasterCSV.generate do |csv|
#generate a csv with your data...
#csv << ['spam', '.....']
#csv << ['ham', '.....']
end
filename = store_in_google(csv_string)
client = Google::APIClient.new
client.authorization.client_id = "YOUR_CLIENT_ID"
client.authorization.client_secret = "YOUR_CLIENT_SECRET"
client.authorization.scope = 'https://www.googleapis.com/auth/prediction'
client.authorization.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
code = nil
token_hash = nil
if code.nil?
puts "Please go visit this URL in your browser and copy the new code!"
puts client.authorization.authorization_uri.to_s
return
else
client.authorization.code = code
end
if token_hash.nil?
client.authorization.fetch_access_token!
puts "Copy this as your new token!"
puts "{:refresh_token => '#{client.authorization.refresh_token}', :access_token => '#{client.authorization.access_token}', :expires_at => '#{client.authorization.expires_at}'}"
return
else
client.authorization.update_token!(token_hash)
end
prediction = client.discovered_api('prediction', 'v1.2')
# Make training API call
response = client.execute(prediction.training.insert,{'data' => "#{BUCKET}/#{filename}"})
puts response.to_yaml
# Check Training Status
response = client.execute(prediction.training.get, {'data' => "#{BUCKET}/#{filename}"})
puts response.to_yaml
ensure
#could use this to delete your file in google storage if the training has completed...
#delete_from_google filename
end
def self.gstore_client
@gstore_client ||= GStore::Client.new(
:access_key => "YOUR_GOOGLE_STORAGE_LEGACY_ACCESS_KEY",
:secret_key => "YOUR_GOOGLE_STORAGE_LEGACY_SECRET"
)
end
def self.store_in_google data
puts "Uploading #{data.length / 1000 / 1000}MB to google storage..."
gstore_client.create_bucket(BUCKET) #in case it doesn't exist
filename = "#{BUCKET}-#{Time.now.to_i}.csv"
gstore_client.put_object(BUCKET, filename, :data => data)
filename
end
def self.delete_from_google filename
gstore_client.delete_object(BUCKET, filename)
end
end
@abronte
Copy link

abronte commented Jun 17, 2011

I'm getting a "Missing Access Token" with this. Am I missing something?

@barmstrong
Copy link
Author

I got these periodically as well. Maybe set the code and token_hash back to nil and restart the process?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment