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 +7 -0
- data/lib/nexosis_api.rb +12 -0
- data/lib/nexosis_api/algorithm.rb +18 -0
- data/lib/nexosis_api/algorithm_run.rb +32 -0
- data/lib/nexosis_api/algorithm_selection.rb +34 -0
- data/lib/nexosis_api/client.rb +65 -0
- data/lib/nexosis_api/client/datasets.rb +165 -0
- data/lib/nexosis_api/client/sessions.rb +226 -0
- data/lib/nexosis_api/dataset_data.rb +24 -0
- data/lib/nexosis_api/dataset_model.rb +26 -0
- data/lib/nexosis_api/dataset_summary.rb +15 -0
- data/lib/nexosis_api/http_exception.rb +28 -0
- data/lib/nexosis_api/impact_metric.rb +22 -0
- data/lib/nexosis_api/link.rb +18 -0
- data/lib/nexosis_api/metric.rb +22 -0
- data/lib/nexosis_api/session.rb +63 -0
- data/lib/nexosis_api/session_response.rb +26 -0
- data/lib/nexosis_api/session_result.rb +23 -0
- data/nexosisapi.gemspec +21 -0
- metadata +91 -0
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
|
data/lib/nexosis_api.rb
ADDED
@@ -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
|
data/nexosisapi.gemspec
ADDED
@@ -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: []
|