From 31f1e29800dfd3f822bd39a27625ce707235814f Mon Sep 17 00:00:00 2001 From: Jesse LaRusso Date: Fri, 24 Aug 2018 17:18:23 -0400 Subject: [PATCH] WIP: Add Clarifai class for image classification --- Gemfile | 1 + Gemfile.lock | 9 ++++++++ config/application.rb | 1 + lib/clarifai.rb | 43 +++++++++++++++++++++++++++++++++++++++ spec/lib/clarifai_spec.rb | 41 +++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 3 +++ 6 files changed, 98 insertions(+) create mode 100644 lib/clarifai.rb create mode 100644 spec/lib/clarifai_spec.rb diff --git a/Gemfile b/Gemfile index 4e5567b..27c7a18 100644 --- a/Gemfile +++ b/Gemfile @@ -31,4 +31,5 @@ group :test do gem "launchy" gem "rspec-rails" gem "shoulda-matchers" + gem "webmock" end diff --git a/Gemfile.lock b/Gemfile.lock index d678b1b..03ba032 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,6 +61,8 @@ GEM xpath (~> 3.1) coderay (1.1.2) concurrent-ruby (1.0.5) + crack (0.4.3) + safe_yaml (~> 1.0.0) crass (1.0.4) debug_inspector (0.0.3) diff-lcs (1.3) @@ -81,6 +83,7 @@ GEM ffi (1.9.25) globalid (0.4.1) activesupport (>= 4.2.0) + hashdiff (0.3.7) hashie (3.5.7) http (3.3.0) addressable (~> 2.3) @@ -188,6 +191,7 @@ GEM rspec-mocks (~> 3.8.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + safe_yaml (1.0.4) sass (3.5.7) sass-listen (~> 4.0.0) sass-listen (4.0.0) @@ -223,6 +227,10 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.5) + webmock (3.4.2) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) @@ -252,6 +260,7 @@ DEPENDENCIES shoulda-matchers simple_form uglifier + webmock RUBY VERSION ruby 2.5.1p57 diff --git a/config/application.rb b/config/application.rb index 4402ba9..3091301 100644 --- a/config/application.rb +++ b/config/application.rb @@ -19,5 +19,6 @@ module MyImages # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de + config.autoload_paths += %W(#{config.root}/lib) end end diff --git a/lib/clarifai.rb b/lib/clarifai.rb new file mode 100644 index 0000000..6478736 --- /dev/null +++ b/lib/clarifai.rb @@ -0,0 +1,43 @@ +require 'base64' +require 'http' + +class Clarifai + KEY = ENV.fetch("CLARIFAI_API_KEY").freeze + API_URL = "https://api.clarifai.com/v2/models/aaa03c23b3724a16a56b629203edc62c/outputs" + + attr_reader :tags + + def initialize(image_path) + @image_path = image_path + end + + def predict! + headers = { + "Authorization": "Key #{KEY}", + "Content-Type": "application/json" + } + params = { + "inputs": [ + { + "data": { + "image": { + "base64": Base64.encode64(File.read(@image_path)) + } + } + } + ] + } + + resp = HTTP. + headers(headers). + post(API_URL, json: params) + + extract_tags(JSON.parse(resp.body)) + end + + def extract_tags(response_hash) + @tags = response_hash["outputs"][0]["data"]["concepts"].map do |concept| + concept["name"] + end + end +end diff --git a/spec/lib/clarifai_spec.rb b/spec/lib/clarifai_spec.rb new file mode 100644 index 0000000..5f9d2b0 --- /dev/null +++ b/spec/lib/clarifai_spec.rb @@ -0,0 +1,41 @@ +require "spec_helper" +ENV["CLARIFAI_API_KEY"] = "1234" +require "clarifai" + +describe Clarifai do + describe ".predict" do + it "predicts tags for our image" do + stub_body = { + "outputs": [ + { + "data": { + "concepts": [ + { + "id": "ai_PpTcwbdQ", + "name": "computer", + "value": 0.96887743 + }, + { + "id": "ai_62K34TR4", + "name": "technology", + "value": 0.96544206 + } + ] + } + } + ] + }.to_json + + WebMock. + stub_request(:post, Clarifai::API_URL). + to_return(:status => 200, :body => stub_body) + + clarifai_image = Clarifai.new("spec/fixtures/spectrum.jpg") + clarifai_image.predict! + + expect(clarifai_image.tags).to eq(["computer", "technology"]) + end + end +end + + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ce33d66..f9928a0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,6 @@ +require 'webmock/rspec' +WebMock.disable_net_connect! + # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause