client-api-builder 0.2.1 → 0.2.5
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 +4 -4
- data/client-api-builder.gemspec +1 -1
- data/examples/basic_auth_example_client.rb +23 -0
- data/examples/imdb_datasets_client.rb +31 -0
- data/lib/client_api_builder/net_http_request.rb +24 -1
- data/lib/client_api_builder/router.rb +41 -4
- data/script/console +3 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed94b089c0e0f86ccf4acec03af52e2b23e6b0c7f284b3a947e9c15280fc208e
|
4
|
+
data.tar.gz: 7858cb787ce243ee49ad7d953d747f859116f0cc47906d13235faa71e629f1ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '096660ad1bde2cec7fbfbcf532879cc415a702c467e5dc687469f2b77aaa064a94a82a3a1efc5f480d35408adb0af8c870d686fe5ab11b5842a2c51eff58097e'
|
7
|
+
data.tar.gz: 2e15e44494be6edd6fbb29f1469b70708567d071a4936b1b58902c96e7a0958e1a5de10e8de8abcbf66baeaaab99152c93752cec9045ce11dbba459072fbc938
|
data/client-api-builder.gemspec
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
class BasicAuthExampleClient < Struct.new(
|
4
|
+
:username,
|
5
|
+
:password
|
6
|
+
)
|
7
|
+
|
8
|
+
include ClientApiBuilder::Router
|
9
|
+
|
10
|
+
base_url 'https://www.example.com'
|
11
|
+
|
12
|
+
header 'Authorization', :basic_authorization
|
13
|
+
query_param('cache_buster') { (Time.now.to_f * 1000).to_i }
|
14
|
+
|
15
|
+
route :get_apps, '/apps'
|
16
|
+
route :get_app, '/apps/:app_id'
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def basic_authorization
|
21
|
+
'basic ' + Base64.strict_encode64(username + ':' + password)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class IMDBDatesetsClient
|
2
|
+
include ClientApiBuilder::Router
|
3
|
+
|
4
|
+
base_url 'https://datasets.imdbws.com'
|
5
|
+
|
6
|
+
route :get_name_basics, '/name.basics.tsv.gz', stream: :file
|
7
|
+
route :get_title_akas, '/title.akas.tsv.gz', stream: :io
|
8
|
+
route :get_title_basics, '/title.basics.tsv.gz', stream: :block
|
9
|
+
|
10
|
+
def self.stream_to_file
|
11
|
+
new.get_name_basics(file: 'name.basics.tsv.gz')
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.stream_to_io
|
15
|
+
File.open('title.akas.tsv.gz', 'wb') do |io|
|
16
|
+
new.get_title_akas(io: io)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.stream_with_block
|
21
|
+
File.open('title.basics.tsv.gz', 'wb') do |io|
|
22
|
+
total_read = 0.0
|
23
|
+
new.get_title_basics do |response, chunk|
|
24
|
+
total_read += chunk.bytesize
|
25
|
+
percentage_complete = ((total_read / response.content_length) * 100).to_i
|
26
|
+
puts "downloading title.basics.tsv.gz completed: #{percentage_complete}%"
|
27
|
+
io.write chunk
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -28,7 +28,30 @@ module ClientApiBuilder
|
|
28
28
|
request.body = body if body
|
29
29
|
|
30
30
|
Net::HTTP.start(uri.hostname, uri.port, connection_options.merge(use_ssl: uri.scheme == 'https')) do |http|
|
31
|
-
http.request(request)
|
31
|
+
http.request(request) do |response|
|
32
|
+
yield response if block_given?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def stream(method:, uri:, body:, headers:, connection_options:)
|
38
|
+
request(method: method, uri: uri, body: body, headers: headers, connection_options: connection_options) do |response|
|
39
|
+
response.read_body do |chunk|
|
40
|
+
yield response, chunk
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def stream_to_io(method:, uri:, body:, headers:, connection_options:, io:)
|
46
|
+
stream(method: method, uri: uri, body: body, headers: headers, connection_options: connection_options) do |_, chunk|
|
47
|
+
io.write chunk
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def stream_to_file(method:, uri:, body:, headers:, connection_options:, file:)
|
52
|
+
mode = connection_options.delete(:file_mode) || 'wb'
|
53
|
+
File.open(file, mode) do |io|
|
54
|
+
stream_to_io(method: method, uri: uri, body: body, headers: headers, connection_options: connection_options, io: io)
|
32
55
|
end
|
33
56
|
end
|
34
57
|
end
|
@@ -7,7 +7,7 @@ module ClientApiBuilder
|
|
7
7
|
base.extend InheritanceHelper::Methods
|
8
8
|
base.extend ClassMethods
|
9
9
|
base.include ::ClientApiBuilder::NetHTTP::Request
|
10
|
-
base.attr_reader :response
|
10
|
+
base.attr_reader :response, :request_options
|
11
11
|
end
|
12
12
|
|
13
13
|
module ClassMethods
|
@@ -51,7 +51,7 @@ module ClientApiBuilder
|
|
51
51
|
add_value_to_class_method(:default_options, connection_options: connection_options)
|
52
52
|
end
|
53
53
|
|
54
|
-
def query_param(name, value)
|
54
|
+
def query_param(name, value = nil, &block)
|
55
55
|
query_params = default_options[:query_params].dup
|
56
56
|
query_params[name] = value || block
|
57
57
|
add_value_to_class_method(:default_options, query_params: query_params)
|
@@ -146,6 +146,11 @@ module ClientApiBuilder
|
|
146
146
|
def generate_route_code(method_name, path, options = {})
|
147
147
|
http_method = options[:method] || http_method(method_name)
|
148
148
|
|
149
|
+
# instance method
|
150
|
+
path.gsub!(/\{([a-z0-9_]+)\}/i) do |_|
|
151
|
+
"#\{#{$1}\}"
|
152
|
+
end
|
153
|
+
|
149
154
|
path_arguments = []
|
150
155
|
path.gsub!(/:([a-z0-9_]+)/i) do |_|
|
151
156
|
path_arguments << $1
|
@@ -192,8 +197,18 @@ module ClientApiBuilder
|
|
192
197
|
end
|
193
198
|
expected_response_codes.map!(&:to_s)
|
194
199
|
|
200
|
+
stream_param =
|
201
|
+
case options[:stream]
|
202
|
+
when true,
|
203
|
+
:file
|
204
|
+
:file
|
205
|
+
when :io
|
206
|
+
:io
|
207
|
+
end
|
208
|
+
|
195
209
|
method_args = named_arguments.map { |arg_name| "#{arg_name}:" }
|
196
210
|
method_args += ['body:'] if has_body_param
|
211
|
+
method_args += ["#{stream_param}:"] if stream_param
|
197
212
|
method_args += ['**__options__', '&block']
|
198
213
|
|
199
214
|
code = "def #{method_name}(" + method_args.join(', ') + ")\n"
|
@@ -205,9 +220,31 @@ module ClientApiBuilder
|
|
205
220
|
code += " __body__ = build_body(__body__, __options__)\n"
|
206
221
|
code += " __headers__ = build_headers(__options__)\n"
|
207
222
|
code += " __connection_options__ = build_connection_options(__options__)\n"
|
208
|
-
code += " @
|
223
|
+
code += " @request_options = {method: #{http_method.inspect}, uri: __uri__, body: __body__, headers: __headers__, connection_options: __connection_options__}\n"
|
224
|
+
code += " @request_options[:#{stream_param}] = #{stream_param}\n" if stream_param
|
225
|
+
|
226
|
+
case options[:stream]
|
227
|
+
when true,
|
228
|
+
:file
|
229
|
+
code += " @response = stream_to_file(**@request_options)\n"
|
230
|
+
when :io
|
231
|
+
code += " @response = stream_to_io(**@request_options)\n"
|
232
|
+
when :block
|
233
|
+
code += " @response = stream(**@request_options, &block)\n"
|
234
|
+
else
|
235
|
+
code += " @response = request(**@request_options)\n"
|
236
|
+
end
|
237
|
+
|
209
238
|
code += " expected_response_code!(@response, __expected_response_codes__, __options__)\n"
|
210
|
-
|
239
|
+
|
240
|
+
if options[:stream] || options[:return] == :response
|
241
|
+
code += " @response\n"
|
242
|
+
elsif options[:return] == :body
|
243
|
+
code += " @response.body\n"
|
244
|
+
else
|
245
|
+
code += " handle_response(@response, __options__, &block)\n"
|
246
|
+
end
|
247
|
+
|
211
248
|
code += "end\n"
|
212
249
|
code
|
213
250
|
end
|
data/script/console
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
$LOAD_PATH << File.expand_path('../lib', __dir__)
|
5
|
+
$LOAD_PATH << File.expand_path('../examples', __dir__)
|
5
6
|
require 'client-api-builder'
|
7
|
+
autoload :BasicAuthExampleClient, 'basic_auth_example_client'
|
8
|
+
autoload :IMDBDatesetsClient, 'imdb_datasets_client'
|
6
9
|
require 'irb'
|
7
10
|
IRB.start(__FILE__)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: client-api-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doug Youch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Utility for constructing API clients
|
14
14
|
email: dougyouch@gmail.com
|
@@ -24,6 +24,8 @@ files:
|
|
24
24
|
- LICENSE
|
25
25
|
- README.md
|
26
26
|
- client-api-builder.gemspec
|
27
|
+
- examples/basic_auth_example_client.rb
|
28
|
+
- examples/imdb_datasets_client.rb
|
27
29
|
- lib/client-api-builder.rb
|
28
30
|
- lib/client_api_builder/net_http_request.rb
|
29
31
|
- lib/client_api_builder/query_params.rb
|