deepstack 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc0409e409422c065962aa065244f20658c764c904462935936b05c1950e771a
4
- data.tar.gz: 074e0f2e9f309f72aaa402ef5e1b3bd469da172bbb60679a2a59b218f4a2a7ac
3
+ metadata.gz: b13995c10316b274d2b292316076cf96c96f945ac7304835ca5dc25fd873eaeb
4
+ data.tar.gz: 585b76987b8d1db73e05e78b777bf6fcd716e38f40c7c1e9b9150a7c833d84ec
5
5
  SHA512:
6
- metadata.gz: '0923fd828175f78a7bc90a40623c6ed7ec8ce8681876ab340697309c9557bdbf2551f10567b4df4dd861c2121e2cd37c62b47f06803e08f8cc0b1a5739e68d89'
7
- data.tar.gz: b9be9f1439d69f939f2dbf66842264a750e47d8cba455ff528b7879f115f3510e45690f8ff7a804e1b23428a5313c44c147049b3bcc269db31b4887f7c03b34e
6
+ metadata.gz: 41f4207559f4976ebf42864186661a538f6d45978958ec22a951c2e1ddac17685c67a2050de1064fe070c10f39fd9d3b954807be40bd04b14be5cf4e24221e5c
7
+ data.tar.gz: ceac07d54df401e92619d2c48e493ced1e6b2543a71bfe8dc79ccb5b1be53e34aa96d38eaf395b6bfbd919739c7476a886fac54fdb1fb9bf945a60cce6c0bba4
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DeepStackModule
3
+ class DeepStack
4
4
  # Custom Model
5
5
  module Custom
6
6
  #
@@ -36,8 +36,7 @@ module DeepStackModule
36
36
  #
37
37
  def custom_inference(model, image, **options)
38
38
  target = "vision/custom/#{model}"
39
- api_post(target, image, options)
40
- predictions
39
+ api_post(target, image, options)&.dig('predictions')
41
40
  end
42
41
  end
43
42
  end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pp'
4
+ require 'net/http'
5
+ require 'json'
6
+ require_relative 'face'
7
+ require_relative 'detection'
8
+ require_relative 'scene'
9
+ require_relative 'custom'
10
+ require_relative 'version'
11
+
12
+ # DeepStack API
13
+ class DeepStack
14
+ include DeepStack::Face
15
+ include DeepStack::Detection
16
+ include DeepStack::Scene
17
+ include DeepStack::Custom
18
+
19
+ # Create a deepstack object connected to the given URL
20
+ def initialize(base_url)
21
+ @base_url = base_url
22
+ @http_mutex = Mutex.new
23
+ end
24
+
25
+ #
26
+ # Make a POST request to DeepStack path target
27
+ #
28
+ # @param [String] path to the DeepStack API URL
29
+ # @param [Array] images zero or more images to post
30
+ # @param [Hash] args additional named fields to post
31
+ #
32
+ # @return [Hash] if successful, the json data returned by DeepStack, nil otherwise
33
+ #
34
+ def api_post(path, *images, **args)
35
+ uri = build_uri(path)
36
+
37
+ result = nil
38
+ 10.times do
39
+ result = images ? post_files(uri, images.flatten, **args) : post(uri, args)
40
+ break unless result.is_a?(Net::HTTPRedirection)
41
+
42
+ uri.path = result['location']
43
+ end
44
+ raise Net::HTTPClientException, 'Too many redirections' if result.is_a?(Net::HTTPRedirection)
45
+
46
+ process_result(result)
47
+ end
48
+
49
+ #
50
+ # Close the HTTP connection to DeepStack server
51
+ #
52
+ def close
53
+ @http_mutex.synchronize do
54
+ @http&.finish
55
+ @http = nil
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def build_uri(path)
62
+ URI.join(@base_url, '/v1/', path)
63
+ end
64
+
65
+ def post(uri, **args)
66
+ Net::HTTP.post_form(uri, args)
67
+ end
68
+
69
+ def post_files(uri, *images, **args)
70
+ form_data = combine_images_and_args(images.flatten, **args)
71
+ req = Net::HTTP::Post.new(uri)
72
+ req.set_form(form_data, 'multipart/form-data')
73
+ @http_mutex.synchronize do
74
+ @http ||= Net::HTTP.start(uri.hostname, uri.port)
75
+ @http.request(req)
76
+ end
77
+ end
78
+
79
+ def combine_images_and_args(*images, **args)
80
+ stringify_keys(args).concat(image_form_data(images.flatten))
81
+ end
82
+
83
+ def stringify_keys(hash)
84
+ hash.map { |k, v| [k.to_s, v] }
85
+ end
86
+
87
+ #
88
+ # Return an array of image entries for form data.
89
+ # The field name is 'image' for a single image
90
+ # For multiple images, the field names will be 'image1', 'image2', ...
91
+ #
92
+ # @param [Array<Object>] images an array of raw image data or a File object
93
+ #
94
+ # @return [Array] the image entries for set_form
95
+ #
96
+ def image_form_data(*images)
97
+ images = images.flatten
98
+ return [image_entry('image', images.first)] if images.length == 1
99
+
100
+ images.map.with_index(1) { |image, i| image_entry("image#{i}", image) }
101
+ end
102
+
103
+ def image_entry(name, image)
104
+ [name, image].tap { |result| result << { filename: "#{name}.jpg" } unless image.instance_of? File }
105
+ end
106
+
107
+ def process_result(result)
108
+ result.is_a?(Net::HTTPSuccess) ? JSON.parse(result.body) : nil
109
+ end
110
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DeepStackModule
3
+ class DeepStack
4
4
  # APIs related to object detection
5
5
  module Detection
6
6
  #
@@ -13,8 +13,7 @@ module DeepStackModule
13
13
  #
14
14
  def detect_objects(image, **options)
15
15
  target = 'vision/detection'
16
- api_post(target, image, **options)
17
- predictions
16
+ api_post(target, image, **options)&.dig('predictions')
18
17
  end
19
18
  end
20
19
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DeepStackModule
3
+ class DeepStack
4
4
  # APIs related to face recognition
5
5
  module Face
6
6
  #
@@ -15,8 +15,7 @@ module DeepStackModule
15
15
  #
16
16
  def recognize_faces(image, **options)
17
17
  target = 'vision/face/recognize'
18
- api_post(target, image, **options)
19
- predictions
18
+ api_post(target, image, **options)&.dig('predictions')
20
19
  end
21
20
 
22
21
  #
@@ -29,8 +28,7 @@ module DeepStackModule
29
28
  #
30
29
  def detect_faces(image, **options)
31
30
  target = 'vision/face/' # the URL ends with a slash
32
- api_post(target, image, **options)
33
- predictions
31
+ api_post(target, image, **options)&.dig('predictions')
34
32
  end
35
33
 
36
34
  #
@@ -64,8 +62,7 @@ module DeepStackModule
64
62
  #
65
63
  def delete_face(userid)
66
64
  target = 'vision/face/delete'
67
- api_post(target, userid: userid)
68
- success?
65
+ api_post(target, userid: userid)&.dig('success') == true
69
66
  end
70
67
 
71
68
  #
@@ -78,8 +75,7 @@ module DeepStackModule
78
75
  #
79
76
  def register_face(userid, *images)
80
77
  target = 'vision/face/register'
81
- api_post(target, images, userid: userid)
82
- success?
78
+ api_post(target, images, userid: userid)&.dig('success') == true
83
79
  end
84
80
  end
85
81
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DeepStackModule
3
+ class DeepStack
4
4
  # Scene Recognition
5
5
  module Scene
6
6
  #
@@ -5,5 +5,5 @@
5
5
  #
6
6
  class DeepStack
7
7
  # @return [String] Version of DeepStack helper libraries
8
- VERSION = '1.0.0'
8
+ VERSION = '1.1.1'
9
9
  end
data/lib/deepstack.rb CHANGED
@@ -1,109 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pp'
4
- require 'net/http'
5
- require 'json'
6
- require_relative 'deepstack/face'
7
- require_relative 'deepstack/detection'
8
- require_relative 'deepstack/scene'
9
- require_relative 'deepstack/custom'
10
- require_relative 'deepstack/version'
11
-
12
- # DeepStack API
13
- class DeepStack
14
- include DeepStackModule::Face
15
- include DeepStackModule::Detection
16
- include DeepStackModule::Scene
17
- include DeepStackModule::Custom
18
-
19
- attr_reader :duration, :predictions, :success
20
-
21
- # Create a deepstack object connected to the given URL
22
- def initialize(base_url)
23
- @base_url = base_url
24
- end
25
-
26
- #
27
- # The result of the last call
28
- #
29
- # @return [Boolean] true if the last call was successful
30
- #
31
- def success?
32
- @success == true
33
- end
34
-
35
- #
36
- # Make a POST request to DeepStack path target
37
- #
38
- # @param [String] path to the DeepStack API URL
39
- # @param [Array] images zero or more images to post
40
- # @param [Hash] args additional named fields to post
41
- #
42
- # @return [Hash] if successful, the json data returned by DeepStack, nil otherwise
43
- #
44
- def api_post(path, *images, **args)
45
- uri = build_uri(path)
46
-
47
- result = nil
48
- 10.times do
49
- result = images ? post_files(uri, images.flatten, **args) : post(uri, args)
50
- break unless result.is_a?(Net::HTTPRedirection)
51
-
52
- uri.path = result['location']
53
- end
54
- raise Net::HTTPClientException, 'Too many redirections' if result.is_a?(Net::HTTPRedirection)
55
-
56
- process_result(result)
57
- end
58
-
59
- private
60
-
61
- def build_uri(path)
62
- URI.join(@base_url, '/v1/', path)
63
- end
64
-
65
- def post(uri, **args)
66
- Net::HTTP.post_form(uri, args)
67
- end
68
-
69
- def post_files(uri, *images, **args)
70
- form_data = combine_images_and_args(images.flatten, **args)
71
- req = Net::HTTP::Post.new(uri)
72
- req.set_form(form_data, 'multipart/form-data')
73
- Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) }
74
- end
75
-
76
- def combine_images_and_args(*images, **args)
77
- stringify_keys(args).concat(image_form_data(images.flatten))
78
- end
79
-
80
- def stringify_keys(hash)
81
- hash.map { |k, v| [k.to_s, v] }
82
- end
83
-
84
- #
85
- # Return an array of image entries for form data.
86
- # The field name is 'image' for a single image
87
- # For multiple images, the field names will be 'image1', 'image2', ...
88
- #
89
- # @param [Array<Object>] images an array of raw image data or a File object
90
- #
91
- # @return [Array] the image entries for set_form
92
- #
93
- def image_form_data(*images)
94
- images = images.flatten
95
- return [image_entry('image', images.first)] if images.length == 1
96
-
97
- images.map.with_index(1) { |image, i| image_entry("image#{i}", image) }
98
- end
99
-
100
- def image_entry(name, image)
101
- [name, image].tap { |result| result << { filename: "#{name}.jpg" } unless image.instance_of? File }
102
- end
103
-
104
- def process_result(result)
105
- @result = result.is_a?(Net::HTTPSuccess) ? JSON.parse(result.body) : nil
106
- %w[success duration predictions].each { |attrib| instance_variable_set("@#{attrib}", @result&.dig(attrib)) }
107
- @result
108
- end
109
- end
3
+ require_relative 'deep_stack/deep_stack'
metadata CHANGED
@@ -1,36 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deepstack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Tanagra
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-09 00:00:00.000000000 Z
11
+ date: 2022-05-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description:
13
+ description:
14
14
  email:
15
15
  - jcode@tanagra.id.au
16
16
  executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - lib/deep_stack/custom.rb
21
+ - lib/deep_stack/deep_stack.rb
22
+ - lib/deep_stack/detection.rb
23
+ - lib/deep_stack/face.rb
24
+ - lib/deep_stack/scene.rb
25
+ - lib/deep_stack/version.rb
20
26
  - lib/deepstack.rb
21
- - lib/deepstack/custom.rb
22
- - lib/deepstack/detection.rb
23
- - lib/deepstack/face.rb
24
- - lib/deepstack/scene.rb
25
- - lib/deepstack/version.rb
26
27
  homepage: https://github.com/jimtng/deepstack-ruby
27
28
  licenses:
28
29
  - EPL-2.0
29
30
  metadata:
30
31
  homepage_uri: https://github.com/jimtng/deepstack-ruby
31
32
  source_code_uri: https://github.com/jimtng/deepstack-ruby
33
+ documentation_uri: https://rubydoc.info/gems/deepstack
32
34
  changelog_uri: https://github.com/jimtng/deepstack-ruby/blob/main/CHANGELOG.md
33
- post_install_message:
35
+ post_install_message:
34
36
  rdoc_options: []
35
37
  require_paths:
36
38
  - lib
@@ -45,8 +47,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
47
  - !ruby/object:Gem::Version
46
48
  version: '0'
47
49
  requirements: []
48
- rubygems_version: 3.3.7
49
- signing_key:
50
+ rubygems_version: 3.0.3.1
51
+ signing_key:
50
52
  specification_version: 4
51
53
  summary: A Ruby wrapper for DeepStack API
52
54
  test_files: []