module Datarobot::AiApi
Public Class Methods
Adds default headers to a net http request @param [Net::HTTP::*] request The net/http request to add the headers to @param [Hash] additional_headers Will overwrite defaults @return [Net::Http::*] returns an aribitrary request type (GET/POST/etc.)
# File lib/datarobot/ai_api.rb, line 43 def self.add_headers(request, additional_headers={}) request["User-Agent"] = "datarobot-ai/ruby" request["Content-Type"] = "application/json" request["Authorization"] = "Bearer #{@@api_key}" additional_headers.each do |k, v| request[k] = v end request end
# File lib/datarobot/ai_api.rb, line 15 def self.api_key; @@api_key end
# File lib/datarobot/ai_api.rb, line 16 def self.api_key= v; @@api_key = v end
Sets global API key @param [String] api_key
The api key to use for authentication @return [Datarobot::AiApi]
# File lib/datarobot/ai_api.rb, line 21 def self.configure!(api_key: '', base_url: nil) @@api_key = api_key @@base_url = base_url if base_url self end
Creates an AI
@param [String] name The ID of the AI
to retrieve
@return [Datarobot::AiApi::AI]
# File lib/datarobot/ai_api/ai.rb, line 44 def self.create(name: 'New AI') Datarobot::AiApi.request_endpoint('/aiapi/ais/', method: 'post', body: { name: name }) do |data| ai_data = Datarobot::AiApi.get(data["links"]["result"]) new(ai_data) end end
Deletes an AI
. Returns `nil` if the action was successful. Will raise an error if the action was unsuccessful
@param [String] id The ID of the AI
to delete
@return [nil]
# File lib/datarobot/ai_api/ai.rb, line 57 def self.delete(id) Datarobot::AiApi.request_endpoint("/aiapi/ais/#{id}", method: "delete") end
Uses request data to determin error classes Only raises values. Will never return
# File lib/datarobot/ai_api.rb, line 146 def self.determine_error(response_obj) parsed = JSON.parse(response_obj.body) msg = parsed["error"] || parsed["message"] case response_obj.code when "403" raise Datarobot::AiApi::UnauthorizedError, msg when "404" raise Datarobot::AiApi::NotFoundError, msg else raise Datarobot::AiApi::ApiError, msg end end
Given an arbitrary url, return the correct AiApi
object @param [String] url @return [Datarobot::AiApi::*]
# File lib/datarobot/ai_api.rb, line 162 def self.determine_object(url) case url when /\/ais/ Datarobot::AiApi::AI when /\/datasets/ Datarobot::AiApi::Dataset when /\/learningSessions/ Datarobot::AiApi::LearningSession when /\/outputs/ Datarobot::AiApi::Output when /\/status/ Datarobot::AiApi::Task when /\/deployment/ Datarobot::AiApi::Deployment end end
Retrieves an AI
given an ID.
@param [String] id The ID of the AI
to retrieve
@return [Datarobot::AiApi::AI]
# File lib/datarobot/ai_api/ai.rb, line 28 def self.find(id, &block) raise Datarobot::AiApi::NotFoundError, "Cannot find AI with id: nil" if id.nil? Datarobot::AiApi.request_endpoint("/aiapi/ais/#{id}") do |data| if block_given? yield data else self.new(data) end end end
Gets a bare uri. Useful for requests with `result` objects @param [String] bare_uri @param [Block] block passed to `handle_response`
# File lib/datarobot/ai_api.rb, line 72 def self.get(bare_uri, &block) with_https(bare_uri) do |uri, http| request = Net::HTTP::Get.new(uri) request = add_headers(request) response = http.request(request) handle_response(response, &block) end end
Common error handling and response parsing @yield [data] Yields the parsed json response if there is one @return nil if body is empty @return [Hash] data Parsed json response if no block is provided
# File lib/datarobot/ai_api.rb, line 101 def self.handle_response(response, &block) if response.code.to_i < 300 return nil if response.body.to_s.empty? data = JSON.parse(response.body) if block_given? yield data else data end else determine_error(response) end end
Given a parsed response body from the API, will create a new AI
object
# File lib/datarobot/ai_api/ai.rb, line 62 def initialize(options = {}) # Suppresses warnings about uninitialized variables @id = nil @name = nil @dataset_count = nil @output_count = nil @learning_session_count = nil set_from_options(options) @outputs = nil end
Checks the `ping` endpoint. Useful for debugging @return [Hash]
# File lib/datarobot/ai_api.rb, line 29 def self.ping request_endpoint('/aiapi/ping') end
Checks the `ping/me` endpoint. Useful for debugging authentication @return [Hash]
# File lib/datarobot/ai_api.rb, line 35 def self.ping_me request_endpoint('/aiapi/ping/me') end
Makes a request to the given endpoint @param [String] endpoint The url path to the endpoint @param [String] method The HTTP method to make the request with @param [Hash] body JSON body. Only used in put and post requests @param [Hash] headers Additional headers to add to request @param [Hash] params Additoinal url parameters to add @return Delegates return values to `handle_response`
# File lib/datarobot/ai_api.rb, line 122 def self.request_endpoint(endpoint, method: 'get', body: {}, headers: {}, params: {}, &block) uri_str = "#{@@base_url}#{endpoint}" with_https(uri_str, params) do |uri, http| case method.downcase when 'put' request = Net::HTTP::Put.new(uri.request_uri) request.body = JSON.dump(body) when 'delete' request = Net::HTTP::Delete.new(uri.request_uri) when 'post' request = Net::HTTP::Post.new(uri.request_uri) request.body = JSON.dump(body) else request = Net::HTTP::Get.new(uri) end request = add_headers(request, headers) response = http.request(request) handle_response(response, &block) end end
Converts a file into an octet stream, and uploads it to given endpoint @param [String] endpoint The endpoint to upload the file to @param [String] file_path Path to local file for upload @return Delegates return values to `handle_response`
# File lib/datarobot/ai_api.rb, line 86 def self.upload_to_endpoint(endpoint, file_path, &block) uri = "#{@@base_url}#{endpoint}" with_https(uri) do |uri, http| request = Net::HTTP::Post::Multipart.new uri.request_uri, "file" => UploadIO.new(file_path, "application/octet-stream") request["User-Agent"] = "datarobot-ai/ruby" request["Authorization"] = "Bearer #{@@api_key}" response = http.request(request) handle_response(response, &block) end end
Make a request with https. This is a helper method to avoid having to write net/http boilerplate @param [String] uri The uri to make the request to @param [Hash] params Additoinal params to add to the request. Will overwrite params in the query string of the given uri
@yield [uri, http] Yields the https request with the parsed uri and http object
# File lib/datarobot/ai_api.rb, line 60 def self.with_https(uri, params={}) uri = URI.parse(uri) existing_params = CGI::parse(uri.query.to_s) uri.query = URI.encode_www_form(existing_params.merge params) Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http| yield uri, http end end
Public Instance Methods
Adds a dataset to the AI
. Raises an error on failure. Returns true on success
@param [String] dataset_id The ID of the dataset to add @return [Bool] true
# File lib/datarobot/ai_api/ai.rb, line 140 def add_dataset(dataset_id) Datarobot::AiApi.request_endpoint("/aiapi/ais/#{@id}/datasets", method: 'post', body: { datasetId: dataset_id }) true end
Adds a learning session to the AI
. Raises an error on failure. Returns true on success
@param [String] session_id The ID of the learning session to add @return [Bool] true
# File lib/datarobot/ai_api/ai.rb, line 150 def add_learning_session(session_id) Datarobot::AiApi.request_endpoint("/aiapi/ais/#{@id}/learningSessions", method: 'post', body: { learningSessionId: session_id }) true end
Lists all the datasets associated with the AI
as a paginated resource
@return [Datarobot::AiApi::Page(Datarobot::AiApi::Dataset
)]
# File lib/datarobot/ai_api/ai.rb, line 103 def datasets Datarobot::AiApi.request_endpoint("/aiapi/datasets?aiId=#{@id}") do |data| data["aiId"] = @id Datarobot::AiApi::Page.new(Datarobot::AiApi::Dataset, data) end end
Finds an output by name
@param [String] name The name of the output associated with this AI
that you want to find @return [Datarobot::AiApi::Output]
# File lib/datarobot/ai_api/ai.rb, line 115 def find_output(name) # TODO: Update this when AI API supports CGI escaped URIs # # This code was lifted from source of erb method: # https://apidock.com/ruby/v2_6_3/ERB/Util/url_encode # # URI.escape is deprecated because it does not encode url control # characters, thus making it a potential security issue and CGI.escape # substitutes whitespace with a + which is correct, but unsupported by # the AI API encoded_name = name.gsub(/[^a-zA-Z0-9_\-.~]/) { |m| sprintf("%%%02X", m.unpack1("C")) } Datarobot::AiApi.request_endpoint("/aiapi/ais/#{@id}/outputs/#{encoded_name}") do |data| data["aiId"] = @id Datarobot::AiApi::Output.new(data) end end
Lists all the outputs associated with the AI
as a paginated resource
@return [Datarobot::AiApi::Page(Datarobot::AiApi::Output
)]
# File lib/datarobot/ai_api/ai.rb, line 93 def outputs Datarobot::AiApi.request_endpoint("/aiapi/ais/#{@id}/outputs") do |data| data["aiId"] = @id Datarobot::AiApi::Page.new(Datarobot::AiApi::Output, data) end end
Predicts a target feature given a data hash
@param target The target feature to predict @param data The remaining features used to predict target feature
# File lib/datarobot/ai_api/ai.rb, line 173 def predict(target, data={}) output = outputs.find { |o| o.target == target } raise NotFoundError, "No output with target #{target.inspect} found AI with ID #{@id.inspect}" if output.nil? deployment_id = output.source["deploymentId"] key = output.source["datarobot-key"] Datarobot::AiApi.request_endpoint( "/predApi/v1.0/deployments/#{deployment_id}/predictions/", method: 'post', body: [ data ], headers: {"datarobot-key" => key} ) do |data| Datarobot::AiApi::Page.new(Datarobot::AiApi::Prediction, data) end end
Takes a response body from the API. Will set all AI
attributes from the response body
@param [Hash] options A parsed response body @return [void]
# File lib/datarobot/ai_api/ai.rb, line 79 def set_from_options(options = {}) # one-liner replacement for `stringify_keys` options = options.collect{|k,v| [k.to_s, v]}.to_h @output_count = options.dig("outputCount") || @output_count @dataset_count = options.dig("datasetCount") || @dataset_count @learning_session_count = options.dig("learningSessionCount") || @learning_session_count @name = options.dig("name") || @name @id = options.dig("id") || @id end
Trains an AI
on the given target with the data in the file at the given path. Returns true if successful. Raises an error otherwise
@param [String] target The target to train the AI
on @return [Bool] true
# File lib/datarobot/ai_api/ai.rb, line 160 def train(target, file_path) dataset = Datarobot::AiApi::Dataset.create_from_file(file_path) add_dataset(dataset.id) learning_session = Datarobot::AiApi::LearningSession.create(dataset_id: dataset.id, target: target) add_learning_session(learning_session.id) Datarobot::AiApi::Output.create(ai_id: @id, learning_session_id: learning_session.id, output_name: "#{@name} output") true end