chalk_ruby 0.1.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/.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
|