eclaircir 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +17 -0
  5. data/LICENSE +21 -0
  6. data/README.md +70 -0
  7. data/Rakefile +12 -0
  8. data/TODO.md +75 -0
  9. data/bin/console +10 -0
  10. data/bin/test.rb +17 -0
  11. data/eclaircir.gemspec +20 -0
  12. data/lib/eclaircir/api_models/attributes/nullable_date_time.rb +15 -0
  13. data/lib/eclaircir/api_models/attributes.rb +8 -0
  14. data/lib/eclaircir/api_models/base_model.rb +11 -0
  15. data/lib/eclaircir/api_models/concept.rb +12 -0
  16. data/lib/eclaircir/api_models/data.rb +17 -0
  17. data/lib/eclaircir/api_models/input.rb +22 -0
  18. data/lib/eclaircir/api_models/media.rb +9 -0
  19. data/lib/eclaircir/api_models/model.rb +29 -0
  20. data/lib/eclaircir/api_models/output.rb +14 -0
  21. data/lib/eclaircir/api_models/response.rb +16 -0
  22. data/lib/eclaircir/api_models/status.rb +46 -0
  23. data/lib/eclaircir/api_models.rb +16 -0
  24. data/lib/eclaircir/client/status_validator.rb +30 -0
  25. data/lib/eclaircir/client.rb +85 -0
  26. data/lib/eclaircir/configuration.rb +16 -0
  27. data/lib/eclaircir/constants.rb +5 -0
  28. data/lib/eclaircir/error.rb +27 -0
  29. data/lib/eclaircir/version.rb +5 -0
  30. data/lib/eclaircir.rb +32 -0
  31. data/spec/eclaircir/api_models/concept_spec.rb +32 -0
  32. data/spec/eclaircir/api_models/data_spec.rb +104 -0
  33. data/spec/eclaircir/api_models/input_spec.rb +70 -0
  34. data/spec/eclaircir/api_models/media_spec.rb +15 -0
  35. data/spec/eclaircir/api_models/model_spec.rb +109 -0
  36. data/spec/eclaircir/api_models/output_spec.rb +42 -0
  37. data/spec/eclaircir/api_models/response_spec.rb +63 -0
  38. data/spec/eclaircir/api_models/status_spec.rb +67 -0
  39. data/spec/eclaircir/client/status_validator_spec.rb +77 -0
  40. data/spec/eclaircir/client_spec.rb +123 -0
  41. data/spec/eclaircir/configuration_spec.rb +64 -0
  42. data/spec/eclaircir_spec.rb +55 -0
  43. data/spec/etc/fixtures/predict_outputs/invalid_request.json +7 -0
  44. data/spec/etc/fixtures/predict_outputs/success.json +58 -0
  45. data/spec/factories/concept.rb +8 -0
  46. data/spec/factories/data.rb +13 -0
  47. data/spec/factories/input.rb +7 -0
  48. data/spec/factories/media.rb +6 -0
  49. data/spec/factories/model.rb +9 -0
  50. data/spec/factories/response.rb +7 -0
  51. data/spec/factories/status.rb +7 -0
  52. data/spec/spec_helper.rb +53 -0
  53. metadata +122 -0
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eclaircir::Client do
4
+ subject do
5
+ described_class.new(api_key)
6
+ end
7
+
8
+ let(:api_key) do
9
+ 'xxx'
10
+ end
11
+
12
+ describe '#models' do
13
+ before do
14
+ stub_request(:get, 'https://api.clarifai.com/v2/models')
15
+ .with(headers: {
16
+ 'Content-Type' => 'application/json',
17
+ 'Authorization' => 'Key xxx',
18
+ })
19
+ end
20
+
21
+ it 'uses the right authorization header' do
22
+ expect do
23
+ subject.models
24
+ end.not_to raise_error
25
+ end
26
+ end
27
+
28
+ describe '#predict_outputs' do
29
+ before do
30
+ stub_request(:post, 'https://api.clarifai.com/v2/models/blah/outputs')
31
+ .with(
32
+ headers: {
33
+ 'Content-Type' => 'application/json',
34
+ 'Authorization' => 'Key xxx',
35
+ },
36
+ body: {
37
+ 'inputs' => [
38
+ {
39
+ 'data' => {
40
+ 'image' => {
41
+ 'url' => 'http://example.com/lol.jpg'
42
+ },
43
+ 'concepts' => []
44
+ }
45
+ }
46
+ ]
47
+ }.to_json)
48
+ .to_return(status: status, body: body)
49
+ end
50
+
51
+ let(:predicted_outputs) do
52
+ subject.predict_outputs(model, input)
53
+ end
54
+
55
+ let(:model) do
56
+ build(:model, id: 'blah')
57
+ end
58
+
59
+ let(:input) do
60
+ Eclaircir::Input.new(
61
+ data: Eclaircir::Data.new(
62
+ image: Eclaircir::Media.new(
63
+ url: 'http://example.com/lol.jpg')))
64
+ end
65
+
66
+ context 'when the status code is 2xx' do
67
+ let(:status) do
68
+ 201
69
+ end
70
+
71
+ let(:body) do
72
+ load_fixture('predict_outputs/success.json')
73
+ end
74
+
75
+ before do
76
+ allow(Eclaircir::Response)
77
+ .to receive(:parse)
78
+ .with(JSON.parse(body))
79
+ .and_return(fake_response)
80
+
81
+ allow(Eclaircir::Client::StatusValidator)
82
+ .to receive(:new)
83
+ .with(fake_response)
84
+ .and_return(status_validator)
85
+ end
86
+
87
+ let(:fake_response) do
88
+ instance_double(Eclaircir::Response)
89
+ end
90
+
91
+ let(:status_validator) do
92
+ instance_double(Eclaircir::Client::StatusValidator,
93
+ validate!: true)
94
+ end
95
+
96
+ it 'returns a parsed response' do
97
+ expect(predicted_outputs).to be fake_response
98
+ end
99
+
100
+ it 'delegates the response to the status validator' do
101
+ expect(status_validator).to receive(:validate!)
102
+
103
+ predicted_outputs
104
+ end
105
+ end
106
+
107
+ context 'when the status code is not 2xx' do
108
+ let(:status) do
109
+ 400
110
+ end
111
+
112
+ let(:body) do
113
+ load_fixture('predict_outputs/invalid_request.json')
114
+ end
115
+
116
+ it 'raises a Eclaircir::APIError with the status message' do
117
+ expect do
118
+ predicted_outputs
119
+ end.to raise_error(Eclaircir::APIError, /Invalid request/)
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eclaircir::Configuration do
4
+ subject do
5
+ described_class.new(params)
6
+ end
7
+
8
+ let(:params) do
9
+ {
10
+ env: env,
11
+ api_key: api_key,
12
+ }
13
+ end
14
+
15
+ let(:env) do
16
+ {}
17
+ end
18
+
19
+ let(:api_key) do
20
+ 'xyzzy'
21
+ end
22
+
23
+ describe '#api_key' do
24
+ context 'when the api_key is provided explicitely' do
25
+ it 'returns provided api_key' do
26
+ expect(subject.api_key).to eq 'xyzzy'
27
+ end
28
+ end
29
+
30
+ context 'when the api_key is not provided explicitely' do
31
+ let(:api_key) do
32
+ nil
33
+ end
34
+
35
+ context 'when the CLARIFIER_API_KEY env var is provided' do
36
+ let(:env) do
37
+ {
38
+ 'CLARIFIER_API_KEY' => 'xxx'
39
+ }
40
+ end
41
+
42
+ it 'returns the CLARIFIER_API_KEY env var value' do
43
+ expect(subject.api_key).to eq 'xxx'
44
+ end
45
+ end
46
+
47
+ context 'when the CLARIFIER_API_KEY env var is not provided' do
48
+ its(:api_key) { is_expected.to be_nil }
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '#api_key=' do
54
+ it 'changes the api_key' do
55
+ expect { subject.api_key = 'yoloswag' }.to change { subject.api_key }
56
+ end
57
+
58
+ it 'sets the right value' do
59
+ subject.api_key = 'yoloswag'
60
+
61
+ expect(subject.api_key).to eq 'yoloswag'
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eclaircir do
4
+ describe '.configuration' do
5
+ it 'returns a new configuration' do
6
+ expect(described_class.configuration).to be_a Eclaircir::Configuration
7
+ end
8
+ end
9
+
10
+ describe '.configure' do
11
+ before do
12
+ allow(described_class)
13
+ .to receive(:configuration)
14
+ .and_return(fake_configuration)
15
+ end
16
+
17
+ let(:fake_configuration) do
18
+ instance_double(Eclaircir::Configuration)
19
+ end
20
+
21
+ it 'yields the configuration' do
22
+ expect do |b|
23
+ described_class.configure(&b)
24
+ end.to yield_with_args(fake_configuration)
25
+ end
26
+ end
27
+
28
+ describe '.new_client' do
29
+ before do
30
+ allow(described_class)
31
+ .to receive(:configuration)
32
+ .and_return(fake_configuration)
33
+ end
34
+
35
+ let(:fake_configuration) do
36
+ instance_double(Eclaircir::Configuration,
37
+ api_key: 'xxx')
38
+ end
39
+
40
+ before do
41
+ expect(Eclaircir::Client)
42
+ .to receive(:new)
43
+ .with('xxx')
44
+ .and_return(fake_client)
45
+ end
46
+
47
+ let(:fake_client) do
48
+ instance_double(Eclaircir::Client)
49
+ end
50
+
51
+ it 'builds and returns the client correctly' do
52
+ expect(described_class.new_client).to be fake_client
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,7 @@
1
+ {
2
+ "status": {
3
+ "code": 11102,
4
+ "description": "Invalid request",
5
+ "details": "Malformed or invalid request"
6
+ }
7
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "status": {
3
+ "code": 10000,
4
+ "description": "Ok"
5
+ },
6
+ "outputs": [
7
+ {
8
+ "id": "ea68cac87c304b28a8046557062f34a0",
9
+ "status": {
10
+ "code": 10000,
11
+ "description": "Ok"
12
+ },
13
+ "created_at": "2016-11-22T16:50:25Z",
14
+ "model": {
15
+ "name": "general-v1.3",
16
+ "id": "aaa03c23b3724a16a56b629203edc62c",
17
+ "created_at": "2016-03-09T17:11:39Z",
18
+ "app_id": null,
19
+ "output_info": {
20
+ "message": "Show output_info with: GET /models/{model_id}/output_info",
21
+ "type": "concept"
22
+ },
23
+ "model_version": {
24
+ "id": "aa9ca48295b37401f8af92ad1af0d91d",
25
+ "created_at": "2016-07-13T01:19:12Z",
26
+ "status": {
27
+ "code": 21100,
28
+ "description": "Model trained successfully"
29
+ }
30
+ }
31
+ },
32
+ "input": {
33
+ "id": "ea68cac87c304b28a8046557062f34a0",
34
+ "data": {
35
+ "image": {
36
+ "url": "https://samples.clarifai.com/metro-north.jpg"
37
+ }
38
+ }
39
+ },
40
+ "data": {
41
+ "concepts": [
42
+ {
43
+ "id": "ai_HLmqFqBf",
44
+ "name": "train",
45
+ "app_id": null,
46
+ "value": 0.9989112
47
+ },
48
+ {
49
+ "id": "ai_fvlBqXZR",
50
+ "name": "railway",
51
+ "app_id": null,
52
+ "value": 0.9975532
53
+ }
54
+ ]
55
+ }
56
+ }
57
+ ]
58
+ }
@@ -0,0 +1,8 @@
1
+ FactoryBot.define do
2
+ factory :concept, class: Eclaircir::Concept do
3
+ id { Faker::Base.regexify(%r/ai_[A-z0-9]{8}/) }
4
+ name { Faker::Food.ingredient }
5
+ value { rand(0.4..1.0).round(7) }
6
+ initialize_with { Eclaircir::Concept.new(attributes) }
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ FactoryBot.define do
2
+ factory :data, class: Eclaircir::Data do
3
+ trait :image do
4
+ image { build(:media) }
5
+ end
6
+
7
+ trait :with_concepts do
8
+ concepts { build_list(:concept, 3) }
9
+ end
10
+
11
+ initialize_with { Eclaircir::Data.new(attributes) }
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :input, class: Eclaircir::Input do
3
+ id { Faker::Base.regexify(%r/[a-f0-9]{32}/) }
4
+ data { build(:data, :image) }
5
+ initialize_with { Eclaircir::Input.new(attributes) }
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :media, class: Eclaircir::Media do
3
+ url { Faker::Internet.url }
4
+ initialize_with { Eclaircir::Media.new(attributes) }
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ FactoryBot.define do
2
+ factory :model, class: Eclaircir::Model do
3
+ id { Faker::Base.regexify(%r/[a-f0-9]{32}/) }
4
+ name { Faker::Food.ingredient }
5
+ created_at { DateTime.now }
6
+ app_id nil
7
+ initialize_with { Eclaircir::Model.new(attributes) }
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :response, class: Eclaircir::Response do
3
+ status { build(:status) }
4
+ outputs { build_list(:output, 1) }
5
+ initialize_with { Eclaircir::Response.new(attributes) }
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :status, class: Eclaircir::Status do
3
+ code { rand(10_000..20_000) }
4
+ description { Faker::Lorem.sentence }
5
+ initialize_with { Eclaircir::Status.new(attributes) }
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+
5
+ require 'dotenv'
6
+ Dotenv.load
7
+
8
+ require 'simplecov'
9
+ require 'coveralls'
10
+
11
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
12
+ SimpleCov::Formatter::HTMLFormatter,
13
+ Coveralls::SimpleCov::Formatter
14
+ ]
15
+
16
+ SimpleCov.start do
17
+ add_filter ENV['GEM_HOME'] if ENV.fetch('GEM_HOME', '').include?('bundle')
18
+ add_filter 'spec/support'
19
+ add_filter '.bundle'
20
+ add_group 'Library', 'lib'
21
+ add_group 'Specs', 'spec'
22
+ end
23
+
24
+ require 'eclaircir'
25
+ require 'pp'
26
+ require 'byebug'
27
+ require 'rspec'
28
+ require 'rspec/its'
29
+ require 'webmock/rspec'
30
+ require 'factory_bot'
31
+ require 'faker'
32
+
33
+ Dir["./spec/factories/**/*.rb"].sort.each do |factory|
34
+ require factory
35
+ end
36
+
37
+ RSpec.configure do |config|
38
+ config.expect_with :rspec do |c|
39
+ c.syntax = :expect
40
+ end
41
+
42
+ config.include FactoryBot::Syntax::Methods
43
+ end
44
+
45
+ def load_fixture(fixture_path)
46
+ complete_path = File.join(
47
+ File.dirname(__FILE__),
48
+ 'etc',
49
+ 'fixtures',
50
+ fixture_path)
51
+
52
+ File.read(complete_path)
53
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eclaircir
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Karim Bogtob
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.14.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: virtus
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ description: Ruby Clarifai API wrapper that aims to be complete, tested and covered
42
+ email: kabogtob@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - ".gitignore"
48
+ - ".travis.yml"
49
+ - Gemfile
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - TODO.md
54
+ - bin/console
55
+ - bin/test.rb
56
+ - eclaircir.gemspec
57
+ - lib/eclaircir.rb
58
+ - lib/eclaircir/api_models.rb
59
+ - lib/eclaircir/api_models/attributes.rb
60
+ - lib/eclaircir/api_models/attributes/nullable_date_time.rb
61
+ - lib/eclaircir/api_models/base_model.rb
62
+ - lib/eclaircir/api_models/concept.rb
63
+ - lib/eclaircir/api_models/data.rb
64
+ - lib/eclaircir/api_models/input.rb
65
+ - lib/eclaircir/api_models/media.rb
66
+ - lib/eclaircir/api_models/model.rb
67
+ - lib/eclaircir/api_models/output.rb
68
+ - lib/eclaircir/api_models/response.rb
69
+ - lib/eclaircir/api_models/status.rb
70
+ - lib/eclaircir/client.rb
71
+ - lib/eclaircir/client/status_validator.rb
72
+ - lib/eclaircir/configuration.rb
73
+ - lib/eclaircir/constants.rb
74
+ - lib/eclaircir/error.rb
75
+ - lib/eclaircir/version.rb
76
+ - spec/eclaircir/api_models/concept_spec.rb
77
+ - spec/eclaircir/api_models/data_spec.rb
78
+ - spec/eclaircir/api_models/input_spec.rb
79
+ - spec/eclaircir/api_models/media_spec.rb
80
+ - spec/eclaircir/api_models/model_spec.rb
81
+ - spec/eclaircir/api_models/output_spec.rb
82
+ - spec/eclaircir/api_models/response_spec.rb
83
+ - spec/eclaircir/api_models/status_spec.rb
84
+ - spec/eclaircir/client/status_validator_spec.rb
85
+ - spec/eclaircir/client_spec.rb
86
+ - spec/eclaircir/configuration_spec.rb
87
+ - spec/eclaircir_spec.rb
88
+ - spec/etc/fixtures/predict_outputs/invalid_request.json
89
+ - spec/etc/fixtures/predict_outputs/success.json
90
+ - spec/factories/concept.rb
91
+ - spec/factories/data.rb
92
+ - spec/factories/input.rb
93
+ - spec/factories/media.rb
94
+ - spec/factories/model.rb
95
+ - spec/factories/response.rb
96
+ - spec/factories/status.rb
97
+ - spec/spec_helper.rb
98
+ homepage: https://github.com/kbogtob/eclaircir
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.4.5.3
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Clarifai APIv2 Client
122
+ test_files: []