xe_client 0.1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fdaeee0666ddaa0e81f9425aad6e689dd5853570
4
- data.tar.gz: 7b10ff686963faebee6dbd019c0726e9599c94c4
2
+ SHA256:
3
+ metadata.gz: d57a5857429d30d7aa2ab687b7a5d4fc467e18ee1ab10ebf415c914d27f149a9
4
+ data.tar.gz: d0cb8810a53660ac5a45d55d14be341aa8a0876ce6dff1381521a8b9f21af367
5
5
  SHA512:
6
- metadata.gz: a7328447e7f2bd6871fbf40f0613a5eb4591b169cc1008ac9fbecdbdbef9d78c84de04d21b3737a07f4686e1359cfc0e770f26aae6ba66293d1247c61c1d2dbe
7
- data.tar.gz: 50d146942dd556d3606ba348404c70f08b46990e4cecac8596023ff5f7f5ab0820227857f6cbc717e4b71d3c7cb7ddb8df4d7c04af5bb142a208d2a3efd1c31b
6
+ metadata.gz: 55a0a14eee2432daca0c88c9e404453f22c738b6ff6a08d5e44218c349b6536d9fbdf04dbf9ac42a00c65b2a5ba91dd2eaf41bc6a782a9931b08d9f5607da75d
7
+ data.tar.gz: 9868ff4f6350dfed96c509be481595ef17867a9eaa8db0d63399d46a7da3a23610acbc3b069f60afbb2d08470deeb6e895f07666ca032be6ba27be306a95fd5d
@@ -0,0 +1,37 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Setup spec config
35
+ run: cp spec/config.yml{.sample,}
36
+ - name: Run tests
37
+ run: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [1.1.0] - 2021-06-15
6
+ ### Added
7
+ - Update `dry-validation` to 1.x
8
+
9
+ ## [1.0.1] - 2020-06-30
10
+ ### Fixed
11
+ - `#historic_rate_period`: Do not blow up if no rates
12
+
13
+ ## [1.0.0] - 2020-06-30
14
+ ### Changed
15
+ - Changed `url` to `host` fot the XE API host (defaults to https://xecdapi.xe.com)
16
+ - Changed `#convert_from` to accept keyword args named more like the API's param names:
17
+ - `from` instead of the first argument aka `base_currency`
18
+ - `to` instead of the second argument aka `counter_currencies`
19
+ - `amount` instead of the third argument
20
+ - No longer raise exception when XE's response contains an error. Developer should use `#success?` on the response instead and inspect `#error` to see details.
21
+ ### Added
22
+ - `historic_rate_period` call to get historic rates over a period
23
+
24
+ ## [0.2.1] - 2016-08-11
25
+ ### Fixed
26
+ - Fix issue when accessing ConvertFromResponse#to and error was raised
27
+
28
+ ## [0.2.0] - 2016-06-30
29
+ ### Added
30
+ - Raise XEClient::AuthenticationError when there's an auth issue
31
+ - Raise XEClient::Error for all other errors
32
+
5
33
  ## [0.1.0] - 2016-06-22
6
34
  ### Added
7
35
  - Add initial working version (`#convert_from`)
data/README.md CHANGED
@@ -30,7 +30,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
30
30
 
31
31
  ## Contributing
32
32
 
33
- Bug reports and pull requests are welcome on [GitHub](https://github.com/imacchiato/xe_client-ruby). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
33
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/bloom-solutions/xe_client-ruby). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
34
34
 
35
35
 
36
36
  ## License
data/lib/xe_client.rb CHANGED
@@ -1,22 +1,35 @@
1
1
  require "xe_client/version"
2
+ require "api_client_base"
2
3
  require "active_model"
4
+ require "dry-validation"
3
5
  require "virtus"
4
6
  require "httparty"
5
7
  require "active_support/core_ext/hash/indifferent_access"
8
+ require "active_support/core_ext/date_time"
9
+ require "active_support/core_ext/string/conversions"
6
10
  require "xe_client/indifferent_hash"
7
11
  require "xe_client/models/quote"
8
12
  require "xe_client/client"
9
13
  require "xe_client/requests/base_request"
10
14
  require "xe_client/requests/convert_from_request"
15
+ require "xe_client/requests/historic_rate_period_request"
11
16
  require "xe_client/responses/base_response"
12
17
  require "xe_client/responses/convert_from_response"
18
+ require "xe_client/responses/historic_rate_period_response"
19
+ require "xe_client/schemas/convert_from_request_schema"
20
+ require "xe_client/errors/error"
21
+ require "xe_client/errors/authentication_error"
13
22
 
14
23
  module XEClient
15
24
 
16
- def self.new(opts)
17
- client = Client.new(opts)
18
- raise ArgumentError, client.errors.full_messages if client.invalid?
19
- client
25
+ include APIClientBase::Base.module
26
+
27
+ DEFAULT_HOST = "https://xecdapi.xe.com"
28
+
29
+ with_configuration do
30
+ has :host, classes: String, default: DEFAULT_HOST
31
+ has :account_id, classes: String
32
+ has :api_key, classes: String
20
33
  end
21
34
 
22
35
  end
@@ -1,30 +1,18 @@
1
1
  module XEClient
2
2
  class Client
3
3
 
4
- DEFAULT_URL = "https://xecdapi.xe.com"
5
-
6
- include Virtus.model
4
+ include APIClientBase::Client.module(default_opts: :default_opts)
5
+ attribute :host, String
7
6
  attribute :account_id, String
8
7
  attribute :api_key, String
9
- attribute :url, String, default: DEFAULT_URL
10
-
11
- include ActiveModel::Validations
12
- validates :account_id, :api_key, presence: true
13
8
 
14
- def convert_from(base_currency, counter_currencies, amount)
15
- args = default_args.merge(
16
- base_currency: base_currency,
17
- counter_currencies: counter_currencies,
18
- amount: amount,
19
- )
20
- raw_response = ConvertFromRequest.(args)
21
- ConvertFromResponse.new(raw_response: raw_response)
22
- end
9
+ api_action :convert_from
10
+ api_action :historic_rate_period
23
11
 
24
12
  private
25
13
 
26
- def default_args
27
- attributes.slice(:account_id, :api_key, :url)
14
+ def default_opts
15
+ { host: host, account_id: account_id, api_key: api_key }
28
16
  end
29
17
 
30
18
  end
@@ -0,0 +1,4 @@
1
+ module XEClient
2
+ class AuthenticationError < Error
3
+ end
4
+ end
@@ -0,0 +1,22 @@
1
+ module XEClient
2
+ class Error < StandardError
3
+
4
+ CODE_ERROR_MAP = {
5
+ 1 => "AuthenticationError",
6
+ }
7
+ attr_accessor :code
8
+
9
+ def self.new_from_response(response)
10
+ return nil if response.code.nil?
11
+ klass = if class_name = CODE_ERROR_MAP[response.code]
12
+ XEClient.const_get(class_name)
13
+ else
14
+ self
15
+ end
16
+ error = klass.new(response.message)
17
+ error.code = response.code
18
+ error
19
+ end
20
+
21
+ end
22
+ end
@@ -4,6 +4,7 @@ module XEClient
4
4
  include Virtus.model
5
5
  attribute :quotecurrency, String
6
6
  attribute :mid, Float
7
+ attribute :timestamp, DateTime
7
8
 
8
9
  end
9
10
  end
@@ -1,16 +1,13 @@
1
1
  module XEClient
2
2
  class BaseRequest
3
3
 
4
- include Virtus.model
4
+ include APIClientBase::Request.module
5
+ attribute :host, String
5
6
  attribute :account_id, String
6
7
  attribute :api_key, String
7
- attribute :url, String
8
8
 
9
- include ActiveModel::Validations
10
- validates :account_id, :api_key, :url, presence: true
11
-
12
- def self.call(opts)
13
- self.new(opts).call
9
+ def typhoeus_options
10
+ { userpwd: [account_id, api_key].join(":") }
14
11
  end
15
12
 
16
13
  end
@@ -1,37 +1,20 @@
1
1
  module XEClient
2
2
  class ConvertFromRequest < BaseRequest
3
3
 
4
- DEFAULT_PATH = "/v1/convert_from.json"
5
- attribute :base_currency, String
6
- attribute :counter_currencies, Array[String]
4
+ attribute :from, String
5
+ attribute :to, Array[String]
7
6
  attribute :amount, Float
8
- attribute :endpoint, String, lazy: true, default: :default_endpoint
9
7
 
10
- validates(
11
- :base_currency,
12
- :counter_currencies,
13
- :amount,
14
- presence: true,
15
- )
16
-
17
- def call
18
- HTTParty.get(
19
- endpoint,
20
- query: {
21
- from: base_currency,
22
- to: counter_currencies.join(","),
23
- amount: amount,
24
- },
25
- basic_auth: { username: account_id, password: api_key },
26
- )
8
+ def path
9
+ "/v1/convert_from.json"
27
10
  end
28
11
 
29
- private
30
-
31
- def default_endpoint
32
- uri = URI.parse(url)
33
- uri.path = DEFAULT_PATH
34
- uri.to_s
12
+ def params
13
+ {
14
+ from: from,
15
+ to: to.join(","),
16
+ amount: amount,
17
+ }
35
18
  end
36
19
 
37
20
  end
@@ -0,0 +1,29 @@
1
+ module XEClient
2
+ class HistoricRatePeriodRequest < BaseRequest
3
+
4
+ attribute :from, String
5
+ attribute :to, Array[String]
6
+ attribute :start_timestamp, DateTime
7
+ attribute :end_timestamp, DateTime
8
+ attribute :interval, String
9
+ attribute :per_page, Integer
10
+ attribute :page, Integer
11
+
12
+ def path
13
+ "/v1/historic_rate/period.json"
14
+ end
15
+
16
+ def params
17
+ {
18
+ from: from,
19
+ to: to.join(","),
20
+ start_timestamp: start_timestamp,
21
+ end_timestamp: end_timestamp,
22
+ interval: interval,
23
+ per_page: per_page,
24
+ page: page,
25
+ }
26
+ end
27
+
28
+ end
29
+ end
@@ -1,7 +1,37 @@
1
1
  module XEClient
2
2
  class BaseResponse
3
3
 
4
- include Virtus.model
4
+ include APIClientBase::Response.module
5
+ attribute :raw_response
6
+ attribute(:response_body, IndifferentHash, {
7
+ lazy: true,
8
+ default: :default_response_body,
9
+ })
10
+ attribute :code, Integer, lazy: true, default: :default_code
11
+ attribute :message, String, lazy: true, default: :default_message
12
+ attribute :error, Object, lazy: true, default: :default_error
13
+
14
+ private
15
+
16
+ def default_code
17
+ response_body[:code]
18
+ end
19
+
20
+ def default_message
21
+ response_body[:message]
22
+ end
23
+
24
+ def default_error
25
+ Error.new_from_response(self)
26
+ end
27
+
28
+ def default_response_body
29
+ JSON.parse(raw_response.body)
30
+ end
31
+
32
+ def default_success
33
+ error.blank?
34
+ end
5
35
 
6
36
  end
7
37
  end
@@ -3,16 +3,15 @@ module XEClient
3
3
 
4
4
  attribute :from, String, lazy: true, default: :default_from
5
5
  attribute :to, Array, lazy: true, default: :default_to
6
- attribute :raw_response, IndifferentHash
7
6
 
8
7
  private
9
8
 
10
9
  def default_from
11
- raw_response[:from]
10
+ response_body[:from]
12
11
  end
13
12
 
14
13
  def default_to
15
- raw_response[:to].map do |quote_hash|
14
+ response_body[:to].map do |quote_hash|
16
15
  Quote.new(quote_hash)
17
16
  end
18
17
  end
@@ -0,0 +1,26 @@
1
+ module XEClient
2
+ class HistoricRatePeriodResponse < BaseResponse
3
+
4
+ attribute :from, String, lazy: true, default: :default_from
5
+ attribute :to, Array, lazy: true, default: :default_to
6
+
7
+ private
8
+
9
+ def default_from
10
+ response_body[:from]
11
+ end
12
+
13
+ def default_to
14
+ to = response_body[:to]
15
+
16
+ return [] if to.blank?
17
+
18
+ to.each_with_object([]) do |(currency, quote_args), arr|
19
+ quote_args.each do |quote_arg|
20
+ arr << Quote.new(quote_arg.merge(quotecurrency: currency))
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module MyGem
2
+ class ConvertFromRequestSchema < Dry::Validation::Contract
3
+
4
+ params do
5
+ required(:account_id).filled(:str?)
6
+ required(:api_key).filled(:str?)
7
+ required(:host).filled(:str?)
8
+ end
9
+
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module XEClient
2
- VERSION = "0.1.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/xe_client.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["ramon.tayag@gmail.com"]
11
11
 
12
12
  spec.summary = %q{Ruby wrapper for XE's REST API}
13
- spec.homepage = "https://github.com/imacchiato/xe_client-ruby"
13
+ spec.homepage = "https://github.com/bloom-solutions/xe_client-ruby"
14
14
  spec.license = "MIT"
15
15
 
16
16
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
@@ -30,8 +30,11 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency "activemodel", ">= 3.0"
31
31
  spec.add_dependency "virtus", "~> 1.0"
32
32
  spec.add_dependency "httparty"
33
+ spec.add_dependency "api_client_base", "~> 1.9"
34
+ spec.add_dependency "dry-validation", "~> 1.0", "< 2"
35
+ spec.add_dependency "typhoeus", "~> 1.0"
33
36
 
34
- spec.add_development_dependency "bundler", "~> 1.12"
37
+ spec.add_development_dependency "bundler", "~> 2.0"
35
38
  spec.add_development_dependency "rake", "~> 10.0"
36
39
  spec.add_development_dependency "rspec", "~> 3.0"
37
40
  spec.add_development_dependency "shoulda-matchers", "~> 3.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xe_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ramon Tayag
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-22 00:00:00.000000000 Z
11
+ date: 2021-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,20 +66,68 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: api_client_base
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dry-validation
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '2'
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.0'
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '2'
103
+ - !ruby/object:Gem::Dependency
104
+ name: typhoeus
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.0'
69
117
  - !ruby/object:Gem::Dependency
70
118
  name: bundler
71
119
  requirement: !ruby/object:Gem::Requirement
72
120
  requirements:
73
121
  - - "~>"
74
122
  - !ruby/object:Gem::Version
75
- version: '1.12'
123
+ version: '2.0'
76
124
  type: :development
77
125
  prerelease: false
78
126
  version_requirements: !ruby/object:Gem::Requirement
79
127
  requirements:
80
128
  - - "~>"
81
129
  - !ruby/object:Gem::Version
82
- version: '1.12'
130
+ version: '2.0'
83
131
  - !ruby/object:Gem::Dependency
84
132
  name: rake
85
133
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +198,7 @@ dependencies:
150
198
  - - "~>"
151
199
  - !ruby/object:Gem::Version
152
200
  version: '2.0'
153
- description:
201
+ description:
154
202
  email:
155
203
  - ramon.tayag@gmail.com
156
204
  executables: []
@@ -158,9 +206,9 @@ extensions: []
158
206
  extra_rdoc_files: []
159
207
  files:
160
208
  - ".envrc"
209
+ - ".github/workflows/ruby.yml"
161
210
  - ".gitignore"
162
211
  - ".rspec"
163
- - ".travis.yml"
164
212
  - CHANGELOG.md
165
213
  - CODE_OF_CONDUCT.md
166
214
  - Gemfile
@@ -171,20 +219,25 @@ files:
171
219
  - bin/setup
172
220
  - lib/xe_client.rb
173
221
  - lib/xe_client/client.rb
222
+ - lib/xe_client/errors/authentication_error.rb
223
+ - lib/xe_client/errors/error.rb
174
224
  - lib/xe_client/indifferent_hash.rb
175
225
  - lib/xe_client/models/quote.rb
176
226
  - lib/xe_client/requests/base_request.rb
177
227
  - lib/xe_client/requests/convert_from_request.rb
228
+ - lib/xe_client/requests/historic_rate_period_request.rb
178
229
  - lib/xe_client/responses/base_response.rb
179
230
  - lib/xe_client/responses/convert_from_response.rb
231
+ - lib/xe_client/responses/historic_rate_period_response.rb
232
+ - lib/xe_client/schemas/convert_from_request_schema.rb
180
233
  - lib/xe_client/version.rb
181
234
  - xe_client.gemspec
182
- homepage: https://github.com/imacchiato/xe_client-ruby
235
+ homepage: https://github.com/bloom-solutions/xe_client-ruby
183
236
  licenses:
184
237
  - MIT
185
238
  metadata:
186
239
  allowed_push_host: https://rubygems.org
187
- post_install_message:
240
+ post_install_message:
188
241
  rdoc_options: []
189
242
  require_paths:
190
243
  - lib
@@ -199,9 +252,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
252
  - !ruby/object:Gem::Version
200
253
  version: '0'
201
254
  requirements: []
202
- rubyforge_project:
203
- rubygems_version: 2.5.1
204
- signing_key:
255
+ rubygems_version: 3.1.6
256
+ signing_key:
205
257
  specification_version: 4
206
258
  summary: Ruby wrapper for XE's REST API
207
259
  test_files: []
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3.0
5
- before_install: gem install bundler -v 1.12.5