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.
@@ -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
- # 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
- # The timestamp column to use as the basis for a time-series session request
7
- TIMESTAMP = :timestamp
8
- # The target column for which to make predictions
9
- TARGET = :target
10
- # A feature to be included in analysis
11
- FEATURE = :feature
12
- end
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
- # Constants for column data type
3
- module ColumnType
4
- # contains string data
5
- STRING = :string
6
- # contains numeric data
7
- NUMERIC = :numeric
8
- # contains boolean logical data (i.e. 1 and 0, true and false, etc.)
9
- LOGICAL = :logical
10
- # contains ISO-8601 compatible date
11
- DATE = :date
12
- # Indicates a number which is not countable, or is not 'ordinal scaled' but 'ratio' or 'interval' scaled - i.e. a device measurement
13
- NUMERICMEASURE = :numericmeasure
14
- end
15
- end
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
- # 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
+ 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
- # 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
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
- # 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::DatasetColumn.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::DatasetColumn]
25
- attr_accessor :column_metadata
26
- end
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
- 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
- elsif(http_obj.instance_of?(HTTParty::Response))
11
- @message = message.concat("|| Explanation: ").concat(http_obj.parsed_response["errorDetails"].to_s) unless http_obj.parsed_response["errorDetails"].nil?
12
- @type = http_obj.parsed_response["errorType"]
13
- @response = http_obj.response
14
- @request = http_obj.request
15
- @code = http_obj.code
16
- end
17
- end
18
-
19
- attr_reader :code
20
- attr_reader :response
21
- attr_reader :request
22
- attr_reader :message
23
- attr_reader :type
24
- end
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