Dealing with multiple currencies or FX rates in python is a common challenge for many applications such as for ecommerce sites fintech applications, or simply some clever bots that analyze the markets. It is fairly straight forward to get currency data and to manipulate them using python.
The versatility of the Python language allows us to not only get the rates but also create a currency converter with the aid of APIs that are readily available.
In this article, we are going to look at currency rates APIs, how we can use them, and build our own currency converter.
What is an API?
API stands for application programming interface. It allows programs to communicate and share data. It is like a railroad track using which data can be transferred from one terminal to another terminal.
API data is often transmitted in JSON (JavaScript Object Notation) format which is a human readable format that helps to manage data easily. Python comes with modules that are designed to handle that operation – namely requests
and json
.
Choosing an API
There are numerous currency rate APIs – some you can use right away and others requiring you to get an API key. The API you decide to use is completely up to you. For the purpose of this article, we will use these two APIs to illustrate an issue you may come across.
How to Build a Currency Converter using RestAPI.IO
We will start with a program that converts only two currency pairs – in this case, the United States Dollar (USD) and the Euro (EUR). The RestAPI.io service provides a straightforward mechanism to get the conversion by simply sending the base currency (the currency you are converting from) to the target currency (the currency you are converting to). Here is the sample code:
import requests
import json
def main():
payload={"base":"USD","symbols":"EUR"}
response=requests.get('https://api.ratesapi.io/api/latest', params=payload)
if response.status_code !=200:
print("Status Code :",response.status_code)
raise Exception("There was an error accessing the web")
print("Header:", response.headers['Content-Type'])
data=response.json()
print("JSON data",data)
if __name__ == "__main__":
main()
In this program, we import requests
and json
then create a function main()
:
- We then create a variable that sets the base currency and the currency we want to convert to (“payload”) in a dictionary format
- We use the
get
method ofrequests
and pass the API URL and the variable we created earlier – notice we send the dictionary data which gets converted to URL query string. e.g. in the above example, the URL gets sent as: https://api.ratesapi.io/api/latest?base=USD&symbols=EUR. You can even test the url out where you can get the result through your browser:

- We have to check if we got a response from the API – 200 code – if we don’t, print the status code and an error message. The 200 code is the success code returned by web browsers.
- If we got a response, print out the header information we fetched
- We use
json
to convert the JSON data to a dictionary and output that as well

The program works well, but if we wanted to compare different currencies we would have to modify the code. We need a way to choose what currency rate we want to compare against the base we would have set.
NOTE: A 200 response code indicates successful communication to the API
Let’s see how we can make something a bit better:
import requests
def currency_converter():
old_or_latest = input("Do you want the latest or historical value?\n"
"if latest, please type 'latest' or else type historical value in '%Y-%m-%d' format: ")
base_URL_new = 'https://api.ratesapi.io/'+old_or_latest
response = requests.get(base_URL_new, params='base=USD')
if response.status_code == 200:
data,base_value, Date = response.json().items()
print('Available Currency\n>>', data[1].keys())
desired_currency = input("Please provide the currency code\n>>>").upper()
print(f'{desired_currency}:{data[1][desired_currency]} | base:{base_value[1]} | date:{Date[1]}')
convert = input('Do you want to convert the '+ desired_currency+ ' value to USD?\t yes or no: ')
if convert == 'yes' or convert == 'y':
value = float(input("value\n>>>"))
USD_value = value/float(data[1][desired_currency])
print(f'The value is:\t ${USD_value}')
else:
print("\nThank you")
else:
print ("\nPlease give the correct data")
currency_converter()
This program is more functional than the previous one. Unlike the first, it asks the user if they want the latest rates data or from a specific point in time.
- Using the get method, we pass the new API URL and the base currency. When you call restAPI with just the base currency code, the API will in fact return all the rates that currency can convert to. See this example of what happens when the API is called with just USD:

- We then make the check to see if the response we receive is 200
- If it was, we fetch the JSON data, convert it to a dictionary, and output the dictionary keys – the currency code
- We ask the user to select a currency they would like to compare against the base – that rate is outputted along with the date
- In addition, we ask if they would like to convert a specific amount – we perform that calculation and output that as well

We are able to get more information from the API and perform additional tasks with it. A better converter, yes? There is something else we can do to our code, specifically to handle errors that may arise when we make API calls.
How to Handle Errors from API calls
If an error occurs when we try to get the API data, we do not want to display an error message a user would not understand. We avoid that by nesting the line of code when we make the call in a try/except
block. In this example, we will use exchangerates.io
We will make slight modifications to our converter:
import requests
import sys
def currency_converter():
old_or_latest = input("Do you want the latest or historical value?\n"
"if latest, please type 'latest' or else type historical value in '%Y-%m-%d' format: ")
base_URL_new = 'https://api.ratesapi.io/'+old_or_latest
try:
response = requests.get(base_URL_new, params='base=USD')
except:
print("Unable to reach API")
sys.exit()
if response.status_code == 200:
data,base_value, Date = response.json().items()
print('Available Currency\n>>', data[1].keys())
desired_currency = input("Please provide the INR or other currency value\n>>>").upper()
print(f'{desired_currency}:{data[1][desired_currency]} | base:{base_value[1]} | date:{Date[1]}')
convert = input('Do you want to convert the '+ desired_currency+ ' value to USD?\t yes or no: ')
if convert == 'yes' or convert == 'y':
value = float(input("value\n>>>"))
USD_value = value/float(data[1][desired_currency])
print(f'The value is:\t ${USD_value}')
else:
print("\nThank you")
else:
print ("\nPlease give the correct data")
currency_converter()
We have additionally imported sys
. Instead of outright making the get
request, we have nested that in a try block. The way that works is:
- We will try to
- If that is successful the rest of the program executes
- If not, the except block will run – where we output a message and exit the program
To show the output if such an error occurs, I have intentionally modified the API URL so the get request fails.

This is a much better error message that doesn’t leave the user confused.
NOTE: Some currency rate APIs hace a limit to the number of calls you can make to them per day.
We have seen what APIs are, used two such APIs to fetch currency rate data. We have also used that data to create our own currency converters.
Get Notified Automatically Of New Articles
Error SendFox Connection: