stretchy-model 0.6.6 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/docs/_sidebar.md +2 -1
  3. data/docs/examples/_sidebar.md +1 -1
  4. data/docs/examples/neural_search_with_llm.md +381 -0
  5. data/docs/guides/_sidebar.md +2 -1
  6. data/lib/elasticsearch/api/actions/connector/check_in.rb +64 -0
  7. data/lib/elasticsearch/api/actions/connector/delete.rb +64 -0
  8. data/lib/elasticsearch/api/actions/connector/get.rb +64 -0
  9. data/lib/elasticsearch/api/actions/connector/last_sync.rb +66 -0
  10. data/lib/elasticsearch/api/actions/connector/list.rb +60 -0
  11. data/lib/elasticsearch/api/actions/connector/post.rb +57 -0
  12. data/lib/elasticsearch/api/actions/connector/put.rb +66 -0
  13. data/lib/elasticsearch/api/actions/connector/update_api_key_id.rb +66 -0
  14. data/lib/elasticsearch/api/actions/connector/update_configuration.rb +66 -0
  15. data/lib/elasticsearch/api/actions/connector/update_error.rb +66 -0
  16. data/lib/elasticsearch/api/actions/connector/update_filtering.rb +66 -0
  17. data/lib/elasticsearch/api/actions/connector/update_index_name.rb +66 -0
  18. data/lib/elasticsearch/api/actions/connector/update_name.rb +66 -0
  19. data/lib/elasticsearch/api/actions/connector/update_native.rb +66 -0
  20. data/lib/elasticsearch/api/actions/connector/update_pipeline.rb +66 -0
  21. data/lib/elasticsearch/api/actions/connector/update_scheduling.rb +66 -0
  22. data/lib/elasticsearch/api/actions/connector/update_service_type.rb +66 -0
  23. data/lib/elasticsearch/api/actions/connector/update_status.rb +66 -0
  24. data/lib/elasticsearch/api/namespace/connector.rb +36 -0
  25. data/lib/opensearch/api/actions/machine_learning/connector/delete.rb +42 -0
  26. data/lib/opensearch/api/actions/machine_learning/connector/get.rb +42 -0
  27. data/lib/opensearch/api/actions/machine_learning/connector/list.rb +38 -0
  28. data/lib/opensearch/api/actions/machine_learning/connector/post.rb +35 -0
  29. data/lib/opensearch/api/actions/machine_learning/connector/put.rb +44 -0
  30. data/lib/opensearch/api/actions/machine_learning/models/predict.rb +32 -0
  31. data/lib/opensearch/api/namespace/connector.rb +19 -0
  32. data/lib/stretchy/machine_learning/connector.rb +130 -0
  33. data/lib/stretchy/machine_learning/errors.rb +25 -0
  34. data/lib/stretchy/machine_learning/model.rb +162 -109
  35. data/lib/stretchy/machine_learning/registry.rb +19 -0
  36. data/lib/stretchy/open_search_compatibility.rb +2 -0
  37. data/lib/stretchy/pipelines/processor.rb +2 -0
  38. data/lib/stretchy/rails/railtie.rb +11 -0
  39. data/lib/stretchy/rails/tasks/connector/create.rake +32 -0
  40. data/lib/stretchy/rails/tasks/connector/delete.rake +27 -0
  41. data/lib/stretchy/rails/tasks/connector/status.rake +31 -0
  42. data/lib/stretchy/rails/tasks/connector/update.rake +32 -0
  43. data/lib/stretchy/rails/tasks/index/create.rake +28 -0
  44. data/lib/stretchy/rails/tasks/index/delete.rake +27 -0
  45. data/lib/stretchy/rails/tasks/index/status.rake +23 -0
  46. data/lib/stretchy/rails/tasks/ml/delete.rake +25 -0
  47. data/lib/stretchy/rails/tasks/ml/deploy.rake +78 -0
  48. data/lib/stretchy/rails/tasks/ml/status.rake +31 -0
  49. data/lib/stretchy/rails/tasks/pipeline/create.rake +27 -0
  50. data/lib/stretchy/rails/tasks/pipeline/delete.rake +26 -0
  51. data/lib/stretchy/rails/tasks/pipeline/status.rake +25 -0
  52. data/lib/stretchy/rails/tasks/status.rake +15 -0
  53. data/lib/stretchy/rails/tasks/stretchy.rake +42 -0
  54. data/lib/stretchy/version.rb +1 -1
  55. data/lib/stretchy.rb +7 -0
  56. metadata +62 -3
  57. data/docs/examples/semantic_search_with_llm.md +0 -83
@@ -0,0 +1,130 @@
1
+ module Stretchy
2
+ module MachineLearning
3
+ class Connector
4
+
5
+ cattr_reader :client do
6
+ Stretchy.configuration.client.connector
7
+ end
8
+
9
+ class Settings
10
+ def initialize(valid_keys = [])
11
+ @valid_keys = valid_keys
12
+ @settings = {}
13
+ end
14
+
15
+ def as_json(*)
16
+ @settings.as_json
17
+ end
18
+
19
+ def method_missing(method, *args, &block)
20
+ if block_given?
21
+ @settings[method] = self.class.new.tap { |obj| obj.instance_eval(&block) }
22
+ elsif args.empty?
23
+ value = @settings[method]
24
+ value.is_a?(Hash) ? Elasticsearch::Model::HashWrapper[value] : value
25
+ elsif args.length == 1 && @valid_keys.empty? || @valid_keys.include?(method)
26
+ @settings[method] = args.first
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ def respond_to_missing?(method, include_private = false)
33
+ @settings.key?(method) || super
34
+ end
35
+ end
36
+
37
+ class << self
38
+ include Errors
39
+
40
+ METHODS = [
41
+ :description,
42
+ :version,
43
+ :protocol,
44
+ :credentials,
45
+ :parameters,
46
+ :actions,
47
+ :name
48
+ ].freeze
49
+
50
+ def settings
51
+ @settings ||= Settings.new(METHODS)
52
+ end
53
+
54
+ delegate *METHODS, to: :settings
55
+
56
+ def name(name = nil)
57
+ settings.name(name) if name
58
+ settings.name || to_s.split('::').last.underscore
59
+ end
60
+
61
+ def registry
62
+ @registery ||= Stretchy::MachineLearning::Registry.register(class_name: self.name, class_type: 'connector')
63
+ end
64
+
65
+ def id
66
+ @id || registry.model_id
67
+ end
68
+
69
+ concerning :API do
70
+ def create!
71
+ response = client.post(body: self.to_hash.as_json).with_indifferent_access
72
+ registry.update(model_id: response.dig(:connector_id))
73
+ @id = response.dig(:connector_id)
74
+ end
75
+
76
+ def delete!
77
+ begin
78
+ response = client.delete(connector_id: self.id).with_indifferent_access
79
+ rescue "#{Stretchy.configuration.search_backend_const}::Transport::Transport::Errors::NotFound".constantize => e
80
+ raise Stretchy::MachineLearning::Errors::ConnectorMissingError
81
+
82
+ ensure
83
+ if response.dig(:result) == 'deleted'
84
+ registry.delete
85
+ @registry = nil
86
+ @id = nil
87
+ end
88
+ response
89
+ end
90
+ end
91
+
92
+ def update!
93
+ client.put(connector_id: self.id, body: self.to_hash)
94
+ end
95
+
96
+ def find(id = nil)
97
+ begin
98
+ id = self.id if id.nil?
99
+ client.get(connector_id: id)
100
+ rescue ArgumentError => e
101
+ raise Stretchy::MachineLearning::Errors::ConnectorMissingError
102
+ rescue "#{Stretchy.configuration.search_backend_const}::Transport::Transport::Errors::NotFound".constantize => e
103
+ # raise Stretchy::MachineLearning::Errors::ConnectorMissingError
104
+ end
105
+ end
106
+
107
+ def exists?
108
+ self.find(self.id).present?
109
+ end
110
+
111
+ def to_hash
112
+ acts = self.actions.as_json
113
+ acts[:request_body] = actions[:request_body]
114
+ {
115
+ name: self.name,
116
+ description: self.description,
117
+ version: self.version,
118
+ protocol: self.protocol,
119
+ credential: self.credentials,
120
+ parameters: self.parameters,
121
+ actions: [acts]
122
+ }.compact
123
+
124
+ end
125
+ end
126
+
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,25 @@
1
+ module Stretchy::MachineLearning::Errors
2
+ class ModelNotDeployedError < StandardError
3
+ def initialize(msg="Model is not deployed. Please run `rake stretchy:ml:deploy` to deploy it.")
4
+ super
5
+ end
6
+ end
7
+
8
+ class ModelNotRegisteredError < StandardError
9
+ def initialize(msg="Model is not registered. Please run `rake stretchy:ml:register` to register it.")
10
+ super
11
+ end
12
+ end
13
+
14
+ class ConnectorMissingError < StandardError
15
+ def initialize(msg="Connector is missing. Please run `rake stretchy:ml:connector:create` to create it.")
16
+ super
17
+ end
18
+ end
19
+
20
+ class AgentNotRegisteredError < StandardError
21
+ def initialize(msg="Agent is not registered. Please run `rake stretchy:ml:agent:create` to create it.")
22
+ super
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,9 @@
1
+ require 'stretchy/machine_learning/errors'
2
+
1
3
  module Stretchy
2
4
  module MachineLearning
3
5
  class Model
6
+
4
7
  PRETRAINED_MODELS = {
5
8
  :neural_sparse => {
6
9
  :encoding => 'amazon/neural-sparse/opensearch-neural-sparse-encoding-v1',
@@ -31,7 +34,165 @@ module Stretchy
31
34
  end
32
35
 
33
36
  class << self
34
- attr_accessor :model, :group_id
37
+ include Errors
38
+ # delegate :find, :status, :deployed?, :registered?, :task_id, :deploy_id, :model_id, :register, :deploy, :undeploy, :delete, to: :model
39
+
40
+ METHODS = [
41
+ :model,
42
+ :group_id,
43
+ :version,
44
+ :description,
45
+ :model_format,
46
+ :enabled,
47
+ :connector_id,
48
+ :connector,
49
+ :function_name,
50
+ :model_config,
51
+ :model_content_hash_value,
52
+ :url
53
+ ]
54
+
55
+ def settings
56
+ @settings ||= {}
57
+ end
58
+
59
+ METHODS.each do |method|
60
+ define_method(method) do |args = nil|
61
+ return settings[method] unless args.present?
62
+ settings[method] = args
63
+
64
+ if method == :connector
65
+ connector_class = "#{args.to_s.camelize}".constantize
66
+ settings[:connector] = connector_class
67
+ # raise ConnectorMissingError if connector_class.id.nil?
68
+ settings[:connector_id] = connector_class.id
69
+ end
70
+
71
+ if method == :model
72
+ settings[:model] = model_lookup(args)
73
+ end
74
+ end
75
+ end
76
+
77
+ def model_id
78
+ @model_id || registry.model_id
79
+ end
80
+
81
+ def task_id
82
+ @task_id || registry.register_task_id
83
+ end
84
+
85
+ def deploy_id
86
+ @deploy_id || registry.deploy_task_id
87
+ end
88
+
89
+
90
+ def registry
91
+ @registry ||= Stretchy::MachineLearning::Registry.register(class_name: self.name, class_type: 'model')
92
+ end
93
+
94
+ def register
95
+ begin
96
+
97
+ response = client.register(body: self.to_hash, deploy: true)
98
+
99
+ @task_id = response['task_id']
100
+
101
+ self.registry.update(register_task_id: @task_id)
102
+
103
+ yield self if block_given?
104
+
105
+ registered?
106
+ self.registry.update(model_id: @model_id)
107
+ @model_id
108
+ rescue => e
109
+ Stretchy.logger.error "Error registering model: #{e.message}"
110
+ false
111
+ end
112
+ true
113
+ end
114
+
115
+ def registered?
116
+ return false unless task_id
117
+ response = status
118
+ @model_id = response['model_id'] if response['model_id']
119
+ response['state'] == 'COMPLETED' && @model_id.present?
120
+ end
121
+
122
+ def status
123
+ client.get_status(task_id: self.task_id)
124
+ end
125
+
126
+
127
+ def deploy
128
+ @deployed = nil
129
+
130
+ @deploy_id = client.deploy(id: self.model_id)['task_id']
131
+ self.registry.update(deploy_task_id: @deploy_id)
132
+ yield self if block_given?
133
+ @deploy_id
134
+ end
135
+
136
+ def undeploy
137
+ @deployed = nil
138
+ response = client.undeploy(id: self.model_id)
139
+ self.registry.update(deploy_task_id: nil)
140
+ yield self if block_given?
141
+ response
142
+ end
143
+
144
+ def deployed?
145
+ return @deployed if @deployed
146
+ response = client.get_model(id: self.model_id)
147
+ # raise "Model not deployed" if response['model_state'] == 'FAILED'
148
+ @deployed = response['model_state'] == 'DEPLOYED'
149
+ end
150
+
151
+ def delete
152
+ self.registry.delete
153
+ client.delete_model(id: self.model_id)
154
+ end
155
+
156
+ def find
157
+ begin
158
+ client.get_model(id: self.model_id)
159
+ rescue "#{Stretchy.configuration.search_backend_const}::Transport::Transport::Errors::InternalServerError".constantize => e
160
+ raise Stretchy::MachineLearning::Errors::ModelMissingError
161
+ end
162
+ end
163
+
164
+ def model_name(model_name = nil)
165
+ @model_name = model_name if model_name
166
+ @model_name || to_s.demodulize.underscore
167
+ end
168
+
169
+ def to_hash
170
+ {
171
+ name: self.model || self.model_name,
172
+ model_group_id: self.group_id,
173
+ version: self.version,
174
+ description: self.description,
175
+ model_format: self.model_format,
176
+ is_enabled: self.enabled?,
177
+ connector_id: self.connector.present? ? self.connector.id : nil,
178
+ function_name: self.function_name
179
+ }.compact
180
+ end
181
+
182
+ def enabled?
183
+ self.enabled
184
+ end
185
+
186
+ def wait_until_complete(max_attempts: 20, sleep_time: 4)
187
+ attempts = 0
188
+ loop do
189
+ result = yield
190
+ break if result
191
+ attempts += 1
192
+ break if attempts >= max_attempts
193
+ sleep(sleep_time)
194
+ end
195
+ end
35
196
 
36
197
  def all
37
198
  client.get_model
@@ -78,114 +239,6 @@ module Stretchy
78
239
  end
79
240
  end
80
241
 
81
- attr_accessor :model,
82
- :group_id,
83
- :version,
84
- :description,
85
- :model_format,
86
- :enabled,
87
- :connector_id,
88
- :connector,
89
- :function_name,
90
- :model_config,
91
- :model_content_hash_value,
92
- :url
93
-
94
- attr_reader :task_id, :model_id, :deploy_id
95
-
96
- def initialize(args = {})
97
- model_name = args.delete(:model)
98
- args.each do |k,v|
99
- self.send("#{k}=", v)
100
- end
101
- @model = self.class.model_lookup model_name
102
- end
103
-
104
- def register
105
- begin
106
- response = client.register(body: self.to_hash, deploy: true)
107
-
108
- @task_id = response['task_id']
109
-
110
- yield self if block_given?
111
-
112
- @model_id
113
- rescue => e
114
- Stretchy.logger.error "Error registering model: #{e.message}"
115
- false
116
- end
117
- true
118
- end
119
-
120
- def registered?
121
- response = status
122
- @model_id = response['model_id'] if response['model_id']
123
- response['state'] == 'COMPLETED' && @model_id.present?
124
- end
125
-
126
- def status
127
- client.get_status(task_id: self.task_id)
128
- end
129
-
130
- def deploy
131
- @deployed = nil
132
- @deploy_id = client.deploy(id: self.model_id)['task_id']
133
- yield self if block_given?
134
- @deploy_id
135
- end
136
-
137
- def undeploy
138
- @deployed = nil
139
- response = client.undeploy(id: self.model_id)
140
- yield self if block_given?
141
- response
142
- end
143
-
144
- def deployed?
145
- return @deployed if @deployed
146
- response = client.get_model(id: self.model_id)
147
- # raise "Model not deployed" if response['model_state'] == 'FAILED'
148
- @deployed = response['model_state'] == 'DEPLOYED'
149
- end
150
-
151
- def delete
152
- client.delete_model(id: self.model_id)
153
- end
154
-
155
- def client
156
- @@client
157
- end
158
-
159
- def find
160
- client.get_model(id: self.model_id)
161
- end
162
-
163
- def to_hash
164
- {
165
- name: self.model,
166
- model_group_id: self.group_id,
167
- version: self.version,
168
- description: self.description,
169
- model_format: self.model_format,
170
- is_enabled: self.enabled?
171
- }.compact
172
- end
173
-
174
- def enabled?
175
- self.enabled
176
- end
177
-
178
- def wait_until_complete(max_attempts: 20, sleep_time: 4)
179
- attempts = 0
180
- loop do
181
- result = yield
182
- break if result
183
- attempts += 1
184
- break if attempts >= max_attempts
185
- sleep(sleep_time)
186
- end
187
- end
188
-
189
242
 
190
243
  end
191
244
  end
@@ -0,0 +1,19 @@
1
+ module Stretchy::MachineLearning
2
+ class Registry < StretchyModel
3
+
4
+ index_name ".stretchy_ml_registry_#{Stretchy.env}"
5
+
6
+ attribute :model_id, :keyword
7
+ attribute :model_group_id, :keyword
8
+ attribute :deploy_task_id, :keyword
9
+ attribute :register_task_id, :keyword
10
+ attribute :class_name, :keyword
11
+ attribute :class_type, :keyword
12
+
13
+ def self.register(**args)
14
+ self.create_index! unless index_exists?
15
+ where(class_name: args[:class_name]).first || create(**args)
16
+ end
17
+
18
+ end
19
+ end
@@ -1,4 +1,5 @@
1
1
  require 'opensearch/api/namespace/machine_learning/model'
2
+ require 'opensearch/api/namespace/connector'
2
3
 
3
4
  module Stretchy
4
5
  module OpenSearchCompatibility
@@ -82,6 +83,7 @@ module Stretchy
82
83
  ::Elasticsearch::Persistence::Repository.send(:include, patch)
83
84
  ::Elasticsearch::Persistence::Repository.send(:include, store)
84
85
  OpenSearch::API.send(:include, OpenSearch::API::MachineLearning::Models)
86
+ OpenSearch::API.send(:include, OpenSearch::API::Connector)
85
87
 
86
88
  end
87
89
 
@@ -48,9 +48,11 @@ module Stretchy::Pipelines
48
48
  @type = type
49
49
  @description = opts[:description]
50
50
  @opts = opts
51
+ @model = opts.delete(:model)
51
52
  end
52
53
 
53
54
  def to_hash
55
+ @opts[:model_id] = @model.model_id if @model
54
56
  { type => @opts }
55
57
  end
56
58
  end
@@ -0,0 +1,11 @@
1
+ module Stretchy
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ rake_tasks do
6
+ load "#{__dir__}/tasks/stretchy.rake"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ namespace :stretchy do
2
+ namespace :connector do
3
+ desc "Create connector"
4
+ task create: :environment do
5
+ klass = ENV['MODEL']
6
+ Rails.application.eager_load!
7
+ models = klass.nil? ? Stretchy::MachineLearning::Connector.descendants : [klass.constantize]
8
+ models.each do |model|
9
+ spinner = TTY::Spinner.new("Creating Connector #{model} ".ljust(JUSTIFICATION) + ":spinner", format: :dots)
10
+ spinner.auto_spin
11
+
12
+ # if model.exists?
13
+ # spinner.stop(Rainbow("[EXISTS]").yellow)
14
+ # next
15
+ # end
16
+
17
+ begin
18
+ response = model.create!
19
+ rescue Stretchy::MachineLearning::Errors::ConnectorMissingError => e
20
+ spinner.stop(Rainbow("[FAILED]").red)
21
+ next
22
+ end
23
+ status = if response
24
+ Rainbow("[SUCCESS]").green
25
+ else
26
+ Rainbow("[FAILED]").red
27
+ end
28
+ spinner.stop(status)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ namespace :stretchy do
2
+ namespace :connector do
3
+ desc "Delete Connector"
4
+ task delete: :environment do
5
+ klass = ENV['MODEL']
6
+ Rails.application.eager_load!
7
+ models = klass.nil? ? Stretchy::MachineLearning::Connector.descendants : [klass.constantize]
8
+ models.each do |model|
9
+ spinner = TTY::Spinner.new("Deleting Connector #{model} ".ljust(JUSTIFICATION) + ":spinner", format: :dots)
10
+ spinner.auto_spin
11
+
12
+ begin
13
+ response = model.delete!
14
+ rescue Stretchy::MachineLearning::Errors::ConnectorMissingError => e
15
+ spinner.stop(Rainbow("[MISSING]").white)
16
+ next
17
+ end
18
+ status = if response['result'] == 'deleted'
19
+ Rainbow("[SUCCESS]").green
20
+ else
21
+ Rainbow("[#{response['result'].upcase}]").white
22
+ end
23
+ spinner.stop(status)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,31 @@
1
+ namespace :stretchy do
2
+ namespace :connector do
3
+
4
+ desc "Check the status of all connectors"
5
+ task status: :environment do
6
+ klass = ENV['MODEL']
7
+
8
+ Rails.application.eager_load!
9
+ models = klass.nil? ? Stretchy::MachineLearning::Connector.descendants : [klass.constantize]
10
+
11
+ puts Rainbow("Connector").color :gray
12
+ models.each do |model|
13
+
14
+ begin
15
+ response = model.find
16
+ rescue Stretchy::MachineLearning::Errors::ConnectorMissingError => e
17
+ puts "#{model}".ljust(JUSTIFICATION) + Rainbow("[MISSING]").white
18
+ next
19
+ end
20
+ status = if response
21
+ Rainbow("[CREATED]").green.bright
22
+ else
23
+ Rainbow("[MISSING]").white
24
+ end
25
+ puts "#{model}".ljust(JUSTIFICATION) + status
26
+ end
27
+ puts "\n\n"
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ namespace :stretchy do
2
+ namespace :connector do
3
+ desc "Update connector"
4
+ task update: :environment do
5
+ klass = ENV['MODEL']
6
+ Rails.application.eager_load!
7
+ models = klass.nil? ? Stretchy::MachineLearning::Connector.descendants : [klass.constantize]
8
+ models.each do |model|
9
+ spinner = TTY::Spinner.new("Updating Connector #{model} ".ljust(JUSTIFICATION) + ":spinner", format: :dots)
10
+ spinner.auto_spin
11
+
12
+ # if model.exists?
13
+ # spinner.stop(Rainbow("[EXISTS]").yellow)
14
+ # next
15
+ # end
16
+
17
+ begin
18
+ response = model.update!
19
+ rescue Stretchy::MachineLearning::Errors::ConnectorMissingError => e
20
+ spinner.stop(Rainbow("[FAILED]").red)
21
+ next
22
+ end
23
+ status = if response
24
+ Rainbow("[SUCCESS]").green
25
+ else
26
+ Rainbow("[FAILED]").red
27
+ end
28
+ spinner.stop(status)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ namespace :stretchy do
2
+ namespace :index do
3
+ desc "Create indices"
4
+ task create: :environment do
5
+ klass = ENV['MODEL']
6
+ Rails.application.eager_load!
7
+ models = klass.nil? ? StretchyModel.descendants : [klass.constantize]
8
+ models.each do |model|
9
+ next if model.name == "Stretchy::MachineLearning::Registry"
10
+ spinner = TTY::Spinner.new("Creating index #{model} (#{model.index_name}) ".ljust(JUSTIFICATION) + ":spinner", format: :dots)
11
+ spinner.auto_spin
12
+ if model.index_exists?
13
+ spinner.stop( Rainbow("[EXISTS]").orange)
14
+ next
15
+ end
16
+
17
+ response = model.create_index!
18
+ status = if response
19
+ Rainbow("[SUCCESS]").green
20
+ else
21
+ Rainbow("[FAILED]").red
22
+ end
23
+
24
+ spinner.stop(status)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ namespace :stretchy do
2
+ namespace :index do
3
+ desc "Delete indices"
4
+ task delete: :environment do
5
+ klass = ENV['MODEL']
6
+ models = klass.nil? ? StretchyModel.descendants : [klass.constantize]
7
+ models.each do |model|
8
+ next if model.name == "Stretchy::MachineLearning::Registry"
9
+ spinner = TTY::Spinner.new("Deleting index #{model} (#{model.index_name}) ".ljust(JUSTIFICATION) + ":spinner", format: :dots)
10
+ spinner.auto_spin
11
+ unless model.index_exists?
12
+ spinner.stop( Rainbow("[MISSING]").white)
13
+ next
14
+ end
15
+
16
+ response = model.delete_index!
17
+ status = if response
18
+ Rainbow("[SUCCESS]").green
19
+ else
20
+ Rainbow("[FAILED]").red
21
+ end
22
+
23
+ spinner.stop(status)
24
+ end
25
+ end
26
+ end
27
+ end