nexosis_api 1.1.2 → 1.2.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 +4 -4
- data/lib/nexosis_api.rb +11 -11
- data/lib/nexosis_api/algorithm.rb +18 -18
- data/lib/nexosis_api/algorithm_run.rb +32 -32
- data/lib/nexosis_api/algorithm_selection.rb +34 -34
- data/lib/nexosis_api/client.rb +98 -72
- data/lib/nexosis_api/client/datasets.rb +157 -162
- data/lib/nexosis_api/client/imports.rb +74 -75
- data/lib/nexosis_api/client/sessions.rb +213 -213
- data/lib/nexosis_api/client/views.rb +109 -0
- data/lib/nexosis_api/column.rb +49 -0
- data/lib/nexosis_api/column_options.rb +33 -0
- data/lib/nexosis_api/column_role.rb +15 -12
- data/lib/nexosis_api/column_type.rb +19 -15
- data/lib/nexosis_api/dataset_data.rb +24 -24
- data/lib/nexosis_api/dataset_model.rb +26 -26
- data/lib/nexosis_api/dataset_summary.rb +27 -27
- data/lib/nexosis_api/http_exception.rb +28 -24
- data/lib/nexosis_api/impact_metric.rb +22 -22
- data/lib/nexosis_api/imports_response.rb +66 -66
- data/lib/nexosis_api/join.rb +58 -0
- data/lib/nexosis_api/link.rb +18 -18
- data/lib/nexosis_api/metric.rb +21 -21
- data/lib/nexosis_api/session.rb +88 -80
- data/lib/nexosis_api/session_response.rb +26 -26
- data/lib/nexosis_api/session_result.rb +23 -23
- data/lib/nexosis_api/time_interval.rb +15 -15
- data/lib/nexosis_api/view_data.rb +13 -0
- data/lib/nexosis_api/view_definition.rb +51 -0
- data/nexosisapi.gemspec +20 -20
- metadata +10 -5
- data/lib/nexosis_api/dataset_column.rb +0 -47
@@ -0,0 +1,109 @@
|
|
1
|
+
module NexosisApi
|
2
|
+
# class to operate on views endpoint in Nexosis API
|
3
|
+
class Client
|
4
|
+
# Views-based API operations
|
5
|
+
# @see http://docs.nexosis.com/
|
6
|
+
# @since v1.2
|
7
|
+
module Views
|
8
|
+
## List all existing view defintions, optionally limited by
|
9
|
+
# partial name or participating data sources
|
10
|
+
# @param partial_name [String] optionally limit results by view name
|
11
|
+
# @param dataset_name [String] optionally limit results by dataset used in definition
|
12
|
+
# @param page [Integer] optionally get results by non-zero page - defaults to 0
|
13
|
+
# @param page_size [Integer] optionally limit page size - defaults to 50 (max: 1000)
|
14
|
+
# @return [Array of NexosisApi::ViewDefinition]
|
15
|
+
# @raise [NexosisApi::HttpException]
|
16
|
+
def list_views(partial_name = '', dataset_name = '', page = 0, page_size = 50)
|
17
|
+
url = '/views'
|
18
|
+
query = {
|
19
|
+
'page': page,
|
20
|
+
'pageSize': page_size
|
21
|
+
}
|
22
|
+
query.store 'partialName', partial_name if partial_name.empty? == false
|
23
|
+
query.store 'dataSetName', dataset_name if dataset_name.empty? == false
|
24
|
+
response = self.class.get(url, headers: @headers, query: query)
|
25
|
+
if response.success?
|
26
|
+
items = []
|
27
|
+
response.parsed_response['items'].each do |definition|
|
28
|
+
items << NexosisApi::ViewDefinition.new(definition)
|
29
|
+
end
|
30
|
+
items
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create a new view or update an existing one by name
|
35
|
+
# @param view_name [String] the name of the view to create or update.
|
36
|
+
# @param dataset_name [String] the unique name of a data that is one source of this view.
|
37
|
+
# @param right_datasource_name [String] the additional data source to join in this view.
|
38
|
+
# @return [NexosisApi::ViewDefinition] - definition as created by API
|
39
|
+
# @note @view_name Must be unique within your organization
|
40
|
+
# @raise [NexosisApi::HttpException]
|
41
|
+
def create_view(view_name, dataset_name, right_datasource_name)
|
42
|
+
raise ArgumentError 'view_name was not provided and is not optional' unless view_name.to_s.empty? == false
|
43
|
+
raise ArgumentError 'dataset_name was not provided and is not optional' unless dataset_name.to_s.empty? == false
|
44
|
+
raise ArgumentError 'right_datasource_name was not provided and is not optional' unless right_datasource_name.to_s.empty? == false
|
45
|
+
view_definition = NexosisApi::ViewDefinition.new('viewName' => view_name)
|
46
|
+
view_definition.dataset_name = dataset_name
|
47
|
+
join = NexosisApi::Join.new('dataSet' => { 'name' => right_datasource_name })
|
48
|
+
view_definition.joins = [join]
|
49
|
+
create_view_by_def(view_definition)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create or update a view based on a view definition object
|
53
|
+
# @param view_definition [NexosisApi::ViewDefinition] an object populated with the view configuration to create
|
54
|
+
# @return [NexosisApi::ViewDefinition] - definition as created by API
|
55
|
+
# @raise [NexosisApi::HttpException]
|
56
|
+
def create_view_by_def(view_definition)
|
57
|
+
view_name = view_definition.view_name
|
58
|
+
raise ArgumentError 'view_name was not provided and is not optional' unless view_name.to_s.empty? == false
|
59
|
+
url = "/views/#{view_name}"
|
60
|
+
response = self.class.put(url, headers: @headers, body: view_definition.to_json)
|
61
|
+
if response.success?
|
62
|
+
return NexosisApi::ViewDefinition.new(response.parsed_response)
|
63
|
+
else
|
64
|
+
raise NexosisApi::HttpException.new('Could not create the requested view',
|
65
|
+
"Attempting to create view named #{view_name}",
|
66
|
+
response)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Deletes the named view and optionally all sessions created from it
|
71
|
+
# @param view_name [String] the view to remove
|
72
|
+
# @param cascade [String] indicate any non-nil to remove associated sessions
|
73
|
+
# @return [void]
|
74
|
+
# @raise [NexosisApi::HttpException]
|
75
|
+
def remove_view(view_name, cascade = nil)
|
76
|
+
raise ArgumentError 'view_name was not provided and is not optional' unless view_name.to_s.empty? == false
|
77
|
+
url = "/views/#{view_name}"
|
78
|
+
query = 'cascade=sessions' unless cascade.nil?
|
79
|
+
response = self.class.delete(url, headers: @headers, query: query)
|
80
|
+
unless response.success?
|
81
|
+
raise NexosisApi::HttpException.new('Could not delete view',
|
82
|
+
"Attempting to delete view #{view_name}",
|
83
|
+
response)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get the processed data from the view definition
|
88
|
+
#
|
89
|
+
# @param view_name [String] the unique name of the view for which to retrieve data
|
90
|
+
# @param page_number [Integer] zero-based page number of results to retrieve
|
91
|
+
# @param page_size [Integer] Count of results to retrieve in each page (max 1000).
|
92
|
+
# @param query_options [Hash] options hash for limiting and projecting returned results
|
93
|
+
# @note Query Options includes start_date as a DateTime or ISO 8601 compliant string,
|
94
|
+
# end_date, also as a DateTime or string, and :include as an Array of strings indicating the columns to return.
|
95
|
+
# The dates can be used independently and are inclusive. Lack of options returns all values within the given page.
|
96
|
+
# @note - the results include any transformations or imputations required to prepare the data for a session
|
97
|
+
# @raise [NexosisApi::HttpException]
|
98
|
+
def get_view(view_name, page_number = 0, page_size = 50, query_options = {})
|
99
|
+
raise ArgumentError 'view_name was not provided and is not optional' unless view_name.to_s.empty? == false
|
100
|
+
url = "/views/#{view_name}"
|
101
|
+
response = self.class.get(url, headers: @headers,
|
102
|
+
query: create_query(page_number, page_size, query_options),
|
103
|
+
query_string_normalizer: ->(query_map) { array_query_normalizer(query_map) } )
|
104
|
+
raise NexosisApi::HttpException.new('Could not retrieve data for the given view', "Requesting data for view #{view_name}", response) unless response.success?
|
105
|
+
NexosisApi::ViewData.new(response.parsed_response)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module NexosisApi
|
2
|
+
# class to hold the parsed results of column metadata
|
3
|
+
class Column
|
4
|
+
def initialize(column_name, value_hash)
|
5
|
+
@name = column_name
|
6
|
+
@type = NexosisApi::ColumnType.const_get(value_hash['dataType'].upcase) unless value_hash['dataType'].nil?
|
7
|
+
@role = NexosisApi::ColumnRole.const_get(value_hash['role'].upcase) unless value_hash['role'].nil?
|
8
|
+
@imputation = value_hash['imputation'] unless value_hash['imputation'].nil?
|
9
|
+
@aggregation = value_hash['aggregation'] unless value_hash['aggregation'].nil?
|
10
|
+
end
|
11
|
+
# The column header, label, or name
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :name
|
14
|
+
|
15
|
+
# The data type of this column
|
16
|
+
# @note Either string, numeric, logical, or date
|
17
|
+
# @return [NexosisApi::ColumnType]
|
18
|
+
attr_accessor :type
|
19
|
+
|
20
|
+
# The role of this column
|
21
|
+
# @note Either none, timestamp, target, or feature
|
22
|
+
# @return [NexosisApi::ColumnRole]
|
23
|
+
attr_accessor :role
|
24
|
+
|
25
|
+
# The strategy used to imput missing values
|
26
|
+
# @note Either Zeroes, Mean, Median, or Mode
|
27
|
+
# @return [String]
|
28
|
+
attr_accessor :imputation
|
29
|
+
|
30
|
+
# The strategy used to aggregate data if requested prediction period is greater than observation period
|
31
|
+
# @note Either Sum, Mean, Median, or Mode
|
32
|
+
# @return [String]
|
33
|
+
attr_accessor :aggregation
|
34
|
+
|
35
|
+
# utility method to format a column description in the way it is expected on input
|
36
|
+
def to_hash
|
37
|
+
{ name => { 'dataType' => type.to_s,
|
38
|
+
'role' => role.to_s,
|
39
|
+
'imputation' => imputation.to_s,
|
40
|
+
'aggregation' => aggregation.to_s } }
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.to_json(column_array)
|
44
|
+
result = {}
|
45
|
+
column_array.each { |col| result[col.to_hash.keys[0]] = col.to_hash.values[0] }
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module NexosisApi
|
2
|
+
# Class for holding the join options on a column in a view-based join
|
3
|
+
# @since v1.2
|
4
|
+
class ColumnOptions
|
5
|
+
# Create a new option for a join column.
|
6
|
+
# @param column_name [String] the name of the original column from the source dataset
|
7
|
+
# @param options_hash [Hash] additional information about how to process the column in a join
|
8
|
+
def initialize(column_name, options_hash)
|
9
|
+
@name = column_name
|
10
|
+
@join_interval = NexosisApi::TimeInterval.const_get(options_hash['joinInterval'].upcase) unless options_hash['joinInterval'].nil?
|
11
|
+
@alias = options_hash['alias']
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :name
|
15
|
+
|
16
|
+
# Optional interval of a time series column being joined to another time series
|
17
|
+
# @note not valid outside of join defintion
|
18
|
+
# @return [NexosisApi::TimeInterval]
|
19
|
+
attr_accessor :join_interval
|
20
|
+
|
21
|
+
# Optional alias of the column when participating in a join
|
22
|
+
# @note An alias can be used to keep two same-named columns distinct
|
23
|
+
# or to merge two distinctly named columns. By default same-named columns
|
24
|
+
# on two sides of a join will be merged.
|
25
|
+
# @return [String]
|
26
|
+
attr_accessor :alias
|
27
|
+
|
28
|
+
def to_hash
|
29
|
+
{ name => { 'join_interval' => @join_internal.to_s,
|
30
|
+
'alias' => @alias.to_s } }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
module NexosisApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module NexosisApi
|
2
|
+
# Constants for dataset column role
|
3
|
+
module ColumnRole
|
4
|
+
# No specific role, additional data which could be identified as target in a session
|
5
|
+
NONE = :none
|
6
|
+
|
7
|
+
# The timestamp column to use as the basis for a time-series session request
|
8
|
+
TIMESTAMP = :timestamp
|
9
|
+
|
10
|
+
# The target column for which to make predictions
|
11
|
+
TARGET = :target
|
12
|
+
|
13
|
+
# A feature to be included in analysis
|
14
|
+
FEATURE = :feature
|
15
|
+
end
|
13
16
|
end
|
@@ -1,15 +1,19 @@
|
|
1
|
-
module NexosisApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
1
|
+
module NexosisApi
|
2
|
+
# Constants for column data type
|
3
|
+
module ColumnType
|
4
|
+
# contains string data
|
5
|
+
STRING = :string
|
6
|
+
|
7
|
+
# contains numeric data
|
8
|
+
NUMERIC = :numeric
|
9
|
+
|
10
|
+
# contains boolean logical data (i.e. 1 and 0, true and false, etc.)
|
11
|
+
LOGICAL = :logical
|
12
|
+
|
13
|
+
# contains ISO-8601 compatible date
|
14
|
+
DATE = :date
|
15
|
+
|
16
|
+
# Indicates a number which is not countable, or is not 'ordinal scaled' but 'ratio' or 'interval' scaled - i.e. a device measurement
|
17
|
+
NUMERICMEASURE = :numericmeasure
|
18
|
+
end
|
19
|
+
end
|
@@ -1,24 +1,24 @@
|
|
1
|
-
module NexosisApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
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
|
@@ -1,26 +1,26 @@
|
|
1
|
-
module NexosisApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
1
|
+
module NexosisApi
|
2
|
+
# Class to parse the model results calculated for a dataset
|
3
|
+
class DatasetModel
|
4
|
+
def initialize(data_hash)
|
5
|
+
data_hash.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
|
@@ -1,27 +1,27 @@
|
|
1
|
-
module NexosisApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
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
|
+
elsif(k == 'columns')
|
9
|
+
columns = []
|
10
|
+
next if v.nil?
|
11
|
+
v.keys.each do |col_key|
|
12
|
+
columns << NexosisApi::Column.new(col_key, v[col_key])
|
13
|
+
end
|
14
|
+
@column_metadata = columns
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# The name of the dataset uploaded and saved
|
20
|
+
# @return [String]
|
21
|
+
attr_accessor :dataset_name
|
22
|
+
|
23
|
+
# Descriptive information about the columns
|
24
|
+
# @return [Array of NexosisApi::Column]
|
25
|
+
attr_accessor :column_metadata
|
26
|
+
end
|
27
|
+
end
|
@@ -1,25 +1,29 @@
|
|
1
|
-
module NexosisApi
|
2
|
-
# encapsulate errors from the Nexosis API
|
3
|
-
class HttpException < StandardError
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
+
base_message = message
|
7
|
+
full_message = nil
|
8
|
+
if(http_obj.is_a?(Hash))
|
9
|
+
base_message.prepend(http_obj['message'].concat(': ')) unless http_obj['message'].nil?
|
10
|
+
@action = action
|
11
|
+
elsif(http_obj.instance_of?(HTTParty::Response))
|
12
|
+
full_message = http_obj.parsed_response['message']
|
13
|
+
full_message = full_message.concat(' || Details: ').concat(http_obj.parsed_response['errorDetails'].to_s) unless http_obj.parsed_response['errorDetails'].nil?
|
14
|
+
@type = http_obj.parsed_response['errorType']
|
15
|
+
@response = http_obj.response
|
16
|
+
@request = http_obj.request
|
17
|
+
@code = http_obj.code
|
18
|
+
end
|
19
|
+
full_message ||= base_message
|
20
|
+
@message = full_message
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :code
|
24
|
+
attr_reader :response
|
25
|
+
attr_reader :request
|
26
|
+
attr_reader :message
|
27
|
+
attr_reader :type
|
28
|
+
end
|
25
29
|
end
|