stretchy-model 0.6.6 → 0.7.0

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 (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