fx_rates 1.0.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/.gitignore +11 -0
- data/.rspec +3 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +21 -0
- data/README.md +193 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/fx_rates.gemspec +41 -0
- data/lib/fx_rates/client.rb +85 -0
- data/lib/fx_rates/configuration.rb +9 -0
- data/lib/fx_rates/request.rb +42 -0
- data/lib/fx_rates/response/convert.rb +17 -0
- data/lib/fx_rates/response/rates.rb +14 -0
- data/lib/fx_rates/response/timeseries.rb +14 -0
- data/lib/fx_rates/version.rb +3 -0
- data/lib/fx_rates.rb +20 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ba8ee3362236531a97f762c3789cf75320fb738260f757aa6859618944331cf8
|
4
|
+
data.tar.gz: 489939c77bb65495fd997e6a023eefcb1323e0b819afe014d6749861db65b378
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3065a665d71668c328e1898f6d33f520a34bd8e3ada0b43beb24b41e952254907619c9e960580fdf27b2a225a4a3ae64f5624b431b4ad2026f22b667f7d96acb
|
7
|
+
data.tar.gz: a9497fca5dec8b412add61019d8461bdf688bc45732a97b026635c2f45fb20319760bfa39d508572c0947150de773d058416833e240411cc68c39d62e12de75d
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fx_rates (1.0.0)
|
5
|
+
faraday (~> 2.0)
|
6
|
+
zeitwerk (~> 2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
base64 (0.2.0)
|
12
|
+
diff-lcs (1.5.1)
|
13
|
+
faraday (2.8.1)
|
14
|
+
base64
|
15
|
+
faraday-net_http (>= 2.0, < 3.1)
|
16
|
+
ruby2_keywords (>= 0.0.4)
|
17
|
+
faraday-net_http (3.0.2)
|
18
|
+
rake (10.5.0)
|
19
|
+
rspec (3.13.0)
|
20
|
+
rspec-core (~> 3.13.0)
|
21
|
+
rspec-expectations (~> 3.13.0)
|
22
|
+
rspec-mocks (~> 3.13.0)
|
23
|
+
rspec-core (3.13.3)
|
24
|
+
rspec-support (~> 3.13.0)
|
25
|
+
rspec-expectations (3.13.3)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.13.0)
|
28
|
+
rspec-mocks (3.13.2)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.13.0)
|
31
|
+
rspec-support (3.13.2)
|
32
|
+
ruby2_keywords (0.0.5)
|
33
|
+
zeitwerk (2.6.18)
|
34
|
+
|
35
|
+
PLATFORMS
|
36
|
+
ruby
|
37
|
+
|
38
|
+
DEPENDENCIES
|
39
|
+
bundler (~> 1.17)
|
40
|
+
fx_rates!
|
41
|
+
rake (~> 10.0)
|
42
|
+
rspec (~> 3.0)
|
43
|
+
|
44
|
+
BUNDLED WITH
|
45
|
+
1.17.3
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Kevin Luo
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
# FxRates
|
2
|
+
|
3
|
+
`fx_rates` is an API wrapper for https://fxratesapi.com/. I don't work for them. I just like their service very much, so I made this gem to let rubists access their service easier.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'fx_rates'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install fx_rates
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### Initialize
|
25
|
+
|
26
|
+
You can initialize `FXRates::Client` with an API key you get on https://fxratesapi.com/.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
client = FXRates::Client.new(api_key: 'fxr_live_xxxxxxxxxxxxxxxxxxxxxxxxxx') # api key is required!
|
30
|
+
|
31
|
+
# Or you can configure
|
32
|
+
FXRates.configure do |config|
|
33
|
+
config.api_key = 'fxr_live_xxxxxxxxxxxxxxxxxxxxxxxxxx'
|
34
|
+
end
|
35
|
+
client = FXRates::Client.new
|
36
|
+
```
|
37
|
+
|
38
|
+
Then you can call FXRates API endpoints with the this `client`
|
39
|
+
|
40
|
+
### latest
|
41
|
+
|
42
|
+
`#latest` returns the latest rates based on the base currency.
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
response = client.latest
|
46
|
+
response.base
|
47
|
+
# "USD"
|
48
|
+
response.rates
|
49
|
+
# All available currencies and their exchange rates
|
50
|
+
# {"ADA"=>1.2661080459, "AED"=>3.6726003855, ... }
|
51
|
+
response.date
|
52
|
+
# "2025-02-15T19:14:00.000Z"
|
53
|
+
response.timestamp
|
54
|
+
# 1739646840
|
55
|
+
|
56
|
+
# you can specify the parameters
|
57
|
+
response = client.latest(base: 'CAD', currencies: ['USD', 'JPY', 'TWD'])
|
58
|
+
```
|
59
|
+
#### Available parameters
|
60
|
+
|
61
|
+
| Parameter | Description | Default |
|
62
|
+
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
63
|
+
| **resolution** | Specifies the update interval of the exchange rates. Available options:<br> - `1d` - daily<br> - `1h` - hourly<br> - `10m` - every 10 minutes<br> - `1m` - every 60 seconds<br> Most current available rates for your subscription plan. | Most current available rates for your plan |
|
64
|
+
| **currencies** | Specifies the currencies you want exchange rates for. Multiple currencies can be separated with a comma. | All available currencies |
|
65
|
+
| **base** | Sets the currency in which exchange rates are quoted. All exchange rates are relative to this base currency. | `USD` |
|
66
|
+
| **amount** | The amount of the base currency to convert. | `1` |
|
67
|
+
| **places** | Specifies the number of decimal places in the response. By default, the most available decimal places for the currency are returned. | Most available decimal places |
|
68
|
+
|
69
|
+
### historical
|
70
|
+
|
71
|
+
`#historical` returns the exchange rates on a specific date. If the date is not given, it will use the current date.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
response = client.historical(date: '2025-01-31')
|
75
|
+
response.base
|
76
|
+
# "USD"
|
77
|
+
response.rates
|
78
|
+
# All available currencies and their exchange rates
|
79
|
+
# {"ADA"=>1.2661080459, "AED"=>3.6726003855, ... }
|
80
|
+
response.date
|
81
|
+
# "2025-02-15T19:14:00.000Z"
|
82
|
+
response.timestamp
|
83
|
+
# 1739646840
|
84
|
+
|
85
|
+
# you can specify the parameters
|
86
|
+
response = client.latest(base: 'CAD', currencies: ['USD', 'JPY', 'TWD'])
|
87
|
+
```
|
88
|
+
|
89
|
+
#### Available parameters
|
90
|
+
| Parameter | Description | Default |
|
91
|
+
|:-------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
|
92
|
+
| **date** | The date for which you want to get the exchange rates. The date must be specified in the `YYYY-MM-DD` format. | Current date |
|
93
|
+
| **base** | Sets the currency in which exchange rates are quoted. All exchange rates are relative to this base currency. | `USD` |
|
94
|
+
| **currencies** | Specifies the currencies you want exchange rates for. Multiple currencies can be separated with a comma. | All available currencies |
|
95
|
+
| **amount** | The amount of the base currency to convert. | `1` |
|
96
|
+
| **places** | Specifies the number of decimal places in the response. By default, the most available decimal places for the currency are returned. | All available decimal places |
|
97
|
+
|
98
|
+
### timeseries
|
99
|
+
|
100
|
+
`#timeseries` returns the rates during the specified period. `start_date` and `end_date` are required
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
response = client.timeseries start_date: '2025-02-01', end_date: '2025-02-05', currencies: ['CAD', 'JPY']
|
104
|
+
|
105
|
+
response.base
|
106
|
+
# "USD"
|
107
|
+
response.start_date
|
108
|
+
# "2025-02-01T00:00:00.000Z"
|
109
|
+
response.end_date
|
110
|
+
# "2025-02-05T00:00:00.000Z"
|
111
|
+
response.rates
|
112
|
+
# {
|
113
|
+
# "2025-02-04T23:59:00.000Z"=>{"CAD"=>1.4327402762, "JPY"=>154.1029666308},
|
114
|
+
# "2025-02-03T23:59:00.000Z"=>{"CAD"=>1.4415901702, "JPY"=>155.2101489283},
|
115
|
+
# "2025-02-02T23:59:00.000Z"=>{"CAD"=>1.4713002625, "JPY"=>155.3692612221},
|
116
|
+
# "2025-02-01T23:59:00.000Z"=>{"CAD"=>1.451700235, "JPY"=>155.1286365022}
|
117
|
+
# }
|
118
|
+
```
|
119
|
+
|
120
|
+
#### Availalbe parameters
|
121
|
+
|
122
|
+
| Parameter | Description | Default |
|
123
|
+
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
124
|
+
| **start_date** *(required)* | The start date for which you want to get the exchange rates. The date must be specified in the `YYYY-MM-DD` format or `YYYY-MM-DDTHH:mm:ss` format. | - |
|
125
|
+
| **end_date** *(required)* | The end date for which you want to get the exchange rates. The date must be specified in the `YYYY-MM-DD` format or `YYYY-MM-DDTHH:mm:ss` format. | - |
|
126
|
+
| **accuracy** | Specifies the interval length of the requested time series:<br> - `day` - daily (Rates available for the last 365 days)<br> - `hours` - hourly (Rates available for the last 90 days)<br> - `15m` - every 15 minutes (Rates available for the last 7 days)<br> - `10m` - every 10 minutes (Rates available for the last 7 days)<br> - `5m` - every 5 minutes (Rates available for the last 7 days)<br> - `1m` - every 60 seconds (Rates available for the last 7 days) | `day` |
|
127
|
+
| **currencies** | Specifies the currencies you want exchange rates for. Multiple currencies can be separated with a comma. | All available currencies |
|
128
|
+
| **base** | Sets the currency in which exchange rates are quoted. All exchange rates are relative to this base currency. | `USD` |
|
129
|
+
| **amount** | The amount of the base currency to convert. | `1` |
|
130
|
+
| **places** | Specifies the number of decimal places in the response. By default, the most available decimal places for the currency are returned. | All available decimals |
|
131
|
+
|
132
|
+
### convert
|
133
|
+
|
134
|
+
`convert` calculates the conversion of 2 currencies.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
response = client.convert(from: 'USD', to: 'CAD', amount: 1000)
|
138
|
+
response.from
|
139
|
+
# "USD"
|
140
|
+
response.to
|
141
|
+
# "CAD"
|
142
|
+
response.amount
|
143
|
+
# 1000
|
144
|
+
response.result
|
145
|
+
# 1418.3401925
|
146
|
+
response.rate
|
147
|
+
# 1.4183401925
|
148
|
+
response.date
|
149
|
+
# "2025-02-15T00:07:00.000Z"
|
150
|
+
response.timestamp
|
151
|
+
# 1739578020
|
152
|
+
```
|
153
|
+
|
154
|
+
#### Available parameters
|
155
|
+
| Parameter | Description | Default |
|
156
|
+
| --------------------- |:------------------------------------------------------------------------------------------------------------- | ------------ |
|
157
|
+
| **date** | The date for which you want to get the exchange rates. The date must be specified in the `YYYY-MM-DD` format. | Current date |
|
158
|
+
| **from** *(required)* | The currency of the amount you are converting from. | - |
|
159
|
+
| **to** *(required)* | The currency you want to have the amount converted to. | - |
|
160
|
+
| **amount** | The amount of base currency you want to convert. | `1` |
|
161
|
+
| **places** | The number of decimal places in the response. | - |
|
162
|
+
|
163
|
+
|
164
|
+
### currencies
|
165
|
+
|
166
|
+
`currencies` returns the information of all available currencies from FXRatesAPI
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
client.currencies
|
170
|
+
```
|
171
|
+
|
172
|
+
### Raw response
|
173
|
+
|
174
|
+
For all above methods, you can call `#raw_response` to access te original JSON response
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
response = client.latest
|
178
|
+
response.raw_response
|
179
|
+
```
|
180
|
+
|
181
|
+
## Development
|
182
|
+
|
183
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
184
|
+
|
185
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
186
|
+
|
187
|
+
## Contributing
|
188
|
+
|
189
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kevinluo201/fx_rates.
|
190
|
+
|
191
|
+
## License
|
192
|
+
|
193
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "fx_rates"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/fx_rates.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "fx_rates/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fx_rates"
|
8
|
+
spec.version = FXRates::VERSION
|
9
|
+
spec.authors = ["Kevin Luo"]
|
10
|
+
spec.email = ["kevin.luo@hey.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{It is a wrapper gem for FXRatesAPI}
|
13
|
+
spec.description = %q{You can use this gem to call all APIs provided by FXRatesAPI with ease.}
|
14
|
+
spec.homepage = "https://github.com/kevinluo201/fx_rates"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
if spec.respond_to?(:metadata)
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = "https://github.com/kevinluo201/fx_rates"
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/kevinluo201/fx_rates"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
+
"public gem pushes."
|
24
|
+
end
|
25
|
+
|
26
|
+
# Specify which files should be added to the gem when it is released.
|
27
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
30
|
+
end
|
31
|
+
spec.bindir = "exe"
|
32
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ["lib"]
|
34
|
+
|
35
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
36
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
37
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
38
|
+
|
39
|
+
spec.add_runtime_dependency "zeitwerk", "~> 2.0"
|
40
|
+
spec.add_runtime_dependency "faraday", "~> 2.0"
|
41
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module FXRates
|
2
|
+
class Client
|
3
|
+
def initialize(api_key: nil)
|
4
|
+
@api_key = api_key || FXRates.config&.api_key
|
5
|
+
@requset = FXRates::Request.new(@api_key)
|
6
|
+
end
|
7
|
+
|
8
|
+
def latest(**params)
|
9
|
+
query = {}
|
10
|
+
query[:base] = params[:base] || 'USD'
|
11
|
+
query[:amount] = params[:amount] || 1
|
12
|
+
query[:places] = params[:places] if params[:places]
|
13
|
+
query[:resolution] = params[:resolution] if params[:resolution]
|
14
|
+
query[:currencies] = currencies_params(params[:currencies]) if params[:currencies]
|
15
|
+
|
16
|
+
Response::Rates.new(@requset.get('/latest', query))
|
17
|
+
end
|
18
|
+
|
19
|
+
def historical(**params)
|
20
|
+
query = {}
|
21
|
+
query[:date] = date_params(params[:date] || Time.now.utc)
|
22
|
+
query[:base] = params[:base] || 'USD'
|
23
|
+
query[:currencies] = currencies_params(params[:currencies]) if params[:currencies]
|
24
|
+
query[:amount] = params[:amount] || 1
|
25
|
+
query[:places] = params[:places] if params[:places]
|
26
|
+
|
27
|
+
Response::Rates.new(@requset.get('/historical', query))
|
28
|
+
end
|
29
|
+
|
30
|
+
def timeseries(start_date:, end_date:, accuracy: 'day', **params)
|
31
|
+
if !start_date.match?(/\d{4}-\d{2}-\d{2}/) && !start_date.match?(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)
|
32
|
+
raise ArgumentError, "Invalid start_date format. Must be in the YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss format"
|
33
|
+
end
|
34
|
+
if !end_date.match?(/\d{4}-\d{2}-\d{2}/) && !end_date.match?(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)
|
35
|
+
raise ArgumentError, "Invalid end_date format. Must be in the YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss format"
|
36
|
+
end
|
37
|
+
|
38
|
+
query = {
|
39
|
+
start_date: start_date,
|
40
|
+
end_date: end_date,
|
41
|
+
accuracy: accuracy
|
42
|
+
}
|
43
|
+
query[:currencies] = currencies_params(params[:currencies]) if params[:currencies]
|
44
|
+
query[:base] = params[:base] || 'USD'
|
45
|
+
query[:amount] = params[:amount] || 1
|
46
|
+
query[:places] = params[:places] if params[:places]
|
47
|
+
|
48
|
+
Response::Timeseries.new(@requset.get('/timeseries', query))
|
49
|
+
end
|
50
|
+
|
51
|
+
def convert(from:, to:, **params)
|
52
|
+
query = {
|
53
|
+
from: from,
|
54
|
+
to: to
|
55
|
+
}
|
56
|
+
query[:date] = (params[:date] || Time.now.utc).strftime('%Y-%m-%d')
|
57
|
+
query[:amount] = params[:amount] || 1
|
58
|
+
query[:places] = params[:places] if params[:places]
|
59
|
+
|
60
|
+
Response::Convert.new(@requset.get('/convert', query))
|
61
|
+
end
|
62
|
+
|
63
|
+
def currencies
|
64
|
+
@requset.get('/currencies')
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def date_params(date)
|
70
|
+
if date.is_a?(String)
|
71
|
+
if !date.match?(/\d{4}-\d{2}-\d{2}/)
|
72
|
+
raise ArgumentError, "Invalid start_date format. Must be in the YYYY-MM-DD"
|
73
|
+
end
|
74
|
+
|
75
|
+
return date
|
76
|
+
end
|
77
|
+
|
78
|
+
date.strftime('%Y-%m-%d')
|
79
|
+
end
|
80
|
+
|
81
|
+
def currencies_params(currencies)
|
82
|
+
currencies.is_a?(Array) ? currencies.join(',') : nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module FXRates
|
5
|
+
class Request
|
6
|
+
BASE_URL = "https://api.fxratesapi.com"
|
7
|
+
|
8
|
+
def initialize(api_key)
|
9
|
+
raise FXRates::AuthenticationError, "API key is required" if api_key.nil?
|
10
|
+
|
11
|
+
@api_key = api_key
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(path, params = {})
|
15
|
+
response = connection.get(path, params)
|
16
|
+
handle_response(response)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def connection
|
22
|
+
Faraday.new(
|
23
|
+
url: BASE_URL,
|
24
|
+
headers: {
|
25
|
+
"Authorization" => "Bearer #{@api_key}",
|
26
|
+
"Content-Type" => "application/json"
|
27
|
+
}
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle_response(response)
|
32
|
+
case response.status
|
33
|
+
when 200..299
|
34
|
+
JSON.parse(response.body)
|
35
|
+
when 401
|
36
|
+
raise FXRates::AuthenticationError, "Invalid API key"
|
37
|
+
else
|
38
|
+
raise FXRates::Error, "Unexpected error: #{response.reason_phrase}. Error message: #{response.body}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module FXRates::Response
|
2
|
+
class Convert
|
3
|
+
attr_reader :success, :from, :to, :amount, :rate, :date, :timestamp, :result, :raw_response
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@success = response["success"]
|
7
|
+
@from = response["query"]["from"]
|
8
|
+
@to = response["query"]["to"]
|
9
|
+
@amount = response["query"]["amount"]
|
10
|
+
@rate = response["info"]["rate"]
|
11
|
+
@date = response["date"]
|
12
|
+
@timestamp = response["timestamp"]
|
13
|
+
@result = response["result"]
|
14
|
+
@raw_response = response
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module FXRates::Response
|
2
|
+
class Rates
|
3
|
+
attr_reader :success, :rates, :timestamp, :date, :base, :raw_response
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@success = response["success"]
|
7
|
+
@rates = response["rates"]
|
8
|
+
@timestamp = response["timestamp"]
|
9
|
+
@date = response["date"]
|
10
|
+
@base = response["base"]
|
11
|
+
@raw_response = response
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module FXRates::Response
|
2
|
+
class Timeseries
|
3
|
+
attr_reader :success, :rates, :start_date, :end_date, :base, :raw_response
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@success = response["success"]
|
7
|
+
@rates = response["rates"]
|
8
|
+
@start_date = response["start_date"]
|
9
|
+
@end_date = response["end_date"]
|
10
|
+
@base = response["base"]
|
11
|
+
@raw_response = response
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/fx_rates.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "zeitwerk"
|
2
|
+
loader = Zeitwerk::Loader.for_gem
|
3
|
+
loader.inflector.inflect(
|
4
|
+
"fx_rates" => "FXRates",
|
5
|
+
)
|
6
|
+
loader.setup
|
7
|
+
|
8
|
+
module FXRates
|
9
|
+
class Error < StandardError; end
|
10
|
+
class AuthenticationError < Error; end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_accessor :config
|
14
|
+
|
15
|
+
def configure
|
16
|
+
self.config ||= FXRates::Configuration.new
|
17
|
+
yield(config) if block_given?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fx_rates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Luo
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-02-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: zeitwerk
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
description: You can use this gem to call all APIs provided by FXRatesAPI with ease.
|
84
|
+
email:
|
85
|
+
- kevin.luo@hey.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- bin/console
|
98
|
+
- bin/setup
|
99
|
+
- fx_rates.gemspec
|
100
|
+
- lib/fx_rates.rb
|
101
|
+
- lib/fx_rates/client.rb
|
102
|
+
- lib/fx_rates/configuration.rb
|
103
|
+
- lib/fx_rates/request.rb
|
104
|
+
- lib/fx_rates/response/convert.rb
|
105
|
+
- lib/fx_rates/response/rates.rb
|
106
|
+
- lib/fx_rates/response/timeseries.rb
|
107
|
+
- lib/fx_rates/version.rb
|
108
|
+
homepage: https://github.com/kevinluo201/fx_rates
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata:
|
112
|
+
homepage_uri: https://github.com/kevinluo201/fx_rates
|
113
|
+
source_code_uri: https://github.com/kevinluo201/fx_rates
|
114
|
+
changelog_uri: https://github.com/kevinluo201/fx_rates
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubygems_version: 3.0.3.1
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: It is a wrapper gem for FXRatesAPI
|
134
|
+
test_files: []
|