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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d181593590629e548b61b096cf47322584fd943002972d002d6104348628af7
4
- data.tar.gz: 01a9168981928f32c6a64a0315dce7227c2153a4b75bfb1e9192a69f1bc80785
3
+ metadata.gz: ed94b089c0e0f86ccf4acec03af52e2b23e6b0c7f284b3a947e9c15280fc208e
4
+ data.tar.gz: 7858cb787ce243ee49ad7d953d747f859116f0cc47906d13235faa71e629f1ca
5
5
  SHA512:
6
- metadata.gz: b7eec7746486022b3f92e01a96a49057299cb2a4f6afd9b763ba4214bd6c61d79f0c2d6e4e2447a302a7751939628881dca83b274cbf4efc5a8f70b582d2ecc4
7
- data.tar.gz: 2b4729698266b975556d13b717fd6ea5224f2da79379e2f1225058b1bc03e2a20d20be7228ff4d7c181e0275529577f46cf183dcddd271efb08a95f8490ea9b8
6
+ metadata.gz: '096660ad1bde2cec7fbfbcf532879cc415a702c467e5dc687469f2b77aaa064a94a82a3a1efc5f480d35408adb0af8c870d686fe5ab11b5842a2c51eff58097e'
7
+ data.tar.gz: 2e15e44494be6edd6fbb29f1469b70708567d071a4936b1b58902c96e7a0958e1a5de10e8de8abcbf66baeaaab99152c93752cec9045ce11dbba459072fbc938
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'client-api-builder'
5
- s.version = '0.2.1'
5
+ s.version = '0.2.5'
6
6
  s.licenses = ['MIT']
7
7
  s.summary = 'Develop Client API libraries faster'
8
8
  s.description = 'Utility for constructing API clients'
@@ -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 += " @response = request(method: #{http_method.inspect}, uri: __uri__, body: __body__, headers: __headers__, connection_options: __connection_options__)\n"
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
- code += " handle_response(@response, __options__, &block)\n"
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.1
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-05 00:00:00.000000000 Z
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