chalk_ruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/CODEOWNERS +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +13 -0
- data/.gitignore +38 -0
- data/.rubocop.yml +185 -0
- data/.rubocop_todo.yml +14 -0
- data/Gemfile +18 -0
- data/LICENSE +201 -0
- data/README.md +25 -0
- data/Rakefile +35 -0
- data/SECURITY.md +17 -0
- data/Steepfile +6 -0
- data/bin/console +21 -0
- data/bin/setup +8 -0
- data/chalk_ruby.gemspec +50 -0
- data/lib/chalk_ruby/client.rb +192 -0
- data/lib/chalk_ruby/config/config.rb +39 -0
- data/lib/chalk_ruby/defaults.rb +36 -0
- data/lib/chalk_ruby/error.rb +22 -0
- data/lib/chalk_ruby/helpers.rb +45 -0
- data/lib/chalk_ruby/http/http_requester.rb +94 -0
- data/lib/chalk_ruby/http/response.rb +23 -0
- data/lib/chalk_ruby/logger_helper.rb +14 -0
- data/lib/chalk_ruby/transport/transport.rb +54 -0
- data/lib/chalk_ruby/version.rb +3 -0
- data/lib/chalk_ruby.rb +13 -0
- data/renovate.json +5 -0
- data/sig/chalk_ruby/client.rbs +43 -0
- data/sig/chalk_ruby/config/config.rbs +31 -0
- data/sig/chalk_ruby/defaults.rbs +35 -0
- data/sig/chalk_ruby/error.rbs +6 -0
- data/sig/chalk_ruby/helpers.rbs +15 -0
- data/sig/chalk_ruby/http/http_requester.rbs +25 -0
- data/sig/chalk_ruby/http/response.rbs +14 -0
- data/sig/chalk_ruby/interfaces/_connection.rbs +17 -0
- data/sig/chalk_ruby/token.rbs +10 -0
- data/sig/chalk_ruby/transport/transport.rbs +21 -0
- data/sig/chalk_ruby/versions.rbs +3 -0
- data/test/chalk_ai/integration/client_test.rb +20 -0
- data/test/chalk_ai/test_helper.rb +15 -0
- metadata +268 -0
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'chalk_ruby/config/config'
|
2
|
+
require 'chalk_ruby/logger_helper'
|
3
|
+
require 'chalk_ruby/transport/transport'
|
4
|
+
require 'chalk_ruby/http/response'
|
5
|
+
|
6
|
+
module ChalkRuby
|
7
|
+
class Token
|
8
|
+
attr_accessor :token, :expires_at, :environment, :engines
|
9
|
+
|
10
|
+
# @param [Hash[String, untyped]] exchange_credentials_response
|
11
|
+
def initialize(exchange_credentials_response)
|
12
|
+
@token = exchange_credentials_response[:access_token]
|
13
|
+
@expires_at = DateTime.parse(exchange_credentials_response[:expires_at])
|
14
|
+
@environment = exchange_credentials_response[:primary_environment]
|
15
|
+
@engines = exchange_credentials_response[:engines]
|
16
|
+
end
|
17
|
+
|
18
|
+
def expired?
|
19
|
+
DateTime.now.advance({ seconds: 60 }) > @expires_at
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Client
|
24
|
+
# Initializes the Personalization client
|
25
|
+
#
|
26
|
+
# @param chalk_config [ChalkRuby::Config] a ChalkRuby::Config object which contains your APP_ID and API_KEY
|
27
|
+
# @option adapter [Object] adapter object used for the connection
|
28
|
+
# @option logger [Object]
|
29
|
+
# @option http_requester [Object] http_requester object used for the connection
|
30
|
+
#
|
31
|
+
def initialize(chalk_config, opts = {})
|
32
|
+
@token = nil
|
33
|
+
@config = chalk_config
|
34
|
+
adapter = opts[:adapter] || Defaults::ADAPTER
|
35
|
+
logger = opts[:logger] || LoggerHelper.create
|
36
|
+
requester = opts[:http_requester] || Defaults::REQUESTER_CLASS.new(adapter: adapter, logger: logger)
|
37
|
+
@transporter = Transport::Transport.new(requester: requester)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Create a new client providing only app ID and API key
|
41
|
+
#
|
42
|
+
# @param client_id [String] ChalkRuby application ID
|
43
|
+
# @param client_secret [String] ChalkRuby API key
|
44
|
+
# @param environment [String] ChalkRuby environment
|
45
|
+
# @param query_server [String] ChalkRuby query server
|
46
|
+
# @param api_server [String] ChalkRuby API server
|
47
|
+
#
|
48
|
+
# @return self
|
49
|
+
#
|
50
|
+
def self.create(
|
51
|
+
client_id,
|
52
|
+
client_secret,
|
53
|
+
environment = nil,
|
54
|
+
query_server = nil,
|
55
|
+
api_server = nil
|
56
|
+
)
|
57
|
+
config = Config.new(
|
58
|
+
client_id: client_id,
|
59
|
+
client_secret: client_secret,
|
60
|
+
environment: environment,
|
61
|
+
query_server: query_server,
|
62
|
+
api_server: api_server
|
63
|
+
)
|
64
|
+
create_with_config(config)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Create a new client providing only a ChalkRuby::Config object
|
68
|
+
#
|
69
|
+
# @param config [ChalkRuby::Config]
|
70
|
+
#
|
71
|
+
# @return self
|
72
|
+
#
|
73
|
+
def self.create_with_config(config)
|
74
|
+
new(config)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Compute features values using online resolvers.
|
78
|
+
# See https://docs.chalk.ai/docs/query-basics for more information.
|
79
|
+
#
|
80
|
+
# @param input [Hash[String, any]] The features for which there are known values, mapped to those values.
|
81
|
+
#
|
82
|
+
# @param output [[String]] Outputs are the features that you'd like to compute from the inputs.
|
83
|
+
# For example, `['user.age', 'user.name', 'user.email']`.
|
84
|
+
#
|
85
|
+
# If an empty sequence, the output will be set to all features on the namespace
|
86
|
+
# of the query. For example, if you pass as input `{"user.id": 1234}`, then the query
|
87
|
+
# is defined on the `User` namespace, and all features on the `User` namespace
|
88
|
+
# (excluding has-one and has-many relationships) will be used as outputs.
|
89
|
+
#
|
90
|
+
#
|
91
|
+
# @return [Hash[Symbol, String]]
|
92
|
+
#
|
93
|
+
def query(
|
94
|
+
input:,
|
95
|
+
output:,
|
96
|
+
# now,
|
97
|
+
opts: {}
|
98
|
+
# _staleness
|
99
|
+
)
|
100
|
+
query_server_request(
|
101
|
+
method: :post,
|
102
|
+
path: 'v1/query/online',
|
103
|
+
body: {
|
104
|
+
inputs: input,
|
105
|
+
outputs: output
|
106
|
+
# now: now
|
107
|
+
},
|
108
|
+
headers: get_authenticated_headers
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_token
|
113
|
+
response = api_server_request(
|
114
|
+
method: :post,
|
115
|
+
path: '/v1/oauth/token',
|
116
|
+
body: {
|
117
|
+
client_id: @config.client_id,
|
118
|
+
client_secret: @config.client_secret,
|
119
|
+
grant_type: 'client_credentials'
|
120
|
+
},
|
121
|
+
headers: get_unauthenticated_headers
|
122
|
+
)
|
123
|
+
Token.new(response)
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def api_server_request(method:, path:, body:, headers:)
|
129
|
+
@transporter.request_simple(
|
130
|
+
method: method,
|
131
|
+
host: @config.api_server,
|
132
|
+
path: path,
|
133
|
+
timeout: @config.api_timeout,
|
134
|
+
connect_timeout: @config.connect_timeout,
|
135
|
+
body: body,
|
136
|
+
headers: headers
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
def query_server_request(method:, path:, body:, headers:)
|
141
|
+
@transporter.request_simple(
|
142
|
+
method: method,
|
143
|
+
host: query_server_host,
|
144
|
+
path: path,
|
145
|
+
timeout: @config.query_timeout,
|
146
|
+
connect_timeout: @config.connect_timeout,
|
147
|
+
body: body,
|
148
|
+
headers: headers
|
149
|
+
)
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_authenticated_headers
|
153
|
+
t = valid_token
|
154
|
+
{
|
155
|
+
'Content-Type': 'application/json',
|
156
|
+
'Accept': 'application/json',
|
157
|
+
'Authorization': 'Bearer ' + t.token,
|
158
|
+
'X-ChalkRuby-Environment': @config.environment || t.environment
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_unauthenticated_headers
|
163
|
+
{
|
164
|
+
'Content-Type': 'application/json',
|
165
|
+
'Accept': 'application/json',
|
166
|
+
'X-ChalkRuby-Environment': @config.environment
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
def query_server_host
|
171
|
+
explicit = @config.query_server
|
172
|
+
if explicit.nil?
|
173
|
+
tok = valid_token
|
174
|
+
found = @config.environment || tok.environment
|
175
|
+
found.nil? ? Defaults::QUERY_SERVER : tok.engines[found] || Defaults::QUERY_SERVER
|
176
|
+
else
|
177
|
+
explicit
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def valid_token
|
182
|
+
if @token.nil? || @token.expired?
|
183
|
+
t = get_token
|
184
|
+
@token = t
|
185
|
+
t
|
186
|
+
else
|
187
|
+
@token
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'chalk_ruby/defaults'
|
3
|
+
|
4
|
+
module ChalkRuby
|
5
|
+
class Config
|
6
|
+
attr_accessor :client_id,
|
7
|
+
:client_secret,
|
8
|
+
:query_server,
|
9
|
+
:api_server,
|
10
|
+
:environment,
|
11
|
+
:query_timeout,
|
12
|
+
:api_timeout,
|
13
|
+
:connect_timeout
|
14
|
+
|
15
|
+
#
|
16
|
+
# @option options [String] :client_id
|
17
|
+
# @option options [String] :client_secret
|
18
|
+
# @option options [String] :query_host
|
19
|
+
# @option options [String] :api_host
|
20
|
+
# @option options [Integer] :read_timeout
|
21
|
+
# @option options [Integer] :write_timeout
|
22
|
+
# @option options [Integer] :connect_timeout
|
23
|
+
#
|
24
|
+
def initialize(opts = {})
|
25
|
+
@client_id = opts[:client_id] || ENV['CHALK_CLIENT_ID']
|
26
|
+
@client_secret = opts[:client_secret] || ENV['CHALK_CLIENT_SECRET']
|
27
|
+
@environment = opts[:environment] || ENV['CHALK_ACTIVE_ENVIRONMENT']
|
28
|
+
@query_server = opts[:query_server] || ENV['CHALK_QUERY_SERVER'] || Defaults::QUERY_SERVER
|
29
|
+
@api_server = opts[:api_server] || ENV['CHALK_API_SERVER'] || Defaults::API_SERVER
|
30
|
+
@query_timeout = opts[:query_timeout] || Defaults::API_TIMEOUT
|
31
|
+
@api_timeout = opts[:api_timeout] || Defaults::QUERY_TIMEOUT
|
32
|
+
@connect_timeout = opts[:connect_timeout] || Defaults::CONNECT_TIMEOUT
|
33
|
+
|
34
|
+
raise ChalkError, 'No Client ID provided, please set :client_id' if @client_id.nil?
|
35
|
+
raise ChalkError, 'No Client Secret provided, please set :client_secret' if @client_secret.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'chalk_ruby/http/http_requester'
|
2
|
+
|
3
|
+
module ChalkRuby
|
4
|
+
module Defaults
|
5
|
+
REQUESTER_CLASS = ChalkRuby::Http::HttpRequester
|
6
|
+
ADAPTER = 'net_http_persistent'
|
7
|
+
|
8
|
+
# HTTP Headers
|
9
|
+
# ----------------------------------------
|
10
|
+
HEADER_CLIENT_ID = 'X-ChalkRuby-Client-Id'.freeze
|
11
|
+
HEADER_CLIENT_SECRET = 'X-ChalkRuby-Client-Secret'.freeze
|
12
|
+
HEADER_ENVIRONMENT = 'X-ChalkRuby-Env-Id'.freeze
|
13
|
+
AUTHORIZATION_HEADER = 'Authorization'.freeze
|
14
|
+
USER_AGENT = "ChalkRuby Ruby (#{ChalkRuby::VERSION}), Ruby (#{RUBY_VERSION})"
|
15
|
+
|
16
|
+
# API Servers
|
17
|
+
# ----------------------------------------
|
18
|
+
QUERY_SERVER = 'https://api.prod.chalk.ai'.freeze
|
19
|
+
API_SERVER = 'https://api.prod.chalk.ai'.freeze
|
20
|
+
|
21
|
+
# HTTP ERROR CODES
|
22
|
+
# ----------------------------------------
|
23
|
+
ERROR_BAD_REQUEST = 400
|
24
|
+
ERROR_FORBIDDEN = 403
|
25
|
+
ERROR_NOT_FOUND = 404
|
26
|
+
ERROR_TIMED_OUT = 408
|
27
|
+
|
28
|
+
# HTTP TIMEOUTS
|
29
|
+
# ----------------------------------------
|
30
|
+
CONNECT_TIMEOUT = 2
|
31
|
+
API_TIMEOUT = 10
|
32
|
+
QUERY_TIMEOUT = 120
|
33
|
+
|
34
|
+
WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY = 100
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ChalkRuby
|
2
|
+
# Base exception class for errors thrown by the ChalkRuby
|
3
|
+
# client library. ChalkError will be raised by any
|
4
|
+
# network operation if ChalkRuby.init() has not been called.
|
5
|
+
#
|
6
|
+
class ChalkError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
# An exception class raised when the REST API returns an error.
|
10
|
+
# The error code and message will be parsed out of the HTTP response,
|
11
|
+
# which is also included in the response attribute.
|
12
|
+
#
|
13
|
+
class ChalkHttpError < ChalkError
|
14
|
+
attr_accessor :code, :message
|
15
|
+
|
16
|
+
def initialize(code:, message:)
|
17
|
+
self.code = code
|
18
|
+
self.message = message
|
19
|
+
super("#{self.code}: #{self.message}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
module ChalkRuby
|
4
|
+
module Helpers
|
5
|
+
# Convert an Hash to json
|
6
|
+
#
|
7
|
+
def to_json(body:)
|
8
|
+
body.is_a?(String) ? body : MultiJson.dump(body)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Converts each key of a hash to symbols
|
12
|
+
#
|
13
|
+
def symbolize_hash(hash:)
|
14
|
+
hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convert a json object to an hash
|
18
|
+
#
|
19
|
+
def json_to_hash(json:, symbolize_keys:)
|
20
|
+
MultiJson.load(json, symbolize_keys: symbolize_keys)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Retrieve the given value associated with a key, in string or symbol format
|
24
|
+
#
|
25
|
+
def get_option(hash:, key:)
|
26
|
+
hash[key.to_sym] || hash[key] || nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# Build a path with the given arguments
|
30
|
+
#
|
31
|
+
def path_encode(path, *args)
|
32
|
+
arguments = []
|
33
|
+
args.each do |arg|
|
34
|
+
arguments.push(CGI.escape(arg.to_s))
|
35
|
+
end
|
36
|
+
|
37
|
+
format(path, *arguments)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.included(base)
|
41
|
+
base.extend(Helpers)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'chalk_ruby/helpers'
|
2
|
+
require 'chalk_ruby/http/response'
|
3
|
+
|
4
|
+
module ChalkRuby
|
5
|
+
module Http
|
6
|
+
class HttpRequester
|
7
|
+
include Helpers
|
8
|
+
attr_accessor :adapter, :logger
|
9
|
+
|
10
|
+
#
|
11
|
+
# @param adapter [Net::Http] adapter used to make requests. Defaults to Net::Http
|
12
|
+
# @param logger [Logger] logger used to log requests. Defaults to ChalkRuby::LoggerHelper
|
13
|
+
#
|
14
|
+
def initialize(adapter:, logger:)
|
15
|
+
@adapter = adapter
|
16
|
+
@logger = logger
|
17
|
+
@connections = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Sends a request
|
21
|
+
#
|
22
|
+
# @param host [String]
|
23
|
+
# @param method [Symbol]
|
24
|
+
# @param path [String]
|
25
|
+
# @param body [String]
|
26
|
+
# @param headers [Hash]
|
27
|
+
# @param timeout [Integer]
|
28
|
+
# @param connect_timeout [Integer]
|
29
|
+
#
|
30
|
+
# @return [Http::Response]
|
31
|
+
#
|
32
|
+
def send_request(
|
33
|
+
host:,
|
34
|
+
method:,
|
35
|
+
path:,
|
36
|
+
body:,
|
37
|
+
headers:,
|
38
|
+
timeout:,
|
39
|
+
connect_timeout:
|
40
|
+
)
|
41
|
+
connection = connection(host)
|
42
|
+
connection.options.timeout = timeout
|
43
|
+
connection.options.open_timeout = connect_timeout
|
44
|
+
|
45
|
+
if ENV['CHALK_DEBUG']
|
46
|
+
@logger.info("Sending #{method.to_s.upcase!} request to #{path} with body #{body}")
|
47
|
+
end
|
48
|
+
|
49
|
+
response = connection.run_request(
|
50
|
+
method,
|
51
|
+
path,
|
52
|
+
body,
|
53
|
+
headers
|
54
|
+
)
|
55
|
+
|
56
|
+
if response.success?
|
57
|
+
if ENV['CHALK_DEBUG']
|
58
|
+
@logger.info("Request succeeded. Response status: #{response.status}, body: #{response.body}")
|
59
|
+
end
|
60
|
+
return Http::Response.new(status: response.status, body: response.body, headers: response.headers)
|
61
|
+
end
|
62
|
+
|
63
|
+
if ENV['CHALK_DEBUG']
|
64
|
+
@logger.info("Request failed. Response status: #{response.status}, error: #{response.body}")
|
65
|
+
end
|
66
|
+
Http::Response.new(status: response.status, error: response.body, headers: response.headers)
|
67
|
+
rescue Faraday::TimeoutError => e
|
68
|
+
if ENV['CHALK_DEBUG']
|
69
|
+
@logger.info("Request timed out. Error: #{e.message}")
|
70
|
+
end
|
71
|
+
Http::Response.new(error: e.message, has_timed_out: true)
|
72
|
+
rescue ::StandardError => e
|
73
|
+
if ENV['CHALK_DEBUG']
|
74
|
+
@logger.info("Request failed. Error: #{e.message}")
|
75
|
+
end
|
76
|
+
Http::Response.new(error: e.message, network_failure: true)
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
# Retrieve the connection from the @connections
|
81
|
+
#
|
82
|
+
# @param host [String]
|
83
|
+
#
|
84
|
+
# @return [Faraday::Connection]
|
85
|
+
#
|
86
|
+
def connection(host)
|
87
|
+
@connections[host] ||= Faraday.new(host) do |f|
|
88
|
+
f.adapter @adapter.to_sym
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ChalkRuby
|
2
|
+
module Http
|
3
|
+
class Response
|
4
|
+
attr_reader :status, :body, :error, :headers, :has_timed_out, :network_failure
|
5
|
+
|
6
|
+
#
|
7
|
+
# @option status [String] Response status
|
8
|
+
# @option body [String] Response body
|
9
|
+
# @option error [String] Response error or caught error
|
10
|
+
# @option headers [String] Response headers
|
11
|
+
# @option has_timed_out [String] If the request has timed out
|
12
|
+
#
|
13
|
+
def initialize(opts = {})
|
14
|
+
@status = opts[:status]
|
15
|
+
@body = opts[:body] || ''
|
16
|
+
@error = opts[:error] || ''
|
17
|
+
@headers = opts[:headers] || ''
|
18
|
+
@has_timed_out = opts[:has_timed_out] || false
|
19
|
+
@network_failure = opts[:network_failure] || false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module ChalkRuby
|
4
|
+
class LoggerHelper
|
5
|
+
# @param debug_file [nil|String] file used to output the logs
|
6
|
+
#
|
7
|
+
def self.create(debug_file = nil)
|
8
|
+
file = debug_file || (ENV['CHALK_DEBUG'] ? File.new('debug.log') : $stderr)
|
9
|
+
instance = ::Logger.new file
|
10
|
+
instance.progname = 'chalk'
|
11
|
+
instance
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
# Default adapter needs to be required to be registered
|
3
|
+
require 'faraday/net_http_persistent' unless Faraday::VERSION < '1'
|
4
|
+
require 'chalk_ruby/error'
|
5
|
+
|
6
|
+
module ChalkRuby
|
7
|
+
module Transport
|
8
|
+
class Transport
|
9
|
+
include Helpers
|
10
|
+
|
11
|
+
# @param requester [ChalkRuby::Http::HttpRequester] requester used for sending requests.
|
12
|
+
#
|
13
|
+
def initialize(requester:)
|
14
|
+
@http_requester = requester
|
15
|
+
end
|
16
|
+
|
17
|
+
def request_simple(method:, host:, path:, timeout:, connect_timeout:, headers:, body:)
|
18
|
+
response = @http_requester.send_request(
|
19
|
+
host: host,
|
20
|
+
method: method,
|
21
|
+
path: path,
|
22
|
+
body: body && to_json(body: body),
|
23
|
+
headers: headers,
|
24
|
+
timeout: timeout,
|
25
|
+
connect_timeout: connect_timeout
|
26
|
+
)
|
27
|
+
|
28
|
+
if response.has_timed_out
|
29
|
+
raise ChalkHttpError.new(code: Defaults::ERROR_TIMED_OUT, message: 'Request timed out')
|
30
|
+
end
|
31
|
+
|
32
|
+
if response.network_failure
|
33
|
+
raise ChalkHttpError.new(code: 502, message: 'Network failure')
|
34
|
+
end
|
35
|
+
|
36
|
+
unless success?(http_response_code: response.status)
|
37
|
+
decoded_error = json_to_hash(json: response.error, symbolize_keys: true)
|
38
|
+
raise ChalkHttpError.new(
|
39
|
+
code: get_option(hash: decoded_error, key: 'status'),
|
40
|
+
message: get_option(hash: decoded_error, key: 'message')
|
41
|
+
)
|
42
|
+
end
|
43
|
+
json_to_hash(json: response.body, symbolize_keys: true)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def success?(http_response_code:)
|
49
|
+
!http_response_code.nil? && (http_response_code.to_i / 100).floor == 2
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/chalk_ruby.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# ChalkRuby module
|
2
|
+
module ChalkRuby
|
3
|
+
require 'chalk_ruby/version'
|
4
|
+
require 'chalk_ruby/helpers'
|
5
|
+
require 'chalk_ruby/http/http_requester'
|
6
|
+
require 'chalk_ruby/defaults'
|
7
|
+
require 'chalk_ruby/config/config'
|
8
|
+
require 'chalk_ruby/http/response'
|
9
|
+
require 'chalk_ruby/transport/transport'
|
10
|
+
require 'chalk_ruby/client'
|
11
|
+
require 'chalk_ruby/error'
|
12
|
+
require 'chalk_ruby/logger_helper'
|
13
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ChalkRuby
|
2
|
+
class Client
|
3
|
+
@config: Config
|
4
|
+
@token: Token?
|
5
|
+
@transporter: Transport::Transport
|
6
|
+
|
7
|
+
def self.create: -> Client
|
8
|
+
|
9
|
+
def self.create_with_config: -> Client
|
10
|
+
|
11
|
+
def get_token: -> Token
|
12
|
+
|
13
|
+
def query: (
|
14
|
+
::Hash[Symbol|String, untyped] input,
|
15
|
+
[String] output,
|
16
|
+
Time? now,
|
17
|
+
?::Hash[String, String] staleness
|
18
|
+
) -> Hash[Symbol, untyped]
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def get_authenticated_headers: -> Hash[Symbol, String | nil]
|
23
|
+
def get_unauthenticated_headers: -> Hash[Symbol, String | nil]
|
24
|
+
|
25
|
+
def query_server_host: -> String
|
26
|
+
|
27
|
+
def query_server_request: (
|
28
|
+
Symbol method,
|
29
|
+
String path,
|
30
|
+
Hash[Symbol, String] body,
|
31
|
+
Hash[String, String] headers
|
32
|
+
) -> Hash[Symbol, untyped]
|
33
|
+
|
34
|
+
def api_server_request: (
|
35
|
+
Symbol method,
|
36
|
+
String path,
|
37
|
+
Hash[Symbol, String] body,
|
38
|
+
Hash[String, String] headers
|
39
|
+
) -> Hash[Symbol, untyped]
|
40
|
+
|
41
|
+
def valid_token: -> Token
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ChalkRuby
|
2
|
+
class Config
|
3
|
+
attr_accessor client_id: String
|
4
|
+
attr_accessor client_secret: String
|
5
|
+
|
6
|
+
attr_accessor api_server: String
|
7
|
+
attr_accessor api_timeout: Integer
|
8
|
+
|
9
|
+
attr_accessor query_server: String
|
10
|
+
attr_accessor query_timeout: Integer
|
11
|
+
|
12
|
+
attr_accessor environment: String
|
13
|
+
|
14
|
+
attr_accessor connect_timeout: Integer
|
15
|
+
|
16
|
+
type options = {
|
17
|
+
client_id: String,
|
18
|
+
client_secret: String,
|
19
|
+
environment: String,
|
20
|
+
api_server: String,
|
21
|
+
query_server: String,
|
22
|
+
query_timeout: Integer,
|
23
|
+
api_timeout: Integer,
|
24
|
+
connect_timeout: Integer,
|
25
|
+
compression_type: String
|
26
|
+
}
|
27
|
+
|
28
|
+
def initialize: (options opts) -> void
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ChalkRuby
|
2
|
+
module Defaults
|
3
|
+
REQUESTER_CLASS : Http::HttpRequester
|
4
|
+
ADAPTER : String
|
5
|
+
|
6
|
+
# HTTP Headers
|
7
|
+
# ----------------------------------------
|
8
|
+
HEADER_CLIENT_ID : String
|
9
|
+
HEADER_CLIENT_SECRET : String
|
10
|
+
HEADER_ENVIRONMENT : String
|
11
|
+
AUTHORIZATION_HEADER : String
|
12
|
+
USER_AGENT : String
|
13
|
+
|
14
|
+
# API Servers
|
15
|
+
# ----------------------------------------
|
16
|
+
QUERY_SERVER : String
|
17
|
+
API_SERVER : String
|
18
|
+
|
19
|
+
# HTTP ERROR CODES
|
20
|
+
# ----------------------------------------
|
21
|
+
ERROR_BAD_REQUEST : Integer
|
22
|
+
ERROR_FORBIDDEN : Integer
|
23
|
+
ERROR_NOT_FOUND : Integer
|
24
|
+
ERROR_TIMED_OUT : Integer
|
25
|
+
|
26
|
+
# HTTP TIMEOUTS
|
27
|
+
# ----------------------------------------
|
28
|
+
CONNECT_TIMEOUT : Integer
|
29
|
+
API_TIMEOUT : Integer
|
30
|
+
QUERY_TIMEOUT : Integer
|
31
|
+
|
32
|
+
|
33
|
+
WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY : Integer
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ChalkRuby
|
2
|
+
module Helpers
|
3
|
+
def to_json: (String | Hash[Symbol, String] body) -> String
|
4
|
+
|
5
|
+
def symbolize_hash: (Hash[Symbol | String, untyped] hash) -> Hash[Symbol, untyped]
|
6
|
+
|
7
|
+
def json_to_hash: (String json, bool symbolize_keys) -> Hash[Symbol, String]
|
8
|
+
|
9
|
+
def get_option: ([Symbol | String, String] hash, String key) -> (String | [String])
|
10
|
+
|
11
|
+
def path_encode: (String path, *String args) -> String
|
12
|
+
|
13
|
+
def self.included: (self base) -> self
|
14
|
+
end
|
15
|
+
end
|