deepstack 1.0.0 → 1.1.1
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.
- checksums.yaml +4 -4
- data/lib/{deepstack → deep_stack}/custom.rb +2 -3
- data/lib/deep_stack/deep_stack.rb +110 -0
- data/lib/{deepstack → deep_stack}/detection.rb +2 -3
- data/lib/{deepstack → deep_stack}/face.rb +5 -9
- data/lib/{deepstack → deep_stack}/scene.rb +1 -1
- data/lib/{deepstack → deep_stack}/version.rb +1 -1
- data/lib/deepstack.rb +1 -107
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b13995c10316b274d2b292316076cf96c96f945ac7304835ca5dc25fd873eaeb
|
4
|
+
data.tar.gz: 585b76987b8d1db73e05e78b777bf6fcd716e38f40c7c1e9b9150a7c833d84ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41f4207559f4976ebf42864186661a538f6d45978958ec22a951c2e1ddac17685c67a2050de1064fe070c10f39fd9d3b954807be40bd04b14be5cf4e24221e5c
|
7
|
+
data.tar.gz: ceac07d54df401e92619d2c48e493ced1e6b2543a71bfe8dc79ccb5b1be53e34aa96d38eaf395b6bfbd919739c7476a886fac54fdb1fb9bf945a60cce6c0bba4
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/deepstack.rb
CHANGED
@@ -1,109 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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.
|
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-
|
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.
|
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: []
|