• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar
  • Skip to footer
WebSetNet

WebSetNet

Technology News

  • Technology News
    • Mobile
    • Games
  • Internet Marketing
  • System Admin
    • Windows
    • Linux
    • Mac & Apple
    • Website Scripts
      • Wordpress

Using Groovy to access and parse an exchange rate API

August 5, 2020 by Martin6

 

A groovy way to simplify bookkeeping: a step-by-step guide to converting currency exchange using Apache Groovy.

Using Groovy to access and parse an exchange rate API

 

Get the newsletter

Join the 85,000 open source advocates who receive our giveaway alerts and article roundups.

I live in Canada and do a fair bit of work in other countries, so when I do my bookkeeping, I have to convert revenue and expenses in foreign currencies to Canadian dollars. I used to do this by laboriously looking up historical exchange rates at the Bank of Canada, but last year the bank reduced the number of currencies it supports. I decided to look for a different and more practical solution, using a website that publishes historical data on currency exchange rates and Apache Groovy, a programming language for the Java platform.

I found two foreign exchange history sites that permit some degree of free access in the form of calls to their APIs that return results in JSON, so I wrote a small script in Groovy to parse the JSON and give me back the info I need to enter in my bookkeeping program. Here’s how I did it.

Exchange rate sites and their APIs

The first site I found is Fixer.io, which I really like. It is a free service that accesses data from the European Central Bank. The API is straightforward and simple to use. For example, if I want exchange rates for Canadian dollars and Indian rupees, I use the following URL:

https://api.fixer.io/latest?symbols=CAD,INR

which, when I ran that query for this article, returned the following JSON:

{
"base":"EUR",
"date":"2018-02-15",
"rates":{"CAD":1.5604,"INR":79.849}
}

This shows that on Feb. 15, 2018, it took 1.5604 Canadian dollars to buy 1 euro and it took 79.849 Indian rupees to buy 1 euro. To figure out how many Indian rupees it took to buy 1 Canadian dollar, just divide 79.849 by 1.5604 to arrive at 51.172 Indian rupees per Canadian dollar. What could be easier?

Even better, Fixer.io is open source, published under the MIT License, and the code is available on GitHub.

Fixer.io addressed my need to convert Indian rupees to Canadian dollars, but unfortunately, it does not offer a solution for Chilean pesos, since the base data at the European Central Bank covers “only” 32 currencies.

To get information on Chilean pesos, I ended up at Currencylayer, which (at this time) provides data for 168 currencies. Currencylayer requires registration and charges a fee for its more valuable products and complex operations, but basic historical exchange rate conversion between U.S. dollars and 167 other currencies is free. Because of its broad coverage, I used Currencylayer to write this article.

Registering at Currencylayer gives the user a key that grants access to the tier of services selected. Assuming the key is K, then a URL like:

http://apilayer.net/api/historical?access_key=K&date=2018-01-01&currencies=CAD,EUR&format=1

will return the following JSON:

{
"success":true,
"terms":"https://currencylayer.com/terms",
"privacy":"https://currencylayer.com/privacy",
"historical":true,
"date":"2018-01-01",
"timestamp":1514851199,
"source":"USD",
"quotes":{
"USDCAD":1.25551,
"USDEUR":0.832296
}
}

Using Groovy to access the API and parse the JSON results

Groovy provides some concise tools for dealing with URLs, streams of data, and JSON.

Starting at the JSON end, there is the JSON slurper and its handy parse() method. One form of the JSON slurper parse method takes a stream as its argument.

This is handy because, starting at the URL end, we can open a stream on a URL with its newInputStream() method.

Assuming we have built the URL string, that is, the API call, in a Groovy string variable called urlString, we can open the URL, read the stream produced, and parse the JSON with the following Groovy code:

def result = (new JsonSlurper()).parse(
new InputStreamReader(
(new URL(urlString)).newInputStream()
)
)

The Groovy variable result is a map (that is, a set of key-value pairs) and looks like this:

[success:true, terms:https://currencylayer.com/terms, 
privacy:https://currencylayer.com/privacy, historical:true, 
date:2018-01-01, timestamp:1514851199, source:USD, quotes:
[USDCAD:1.25551, USDEUR:0.832296]]

This map corresponds precisely to the raw JSON shown above. For example, the key date has the value 2018-01-01.

Groovy allows us to access the value assigned to the date key either by:

result['date']

or

result.date

either of which will return the value 2018-01-01.

Note that the key quote refers itself to a map with two keys: one that gives the conversion between U.S. and Canadian dollars, the other that gives the conversion between U.S. dollars and the other currency of interest. In the above case, these can be accessed by

result['quotes']['USDCAD'] and
result['quotes']['USDEUR']

or

result.quotes.USDCAD and
result.quotes.USDEUR.

Using the latter format, and assuming the original amount is in a Groovy variable amtOrig, the amount in Canadian dollars can be calculated as:

def amtCAD = amtOrig / result.quotes.USDEUR * result.quotes.USDCAD

If I need to convert U.S. dollar expenses incurred while passing through DFW airport, for example, the formula is simpler:

def amtCAD = amtOrig * result.quotes.USDCAD

That’s really all there is to it.

The (almost) working script

Let’s turn it into a working Groovy script. We’ll get the arguments from the command line and check them. Then if all looks good, we’ll build the URL string, call the API, and get the result in map format. Finally, we’ll pull apart the result map and calculate the exchange. Here’s the script:

import groovy.json.JsonSlurper
// Check to make sure arguments are correct and print usage if not
if (args.size() != 3) {
System.err.println "usage: groovy fx.groovy yyyy-mm-dd amount currency-code"
System.exit(1)
}
// Check arguments for formatting and reasonable values
String dateString = args[0]
if (!(dateString ==~ /(19dd|2[01]dd)-(0[1-9]|1[012])-([012]d|3[01])/)) { 1
System.err.println "fx.groovy date $dateString not in format yyyy-mm-dd"
System.exit(1)
}
String amountString = args[1]
if (!(amountString ==~ /d+(.d+)?/)) { 1
System.err.println "fx.groovy amount $amountString not numeric"
System.exit(1)
}
String currencyCode = args[2]
if (!(currencyCode ==~ /[A-Z][A-Z][A-Z]/)) { 1
System.err.println "fx.groovy currency-code $currencyCode not three capital letters, e.g. USD,CAD,EUR,GBP"
System.exit(1)
}
// Our free license will only convert through USD so we adjust the currency list 
// according to whether the original currency was USD or something else
String currencyCodeList = currencyCode == 'USD' ? 'CAD' : "CAD,${currencyCode}" 2
// The access key code given during site signup
String accKey = 'a5bd4434d2299ecb3612ad297402481c' 3
// Build the URL string for the API call, get the JSON and parse it
String urlString = "http://apilayer.net/api/historical?access_key=$accKey&date=${dateString}&currencies=${currencyCodeList}&format=1" 2
def result = (new JsonSlurper()).parse(new InputStreamReader((new URL(urlString)).newInputStream()))
// Pick apart the values returned and compute the exchange info
BigDecimal amtOrig = new BigDecimal(amountString) 4
if (result.quotes.size() > 1) {
String toUSDString = 'USD' + currencyCode
BigDecimal amtCAD = amtOrig / result.quotes[toUSDString] * 5
result.quotes.USDCAD 
println "$amtOrig $currencyCode toUSD ${result.quotes[toUSDString]} toCAD ${result.quotes.USDCAD} $amtCAD" 2
} else {
BigDecimal amtCAD = amtOrig * result.quotes.USDCAD 
println "$amtOrig $currencyCode toCAD ${result.quotes.USDCAD} $amtCAD" 2
}

A few comments:

  1. Those are regular expression pattern matches. Yes, I could have used try... catch blocks.
  2. The notation ... ${foo}... is called a Gstring in Groovy; the thing in ${} is evaluated, and that value replaces it in the final string.
  3. That’s not my access key! But it looks kind of like it.
  4. I’m using BigDecimal rather than double to carry out my calculations.
  5. I’m using [toUSDString] to access the value; this is because toUSDString is a variable, not a constant string.
  6. Long lines have wrapped around somewhat. Sorry about that!

If you haven’t used Groovy much, some of the above will probably seem a bit magical, but it’s not—really. I hope this encourages further study!

Note that people working with U.S. dollars as their base don’t have to go through the intermediate computations.

And a final, cautionary comment: These and other historical exchange rates are indicative, generally computed from averages of other figures. So, if it cost you 2,623 Czech koruna to purchase 100 Euro on Feb 15, 2018, but Fixer.io gives you an exchange rate of 25.370 Czech koruna to the Euro on that date, it’s not an error! You may have paid a different amount at a different financial institution.

 

Source

Related posts:

  1. Google Messages prepares end-to-end encryption for RCS, Google Fi integration, manual cloud restores
  2. How To Start A Premium WordPress Blog (Step-by-Step Guide)
  3. Google Assistant prepares to add a “Memory” feature and earnings call alerts
  4. How to Pretty Print JSON File in Linux Terminal
  5. NVIDIA GeForce RTX 2080 and RTX 2080 Ti Review
  6. MSI GeForce RTX 2080 DUKE OC 8 GB Graphics Card Review – $829.99 US For Tri-Frozr Cooler on Founders Edition PCB
  7. Asus ROG Strix GL504 SCAR II review (GL504GM – i7-8750H, GTX 1060)
  8. To Grow Search Traffic, Add JSON-LD
  9. Streamlined, Fully Customizable Web Scraping with Zenscrape (Review)
  10. Dell XPS 13 9370 review (i7-8550U, FHD screen) – an upgrade, but not across the board

Filed Under: Uncategorized

Primary Sidebar

Trending

  • How to fix Windows Update Error 80244019
  • Windows 10 Update keeps failing with error 0x8007001f – 0x20006
  • How To Change Netflix Download Location In Windows 10
  • Troubleshoot Outlook “Not implemented” Unable to Send Email Error
  • How do I enable or disable Alt Gr key on Windows 10 keyboard
  • How To Install Android App APK on Samsung Tizen OS Device
  • 3 Ways To Open PST File Without Office Outlook In Windows 10
  • FIX: Windows Update error 0x800f0986
  • How to Retrieve Deleted Messages on Snapchat
  • Latest Samsung Galaxy Note 20 leak is a spec dump revealing key features
  • Install Android 7.0 Nougat ROM on Galaxy Core 2 SM-G355H
  • 192.168.1.1 Login, Admin Page, Username, Password | Wireless Router Settings
  • Websites to Watch Movies Online – 10+ Best Websites Without SignUp/Downloading
  • How to Backup SMS Messages on Your Android Smartphone
  • How to delete a blank page at the end of a Microsoft Word document
  • Fix: The Disc Image File Is Corrupted Error In Windows 10
  • Android 11 Custom ROM List – Unofficially Update Your Android Phone!
  • Samsung Galaxy Z Fold 3 could be scheduled for June 2021, with S Pen support

Footer

Tags

Amazon amazon prime amazon prime video Apple Application software epic games Galaxy Note 20 Galaxy S22 Plus Galaxy S22 Ultra Google Sheets headphones Huawei icloud Instagram instant gaming ip address iPhone iphone 12 iphone 13 iphone 13 pro max macOS Microsoft Microsoft Edge Mobile app office 365 outlook Pixel 6 Samsung Galaxy Samsung Galaxy Book 2 Pro 360 Samsung Galaxy Tab S8 Smartphone speedtest speed test teams tiktok Twitter vpn WhatsApp whatsapp web Windows 10 Windows 11 Changes Windows 11 Release Windows 11 Update Windows Subsystem For Android Windows 11 Xiaomi

Archives

  • June 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org