nexosis_api 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ea8420a0cc83927171b7767fb1d94bd3a5079afa
4
+ data.tar.gz: 440f6ff9e8af3ca49723fbb44b8284f632df58b8
5
+ SHA512:
6
+ metadata.gz: fbe33013ff7623c70db259af4f46f070a913987197a8f5740cba1e5ab541cdec4d3f33a43397d3ffe7ee2816e7f2920deec4b4f856475a2ec5db35148f5e739e
7
+ data.tar.gz: cb0c8cf3defc7381ce444ebe0f46a64518c3a2a1377e396361b500afb45805e5887d1cdc9e52440843bfa40857870b2745b3c7ae7840393479c7772e4d726300
@@ -0,0 +1,12 @@
1
+ require 'httparty'
2
+ require 'nexosis_api/client'
3
+
4
+ # The container for the Nexosis API Client
5
+ module NexosisApi
6
+ class << self
7
+ def client options = {}
8
+ return @client if defined?(@client)
9
+ @client = NexosisApi::Client.new(options)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module NexosisApi
2
+ #Class to parse an individual algorithm
3
+ class Algorithm
4
+ def initialize(algoHash)
5
+ algoHash.each do |k,v|
6
+ instance_variable_set("@#{k}", v) unless v.nil?
7
+ end
8
+ end
9
+
10
+ # A friendly name for the algorithm
11
+ # @return [String]
12
+ attr_accessor :name
13
+
14
+ # Descriptive explanation of the algorithm implementation
15
+ # @return [String]
16
+ attr_accessor :description
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ module NexosisApi
2
+ # Class to parse results of an algorithm run
3
+ class AlgorithmRun
4
+ def initialize(runHash)
5
+ runHash.each do |k,v|
6
+ if k == "metrics"
7
+ @metricSet = Array.new
8
+ v.each{|m| @metricSet << NexosisApi::Metric.new(m) unless m.nil?}
9
+ instance_variable_set("@#{k}", @metricSet)
10
+ elsif k == "links"
11
+ @linkSet = Array.new
12
+ v.each{|l| @linkSet << NexosisApi::Link.new(l) unless l.nil?}
13
+ instance_variable_set("@#{k}", @linkSet)
14
+ else
15
+ instance_variable_set("@#{k}", NexosisApi::Algorithm.new(v)) unless v.nil?
16
+ end
17
+ end
18
+ end
19
+
20
+ # Identifier of algorithm run
21
+ # @return [NexosisApi::Algorithm]
22
+ attr_accessor :algorithm
23
+
24
+ # Set of {NexosisApi::Metric} on algorithm
25
+ # @return [Array]
26
+ attr_accessor :metrics
27
+
28
+ # Relevant hypermedia as {NexosisApi::Link}
29
+ # @return [Array]
30
+ attr_accessor :links
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ module NexosisApi
2
+ #Class to parse the model data results from a session
3
+ class AlgorithmSelection
4
+ def initialize(dataHash)
5
+ dataHash.each do |k,v|
6
+ if k == "champion"
7
+ instance_variable_set("@#{k}", NexosisApi::AlgorithmRun.new(v))
8
+ elsif k == "contestants"
9
+ @contestantArray = Array.new
10
+ v.each {|c| @contestantArray << NexosisApi::AlgorithmRun.new(c)}
11
+ instance_variable_set("@#{k}", @contestantArray)
12
+ else
13
+ instance_variable_set("@#{k}", v) unless v.nil?
14
+ end
15
+ end
16
+ end
17
+
18
+ # The date on which this algo was selected as champion
19
+ # @return [DateTime]
20
+ attr_accessor :date
21
+
22
+ # The session which selected the algorithm
23
+ # @return [String] session identifier
24
+ attr_accessor :sessionId
25
+
26
+ # The champion algorithm used
27
+ # @return [NexosisApi::AlgorithmRun]
28
+ attr_accessor :champion
29
+
30
+ # All other algorithms which competed
31
+ # @return [Array of NexosisApi::AlgorithmRun]
32
+ attr_accessor :contestants
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ require 'nexosis_api/algorithm_run'
2
+ require 'nexosis_api/algorithm_selection'
3
+ require 'nexosis_api/algorithm'
4
+ require 'nexosis_api/dataset_data'
5
+ require 'nexosis_api/dataset_model'
6
+ require 'nexosis_api/dataset_summary'
7
+ require 'nexosis_api/http_exception'
8
+ require 'nexosis_api/impact_metric'
9
+ require 'nexosis_api/link'
10
+ require 'nexosis_api/metric'
11
+ require 'nexosis_api/session_response'
12
+ require 'nexosis_api/session_result'
13
+ require 'nexosis_api/session'
14
+ require 'nexosis_api/client/sessions'
15
+ require 'nexosis_api/client/datasets'
16
+
17
+ module NexosisApi
18
+ # Primary entry point to working with Nexosis API
19
+ class Client
20
+ include HTTParty
21
+ base_uri 'https://ml.nexosis.com/api'
22
+ include Client::Sessions
23
+ include Client::Datasets
24
+
25
+ def initialize(options = {})
26
+ raise ArgumentError, 'api_key was not defined' unless options[:api_key].nil? == false
27
+ @api_key = options[:api_key]
28
+ self.class.base_uri options[:base_uri] unless options[:base_uri].nil?
29
+ @headers = {"api-key" => @api_key, "content-type" => "application/json"}
30
+ @options = {:headers => @headers, :format => :json}
31
+ end
32
+
33
+ # Gets the current account balance.
34
+ #
35
+ # @return [String] a string with the numeric balance and currency identifier postfix - 10.0 USD
36
+ # @example Get account balance
37
+ # client.get_account_balance
38
+ def get_account_balance()
39
+ session_url = '/sessions'
40
+ response = self.class.get(session_url,@options)
41
+ response.headers["nexosis-account-balance"]
42
+ end
43
+
44
+ private
45
+ def process_csv_to_s csv
46
+ content = ""
47
+ if(csv.is_a?(CSV))
48
+ csv.each do |row|
49
+ if(csv.headers.nil?)
50
+ #not using row.to_csv because it uses non-compliant '\n' newline
51
+ content.concat(row.join(',')).concat("\r\n")
52
+ else
53
+ content.concat(row.fields.join(',')).concat("\r\n")
54
+ end
55
+ end
56
+ if(csv.headers.nil? == false)
57
+ content.prepend(csv.headers.join(',').concat("\r\n")) unless csv.headers.nil?
58
+ end
59
+ else
60
+ content = csv
61
+ end
62
+ content
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,165 @@
1
+ require 'csv'
2
+
3
+ module NexosisApi
4
+ class Client
5
+ # Dataset-based API operations
6
+ #
7
+ # @see http://docs.nexosis.com/
8
+ module Datasets
9
+
10
+ # save data in a named dataset
11
+ #
12
+ # @param dataset_name [String] name to save the dataset
13
+ # @param json_data [Hash] parsed json data
14
+ # @return [NexosisApi::DatasetSummary] information about your upload
15
+ def create_dataset_json(dataset_name, json_data)
16
+ create_dataset dataset_name, json_data.to_json, 'application/json'
17
+ end
18
+
19
+ # save data in a named dataset from csv content
20
+ #
21
+ # @param dataset_name [String] name to save the dataset
22
+ # @param csv [CSV] csv content ready for reading
23
+ # @return [NexosisApi::DatasetSummary] information about your upload
24
+ def create_dataset_csv(dataset_name, csv)
25
+ content = process_csv_to_s csv
26
+ create_dataset dataset_name, content, 'text/csv'
27
+ end
28
+
29
+ # Gets the list of data sets that have been saved to the system, optionally filtering by partial name match.
30
+ #
31
+ # @param partial_name [String] if provided, all datasets returned will contain this string
32
+ # @return [Array of NexosisApi::DatasetSummary] array of datasets found
33
+ def list_datasets(partial_name = '')
34
+ list_dataset_url = "/data?partialName=#{partial_name.to_s}"
35
+ response = self.class.get(list_dataset_url,:headers => @headers)
36
+ if(response.success?)
37
+ results = []
38
+ response.parsed_response["items"].each do |dr|
39
+ results << NexosisApi::DatasetSummary.new(dr)
40
+ end
41
+ results
42
+ else
43
+ raise HttpException.new("There was a problem listing datasets: #{response.code}.", "listing datasets with partial name #{partial_name}" ,response)
44
+ end
45
+ end
46
+
47
+ # Get the data in the set, with paging, and optional projection.
48
+ #
49
+ # @param dataset_name [String] name of the dataset for which to retrieve data.
50
+ # @param page_number [Integer] zero-based page number of results to retrieve
51
+ # @param page_size [Integer] Count of results to retrieve in each page (max 100).
52
+ # @param query_options [Hash] options hash for limiting and projecting returned results
53
+ # @note Query Options includes start_date as a DateTime or ISO 8601 compliant string,
54
+ # end_date, also as a DateTime or string, and :include as an Array of strings indicating the columns to return.
55
+ # The dates can be used independently and are inclusive. Lack of options returns all values within the given page.
56
+ def get_dataset(dataset_name, page_number = 0, page_size = 50, query_options = {})
57
+ response = get_dataset_internal(dataset_name,page_number,page_size,query_options)
58
+ if(response.success?)
59
+ NexosisApi::DatasetData.new(response.parsed_response)
60
+ else
61
+ raise HttpException.new("There was a problem getting the dataset: #{response.code}.", "getting dataset #{dataset_name}" ,response)
62
+ end
63
+ end
64
+
65
+ # Get the data in the set, written to a CSV file, optionally filtering it.
66
+ #
67
+ # @param dataset_name [String] name of the dataset for which to retrieve data.
68
+ # @param page_number [Integer] zero-based page number of results to retrieve
69
+ # @param page_size [Integer] Count of results to retrieve in each page (max 100).
70
+ # @param query_options [Hash] options hash for limiting and projecting returned results
71
+ # @note Query Options includes start_date as a DateTime or ISO 8601 compliant string,
72
+ # end_date, also as a DateTime or string, and :include as an Array of strings indicating the columns to return.
73
+ # The dates can be used independently and are inclusive. Lack of options returns all values within the given page.
74
+ # @example get page 1 with 20 results each page
75
+ # NexosisApi.client.get_dataset_csv('MyDataset', 1, 20, {:include => 'sales'})
76
+ def get_dataset_csv(dataset_name, page_number = 0, page_size = 50, query_options = {})
77
+ response = get_dataset_internal(dataset_name,page_number,page_size,query_options,"text/csv")
78
+ if(response.success?)
79
+ response.body
80
+ else
81
+ raise HttpException.new("There was a problem getting the dataset: #{response.code}.", "getting dataset #{dataset_name}" ,response)
82
+ end
83
+ end
84
+
85
+ # Remove data from a data set or the entire set.
86
+ #
87
+ # @param dataset [String] the name of the dataset from which to remove data
88
+ # @param filter_options [Hash] filtering which data to remove
89
+ # @Options - start_date, end_date, cascade_forecast, cascade_sessions, cascade
90
+ # start_date - the first date on which to start removing data
91
+ # end_date - the last date on which to finish removing data
92
+ # cascade_forecast - will cascade deletes to all related forecasts
93
+ # cascade_sessions - will cascade deletes to all related sessions
94
+ # cascade - will cascade deletes to all related forecasts and sessions
95
+ # @example - request delete with cascade forecast
96
+ # NexosisApi.client.remove_dataset('mydataset', {:cascade_forecast => true})
97
+ def remove_dataset(dataset_name, filter_options = {})
98
+ raise ArgumentError "dataset_name was not provided and is not optional " unless dataset_name.to_s.empty? == false
99
+ dataset_remove_url = "/data/#{dataset_name}"
100
+ query = {}
101
+ cascade_options = filter_options.each {|k,v|
102
+ if(k.to_s.include?('cascade') && v)
103
+ if(k.to_s == 'cascade')
104
+ #hack here to handle two-keyed api query param
105
+ query["cascade"] = "forecast"
106
+ query[:cascade] = "session"
107
+ elsif(k.to_s == 'cascade_forecast')
108
+ query["cascade"] = "forecast"
109
+ else
110
+ query["cascade"] = "session"
111
+ end
112
+ end
113
+ }
114
+
115
+ if(filter_options.empty? == false)
116
+ query["startDate"] = filter_options[:start_date].to_s unless filter_options[:start_date].nil?
117
+ query["endDate"] = filter_options[:end_date].to_s unless filter_options[:end_date].nil?
118
+ end
119
+ if(query.values.all?{|v|v.to_s.empty?})
120
+ query = nil
121
+ end
122
+ response = self.class.delete(dataset_remove_url, :headers => @headers, :query => query)
123
+ if(response.success?)
124
+ return
125
+ else
126
+ raise HttpException.new("There was a problem removing the dataset: #{response.code}.", "removing dataset #{dataset_name}", response)
127
+ end
128
+ end
129
+
130
+ private
131
+ def create_dataset dataset_name, content, content_type
132
+ raise ArgumentError "dataset_name was not provided and is not optional " unless dataset_name.to_s.empty? == false
133
+ dataset_url = "/data/#{dataset_name}"
134
+ headers = {"api-key" => @api_key, "content-type" => content_type}
135
+ response = self.class.put(dataset_url, {:headers => headers, :body => content})
136
+ if(response.success?)
137
+ NexosisApi::DatasetSummary.new(response)
138
+ else
139
+ raise HttpException.new("There was a problem uploading the dataset: #{response.code}.", "uploading dataset #{dataset_name}" ,response)
140
+ end
141
+ end
142
+
143
+ def get_dataset_internal(dataset_name, page_number = 0, page_size = 50, query_options = {}, content_type = "application/json")
144
+ raise ArgumentError "page size must be <= 100 items per page" unless page_size <= 100
145
+ raise ArgumentError "dataset_name was not provided and is not optional" unless dataset_name.to_s.empty? == false
146
+ dataset_url = "/data/#{dataset_name.to_s}"
147
+ headers = {"api-key" => @api_key, "Accept" => content_type}
148
+ self.class.get(dataset_url, :headers => headers, :query => create_query(page_number, page_size, query_options))
149
+ end
150
+
151
+ def create_query page_number, page_size, options = {}
152
+ options.store(:page_number,page_number)
153
+ options.store(:page_size,page_size)
154
+ query = {
155
+ "startDate" => options[:start_date].to_s,
156
+ "endDate" => options[:end_date].to_s,
157
+ "page" => options[:page_number],
158
+ "pageSize" => options[:page_size],
159
+ "include" => options[:include].to_s
160
+ }
161
+ end
162
+
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,226 @@
1
+ require 'csv'
2
+
3
+ module NexosisApi
4
+ class Client
5
+ # Session-based API operations
6
+ #
7
+ # @see http://docs.nexosis.com/
8
+ module Sessions
9
+
10
+ # List sessions previously submitted
11
+ #
12
+ # @param query_options [Hash] optionally provide query parameters to limit the search of sessions.
13
+ # @return[Array of NexosisApi::SessionResponse] with all sessions matching the query or all if no query
14
+ # @note query parameters hash members are dataset_name, event_name, start_date, and end_date.
15
+ # Start and end dates refer to the session requested date.
16
+ # @example query for just one dataset
17
+ # sessions = NexosisApi.client.list_sessions :dataset_name => 'MyDataset'
18
+ def list_sessions(query_options = {})
19
+ sessions_url = '/sessions'
20
+ response = self.class.get(sessions_url, :headers => @headers, :query => get_query_from_options(query_options))
21
+ if(response.success?)
22
+ all_responses = []
23
+ response.parsed_response["items"].each do |session_hash|
24
+ response_hash = {"session" => session_hash}.merge(response.headers)
25
+ all_responses << NexosisApi::SessionResponse.new(response_hash)
26
+ end
27
+ all_responses
28
+ else
29
+ raise HttpException.new("Could not retrieve sessions","Get all sessions with query #{query_options.to_s}",response)
30
+ end
31
+ end
32
+
33
+ # Remove a session
34
+ # @param session_id [String] required session identifier
35
+ def remove_session(session_id)
36
+ if(session_id.to_s.empty?)
37
+ raise ArgumentError 'session_id cannot be empty or nil'
38
+ end
39
+ session_url = '/session/#{session_id.to_s}'
40
+ response = self.class.delete(session_url)
41
+ if(response.success?)
42
+ return
43
+ else
44
+ raise HttpException.new("Could not delete session with given id","remove session with id #{session_id.to_s}",response)
45
+ end
46
+ end
47
+
48
+ # Remove sessions that have been run. All query options are optional and will be used to limit the sessions removed.
49
+ # @param query_options [Hash] optionally provide query parametes to limit the set of sessions removed.
50
+ # @note query parameters hash members are type, dataset_name, event_name, start_date, and end_date.
51
+ # Start and end dates refer to the session requested date.
52
+ # Results are not removed but then can only be accessed by dataset name
53
+ def remove_sessions(query_options = {})
54
+ sessions_url = '/sessions'
55
+ response = self.class.delete(sessions_url, :headers => @headers, :query => get_query_from_options(query_options))
56
+ if(response.success?)
57
+ return
58
+ else
59
+ raise HttpException.new("Could not remove sessions","Remove sessions with query #{query_options.to_s}",response)
60
+ end
61
+ end
62
+
63
+ # Forecast from data already saved to the API.
64
+ #
65
+ # @param dataset_name [String] The name of the saved data set that has the data to forecast on.
66
+ # @param target_column [String] The name of the column for which you want predictions.
67
+ # @param start_date [DateTime] The starting date of the forecast period. Can be ISO 8601 string.
68
+ # @param end_date [DateTime] The ending date of the forecast period. Can be ISO 8601 string.
69
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion
70
+ def create_forecast_session(dataset_name, target_column, start_date, end_date)
71
+ create_session dataset_name, target_column, start_date, end_date
72
+ end
73
+
74
+ # Forecast from CSV formatted data.
75
+ #
76
+ # @param csv [CSV] initialized CSV object ready for reading.
77
+ # @param target_column [String] The name of the column for which you want predictions.
78
+ # @param start_date [DateTime] The starting date of the forecast period. Can be ISO 8601 parseable string.
79
+ # @param end_date [DateTime] The ending date of the forecast period. Can be ISO 8601 parseable string.
80
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion
81
+ # @example load and send local file
82
+ # mycsv = CSV.read('.\mylocal.csv')
83
+ # NexosisApi.client(:api_key=>mykey).create_forecast_session_csv(mycsv,'sales','01-01-2017','02-01-2017')
84
+ def create_forecast_session_csv(csv, target_column, start_date, end_date)
85
+ content = process_csv_to_s csv
86
+ create_session(nil, target_column, start_date, end_date, false, nil, "forecast", content)
87
+ end
88
+
89
+ # Forecast from data posted in the request.
90
+ #
91
+ # @param json_data [String] Json dataset matching the dataset input schema.
92
+ # @param target_column [String] The name of the column for which you want predictions.
93
+ # @param start_date [DateTime] The starting date of the forecast period. Can be ISO 8601 string.
94
+ # @param end_date [DateTime] The ending date of the forecast period. Can be ISO 8601 string.
95
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion
96
+ # @see https://developers.nexosis.com/docs/services/98847a3fbbe64f73aa959d3cededb3af/operations/5919ef80a730020dd851f233
97
+ def create_forecast_session_data(json_data, target_column, start_date, end_date)
98
+ create_session nil, target_column, start_date, end_date, false, nil, "forecast", json_data, "application/json"
99
+ end
100
+
101
+ # Estimate the cost of a forecast from data already saved to the API.
102
+ #
103
+ # @param dataset_name [String] The name of the saved data set that has the data to forecast on.
104
+ # @param target_column [String] The name of the column for which you want predictions.
105
+ # @param start_date [DateTime] The starting date of the forecast period. Can be ISO 8601 string.
106
+ # @param end_date [DateTime] The ending date of the forecast period. Can be ISO 8601 string.
107
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion, including the cost
108
+ def estimate_forecast_session(dataset_name, target_column, start_date, end_date)
109
+ create_session dataset_name, target_column, start_date, end_date, true
110
+ end
111
+
112
+ # Analyze impact for an event with data already saved to the API.
113
+ #
114
+ # @param dataset_name [String] The name of the saved data set that has the data to forecast on.
115
+ # @param target_column [String] The name of the column for which you want predictions.
116
+ # @param start_date [DateTime] The starting date of the impactful event. Can be ISO 8601 string.
117
+ # @param end_date [DateTime] The ending date of the impactful event. Can be ISO 8601 string.
118
+ # @param event_name [String] The name of the event.
119
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion
120
+ def create_impact_session(dataset_name, target_column, start_date, end_date, event_name)
121
+ create_session dataset_name, target_column, start_date, end_date, false, event_name, "impact"
122
+ end
123
+
124
+ # Analyze impact for an event with data in json format.
125
+ #
126
+ # @param json_data [String] Json dataset matching the dataset input schema.
127
+ # @param target_column [String] The name of the column for which you want predictions.
128
+ # @param start_date [DateTime] The starting date of the impactful event. Can be ISO 8601 string.
129
+ # @param end_date [DateTime] The ending date of the impactful event. Can be ISO 8601 string.
130
+ # @param event_name [String] The name of the event.
131
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion
132
+ # @see https://developers.nexosis.com/docs/services/98847a3fbbe64f73aa959d3cededb3af/operations/5919ef80a730020dd851f233
133
+ def create_impact_session_data(json_data, target_column, start_date, end_date, event_name)
134
+ create_session nil, target_column, start_date, end_date, false, event_name, "impact", json_data, "application/json"
135
+ end
136
+
137
+ # Estimate the cost of impact analysis for an event with data already saved to the API.
138
+ #
139
+ # @param dataset_name [String] The name of the saved data set that has the data to forecast on.
140
+ # @param target_column [String] The name of the column for which you want predictions.
141
+ # @param start_date [DateTime] The starting date of the impactful event. Can be ISO 8601 string.
142
+ # @param end_date [DateTime] The ending date of the impactful event. Can be ISO 8601 string.
143
+ # @param event_name [String] The name of the event.
144
+ # @return [NexosisApi::SessionResponse] providing information about the sesssion, including the cost
145
+ def estimate_impact_session(dataset_name, target_column, start_date, end_date, event_name)
146
+ create_session dataset_name, target_column, start_date, end_date, true, event_name, "impact"
147
+ end
148
+
149
+ # Get the results of the session.
150
+ #
151
+ # @param session_id [String] the Guid string returned in a previous session request
152
+ # @param as_csv [Boolean] indicate whether results should be returned in csv format
153
+ # @return [NexosisApi::SessionResult] SessionResult if parsed, String of csv data otherwise
154
+ def get_session_results(session_id, as_csv = false)
155
+ session_result_url = "/sessions/#{session_id}/results"
156
+
157
+ if as_csv
158
+ @headers["Accept"] = "text/csv"
159
+ end
160
+ response = self.class.get(session_result_url, @options)
161
+ @headers.delete("Accept")
162
+
163
+ if(response.success?)
164
+ if(as_csv)
165
+ response.body
166
+ else
167
+ NexosisApi::SessionResult.new(response.parsed_response)
168
+ end
169
+ else
170
+ raise HttpException.new("There was a problem getting the session: #{response.code}.", "get results for session #{session_id}" ,response)
171
+ end
172
+ end
173
+
174
+ # Get a specific session by id.
175
+ #
176
+ # @param session_id [String] the Guid string returned in a previous session request
177
+ # @return [NexosisApi::Session] a Session object populated with the session's data
178
+ def get_session(session_id)
179
+ session_url = "/sessions/#{session_id}"
180
+ response = self.class.get(session_url, @options)
181
+ if(response.success?)
182
+ NexosisApi::Session.new(response.parsed_response)
183
+ else
184
+ raise HttpException.new("There was a problem getting the session: #{response.code}.", "getting session #{session_id}" ,response)
185
+ end
186
+ end
187
+ private
188
+ def create_session(dataset_name, target_column, start_date, end_date, is_estimate=false, event_name = nil, type = "forecast", content = nil, content_type = "text/csv")
189
+ session_url = "/sessions/#{type}"
190
+ query = {
191
+ "dataSetName" => dataset_name,
192
+ "targetColumn" => target_column,
193
+ "startDate" => start_date.to_s,
194
+ "endDate" => end_date.to_s,
195
+ "isestimate" => is_estimate.to_s
196
+ }
197
+ if(event_name.nil? == false)
198
+ query["eventName"] = event_name
199
+ end
200
+ if content.nil? == false
201
+ headers = {"api-key" => @api_key, "content-type" => content_type}
202
+ response = self.class.post(session_url, {:headers => headers, :query => query, :body => content})
203
+ else
204
+ response = self.class.post(session_url, :headers => @headers, :query => query)
205
+ end
206
+ if(response.success?)
207
+ session_hash = {"session" => response.parsed_response}.merge(response.headers)
208
+ NexosisApi::SessionResponse.new(session_hash)
209
+ else
210
+ raise HttpException.new("Unable to create new #{type} session","Create session for dataset #{dataset_name}",response)
211
+ end
212
+ end
213
+
214
+ def get_query_from_options(options)
215
+ query = {
216
+ "dataSetName" => options[:dataset_name],
217
+ "eventName" => options[:event_name],
218
+ "startDate" => options[:start_date],
219
+ "endDate" => options[:end_date],
220
+ "type" => options[:type]
221
+ }
222
+ query
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,24 @@
1
+ module NexosisApi
2
+ # class to hold the parsed results of a dataset
3
+ class DatasetData
4
+ def initialize(data_hash)
5
+ data_hash.each do |k,v|
6
+ if(k == "data")
7
+ @data = v
8
+ elsif(k == "links")
9
+ links = Array.new
10
+ v.each do |l| links << NexosisApi::Link.new(l) end
11
+ @links = links
12
+ end
13
+ end
14
+ end
15
+
16
+ # Helpful links to more information about this dataset
17
+ # @return [Array of NexosisApi::Link]
18
+ attr_accessor :links
19
+
20
+ #The hash of data values from the dataset
21
+ # @return [Array of Hash] where each hash contains the dataset data
22
+ attr_accessor :data
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ module NexosisApi
2
+ # Class to parse the model results calculated for a dataset
3
+ class DatasetModel
4
+ def initialize(dataHash)
5
+ dataHash.each do |k,v|
6
+ if k == "championContest"
7
+ instance_variable_set("@#{k}", NexosisApi::AlgorithmSelection.new(v))
8
+ else
9
+ instance_variable_set("@#{k}", v) unless v.nil?
10
+ end
11
+ end
12
+ end
13
+
14
+ # The name of the dataset used in the evaluation
15
+ # @return [String]
16
+ attr_accessor :datasetName
17
+
18
+ # The column targeted for prediction
19
+ # @return [String]
20
+ attr_accessor :targetColumn
21
+
22
+ # The details of the winning algorithm
23
+ # @return [NexosisApi::AlgorithmSelection]
24
+ attr_accessor :championContest
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module NexosisApi
2
+ # class to hold the parsed results of a dataset
3
+ class DatasetSummary
4
+ def initialize(data_hash)
5
+ data_hash.each do |k,v|
6
+ if(k == "dataSetName")
7
+ @dataset_name = v unless v.nil?
8
+ end
9
+ end
10
+ end
11
+
12
+ # The name of the dataset uploaded and saved
13
+ attr_accessor :dataset_name
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module NexosisApi
2
+ # encapsulate errors from the Nexosis API
3
+ class HttpException < StandardError
4
+ attr_reader :message,:action,:response,:request
5
+ def initialize(message = "", action = nil, http_obj)
6
+ @message = message
7
+ if(http_obj.is_a?(Hash))
8
+ @message.prepend(http_obj["message"].concat(": ")) unless http_obj["message"].nil?
9
+ @action = action
10
+ if(http_obj.instance_of?(HTTParty::Response))
11
+ @message = message.concat("|| Explanation: ").concat(http_obj["errorDetails"]["message"]) unless http_obj["errorDetails"]["message"].nil?
12
+ @code = http_obj.parsed_response["statusCode"]
13
+ @type = http_obj.parsed_response["errorType"]
14
+ @response = http_obj.response
15
+ @request = http_obj.request
16
+ end
17
+ else
18
+ @code = http_obj.code
19
+ end
20
+ end
21
+
22
+ attr_reader :code
23
+ attr_reader :response
24
+ attr_reader :request
25
+ attr_reader :message
26
+ attr_reader :type
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module NexosisApi
2
+ # Class to parse the metric results of an impact analysis
3
+ class ImpactMetric
4
+ def initialize(metricHash)
5
+ metricHash.each do |k,v|
6
+ instance_variable_set("@#{k}", v) unless v.nil?
7
+ end
8
+ end
9
+
10
+ # Statistical value used to determine the significance of the impact.
11
+ # @return [Float]
12
+ attr_accessor :pValue
13
+
14
+ # Total absolute effect of the event on the dataset.
15
+ # @return [Float]
16
+ attr_accessor :absoluteEffect
17
+
18
+ # Percentage impact of the event on the dataset.
19
+ # @return [Float]
20
+ attr_accessor :relativeEffect
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ module NexosisApi
2
+ # Class to parse hypermedia resutls
3
+ class Link
4
+ def initialize(linkHash)
5
+ linkHash.each do |k,v|
6
+ instance_variable_set("@#{k}", v) unless v.nil?
7
+ end
8
+ end
9
+
10
+ # relation type of the link
11
+ # @return [String]
12
+ attr_accessor :rel
13
+
14
+ # resource url
15
+ # @return [String]
16
+ attr_accessor :href
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module NexosisApi
2
+ # Class to parse algorithm metrics from model results
3
+ class Metric
4
+ def initialize(metricHash)
5
+ metricHash.each do |k,v|
6
+ instance_variable_set("@#{k}", v) unless v.nil?
7
+ end
8
+ end
9
+
10
+ # Friendly name of the metric
11
+ # @return [String]
12
+ attr_accessor :name
13
+
14
+ # Identifier for metric type
15
+ # @return [String]
16
+ attr_accessor :code
17
+
18
+ # Calculated metric
19
+ # @return [Float]
20
+ attr_accessor :value
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ module NexosisApi
2
+ # Class for parsing the results of a session based request
3
+ class Session
4
+ def initialize(sessionHash)
5
+ sessionHash.each do |k,v|
6
+ if(k == "links")
7
+ links = Array.new
8
+ v.each do |l| links << NexosisApi::Link.new(l) end
9
+ instance_variable_set("@#{k}", links) unless v.nil?
10
+ elsif(k == "isEstimate")
11
+ instance_variable_set("@is_estimate", v) unless v.nil?
12
+ else
13
+ instance_variable_set("@#{k}", v) unless v.nil?
14
+ end
15
+ end
16
+ end
17
+
18
+ # identifier for this sesssion
19
+ # @return [String]
20
+ attr_accessor :sessionId
21
+
22
+ # What type of analysis was run during this session
23
+ # @return [String]
24
+ attr_accessor :type
25
+
26
+ # Is this session requested, estimated, started, or completed
27
+ # @return [String]
28
+ attr_accessor :status
29
+
30
+ # Date and status of each status this session has entered
31
+ # @return [Hash]
32
+ attr_accessor :statusHistory
33
+
34
+ # reserved for future extensions
35
+ # @return [Hash]
36
+ attr_accessor :extraParameters
37
+
38
+ # the dataset used in this session
39
+ # @return [String]
40
+ attr_accessor :dataSetName
41
+
42
+ # The column in the dataset for which this session ran predictions
43
+ # @return [String]
44
+ attr_accessor :targetColumn
45
+
46
+ # The start date of analysis in this session
47
+ # @return [DateTime]
48
+ attr_accessor :startDate
49
+
50
+ # The end date of analysis in this session
51
+ # @return [DateTime]
52
+ attr_accessor :endDate
53
+
54
+ # associated hypermedia
55
+ # @return [Array of NexosisApi::Link]
56
+ attr_accessor :links
57
+
58
+ # Is this session an estimate only session
59
+ # @return [Boolean]
60
+ attr_accessor :is_estimate
61
+ end
62
+ end
63
+
@@ -0,0 +1,26 @@
1
+ require 'nexosis_api/session'
2
+
3
+ module NexosisApi
4
+ #Class to parse the results from a new session
5
+ class SessionResponse < Session
6
+ def initialize(forecast_hash)
7
+ forecast_hash.each do |k,v|
8
+ if(k == "session")
9
+ super(v) unless v.nil?
10
+ elsif(k == "nexosis-request-cost")
11
+ instance_variable_set("@cost", v[0]) unless v.nil?
12
+ elsif(k == "nexosis-account-balance")
13
+ instance_variable_set("@account_balance", v[0]) unless v.nil?
14
+ end
15
+ end
16
+ end
17
+
18
+ # The cost of this session with currency identifier
19
+ # @return [String]
20
+ attr_accessor :cost
21
+
22
+ # Remaining balance after charge for this session
23
+ # @return [String]
24
+ attr_accessor :account_balance
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module NexosisApi
2
+ # Class for parsing the results of a completed session
3
+ class SessionResult < Session
4
+ def initialize(sessionHash)
5
+ sessionHash.each do |k,v|
6
+ if k == "metrics"
7
+ instance_variable_set("@#{k}", NexosisApi::ImpactMetric.new(v)) unless v.nil?
8
+ else
9
+ instance_variable_set("@#{k}", v) unless v.nil?
10
+ end
11
+ end
12
+ super(sessionHash.reject {|k,v| k == "data" || k == "metrics"})
13
+ end
14
+
15
+ # The impact analysis if this session type is impact
16
+ # @return [NexosisApi::ImpactMetric]
17
+ attr_accessor :metrics
18
+
19
+ # The result data in a hash with the name of the target column
20
+ # @return [Hash]
21
+ attr_accessor :data
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.add_development_dependency 'bundler', '~> 1.0'
7
+ spec.add_dependency 'httparty', '>= 0.15'
8
+ spec.authors = ["Nexosis,Inc"]
9
+ spec.description = %q{Nexosis API client}
10
+ spec.email = ['support@nexosis.com']
11
+ spec.files = %w(nexosisapi.gemspec)
12
+ spec.files += Dir.glob("lib/**/*.rb")
13
+ spec.homepage = 'https://github.com/nexosis/apiclient-rb'
14
+ spec.licenses = ['MIT']
15
+ spec.name = 'nexosis_api'
16
+ spec.require_paths = ['lib']
17
+ spec.required_ruby_version = '>= 2.0.0'
18
+ spec.summary = "Ruby client for working with the Nexosis API"
19
+ spec.version = '1.0.0'
20
+ spec.metadata["yard.run"] = "yri"
21
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nexosis_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nexosis,Inc
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.15'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.15'
41
+ description: Nexosis API client
42
+ email:
43
+ - support@nexosis.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/nexosis_api.rb
49
+ - lib/nexosis_api/algorithm.rb
50
+ - lib/nexosis_api/algorithm_run.rb
51
+ - lib/nexosis_api/algorithm_selection.rb
52
+ - lib/nexosis_api/client.rb
53
+ - lib/nexosis_api/client/datasets.rb
54
+ - lib/nexosis_api/client/sessions.rb
55
+ - lib/nexosis_api/dataset_data.rb
56
+ - lib/nexosis_api/dataset_model.rb
57
+ - lib/nexosis_api/dataset_summary.rb
58
+ - lib/nexosis_api/http_exception.rb
59
+ - lib/nexosis_api/impact_metric.rb
60
+ - lib/nexosis_api/link.rb
61
+ - lib/nexosis_api/metric.rb
62
+ - lib/nexosis_api/session.rb
63
+ - lib/nexosis_api/session_response.rb
64
+ - lib/nexosis_api/session_result.rb
65
+ - nexosisapi.gemspec
66
+ homepage: https://github.com/nexosis/apiclient-rb
67
+ licenses:
68
+ - MIT
69
+ metadata:
70
+ yard.run: yri
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 2.0.0
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.5.2
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Ruby client for working with the Nexosis API
91
+ test_files: []