Currency Converter Using APIs

Python tutorial for creating a currency converter using APIs

Oliver Lövström
Internet of Technology
6 min readFeb 2, 2024

--

This article explores a practical and beginner-friendly project: building a currency converter using Python. This project is a great opportunity to get hands-on experience with Application Programming Interfaces (APIs). Let’s get started!

Photo by Jason Leung on Unsplash

Step 1: Getting your API key

For this project, we’ll use an API to obtain real-time currency exchange rates. I will be using Open Exchange Rates, but you can choose any exchange rate service. Sign up with your chosen service to obtain your API key.

Once you have your API key, you can test it using the URL provided in their documentation. For Open Exchange Rates:

https://openexchangerates.org/api/latest.json?app_id=<APP_ID>

Ensure to replace <APP_ID> with your actual API key. Remember to keep your API key hidden and don’t share it with others.

{
"disclaimer": "Usage subject to terms: https://openexchangerates.org/terms",
"license": "https://openexchangerates.org/license",
"timestamp": 1706810400,
"base": "USD",
"rates": {
"AED": 3.673,
"AFN": 73.500003,
...
"ZWL": 322
}
}

Step 2: Setting Up Our Environment

We’ll begin by importing some packages:

import argparse
from typing import Optional
import requests

This one is essential for our project:

  • requests for making HTTP requests to our API of choice

The following two are optional:

  • argparse for parsing command-line options and arguments
  • typing.Optional for optional type hints

Step 3: Fetching Exchange Rates

Our first function, fetch_usd_exchange_rate, connects to the API, and retrieves the exchange rate for a specified currency relative to USD. Here’s the function:

def fetch_usd_exchange_rate(api_url: str, target_currency: str) -> Optional[float]:
"""Fetch the USD exchange rate for a target currency.

:param api_url: API URL including the API key.
:param target_currency: The target currency to fetch the exchange rate for.
:return: The exchange rate for the target currency in USD or `None` if not found.
"""
try:
response = requests.get(api_url, timeout=120)
response.raise_for_status()
rates = response.json().get("rates", {})
return rates.get(target_currency, None)
except requests.RequestException as exception:
print(f"Failed to fetch exchange rates: {exception}")
return None

Step-by-step explanation:

  1. API Request: The function begins by sending a GET request to the provided API URL. The timeout parameter is set to 120 seconds to prevent hanging if the API service is unresponsive.
  2. Error Handling: response.raise_for_status() is called immediately after the request. This method throws an error if the request results in an HTTP error (status code 400 or higher). This is enclosed in a try block to catch these exceptions.
  3. Parsing the Response: If the request is successful, the function parses the JSON response to access the rates dictionary, which contains currency exchange rates.
  4. Getting the Rate: The function attempts to retrieve the exchange rate for the specified target_currency from the rates dictionary. If the currency code exists, its value (exchange rate) is returned.
  5. Handling Exceptions: If an exception occurs during the request, the except block catches the requests.RequestException.
  6. Return Value: The function returns the exchange rate for the target_currency if found; otherwise, it returns None.

Step 4: Converting Currency

Next, we’ll create the function convert_currency to make the conversion:

def convert_currency(api_url: str, amount: float, target_currency: str) -> Optional[float]:
"""Convert the amount using the provided exchange rate in USD.

:param api_url: API URL including the API key.
:param amount: The amount to convert.
:param target_currency: The target currency to fetch the exchange rate for.
:return: The amount in the target curreny.
"""
rate = fetch_usd_exchange_rate(api_url, target_currency)
if rate is not None:
return amount * rate
return None

How it works:

  1. Get the Exchange Rate: The function begins by calling fetch_usd_exchange_rate with the api_url and target_currency. This call fetches the current exchange rate for converting USD to the target currency.
  2. Perform the Conversion: If the exchange rate is retrieved (i.e., not None), the function calculates the converted amount by multiplying the amount by the rate.
  3. Return the Result: The function returns the calculated converted amount.

Step 5: Bringing It All Together

We’ll bring it all together by defining a main function and an entry point for our script:

Main function:

def main(api_url: str) -> None:
"""Main function for the currency converter.

:param api_url: API URL including the API key.
"""
while True:
target_currency = input("Convert USD to currency (Type 'exit' to quit): ")
if target_currency.lower() == "exit":
break

try:
amount = float(input("Amount in USD: "))
target_amount = convert_currency(api_url, amount, target_currency)
if target_amount is not None:
print(f"{amount} USD is {target_amount} {target_currency}.")
else:
print(
"Failed to convert currency. Please check your inputs and try again."
)
except ValueError:
print("Please enter a valid amount.")

Let’s go through the code:

  1. User Input: The main function loops indefinitely, prompting the user to specify a currency they wish to convert USD into. The loop exits when the user types "exit".
  2. Currency Conversion: convert_currency is called with the API URL, the amount to convert, and the target currency. The resulting amount in the target currency is displayed if the conversion is successful.

Entry point:

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Currency Converter")

API_URL_HELP = "URL to the currency conversion API including the API key"
parser.add_argument("api_url", type=str, help=API_URL_HELP)

args = parser.parse_args()
main(args.api_url)

Let’s break it down:

This code sets up command line argument parsing, which accepts the API URL as an input. When the script is executed, it parses the command line for the API URL and then calls the main function.

Step 6: Testing Our Currency Converter

Our currency converter script is complete. Let’s test it!

Follow these steps to test the script:

  1. Prepare the Script: Make sure the script is saved (for example, as currency_converter.py) and that all necessary dependencies (see imports section) are installed in your Python environment.
  2. Run the Script: Open your terminal or command prompt -> Navigate to the directory containing the script -> Run the script by executing the following command, replacing "API_URL" with your actual API URL.
$ python currency_converter.py "API_URL"
Convert USD to currency (Type 'exit' to quit): SEK
Amount in USD: 100
100.0 USD is 1039.6924999999999 SEK.
Convert USD to currency (Type 'exit' to quit): exit

Full Code

You can find the complete code for this project on GitHub or you can see it below:

"""Curreny converter."""
import argparse
from typing import Optional
import requests


def fetch_usd_exchange_rate(api_url: str, target_currency: str) -> Optional[float]:
"""Fetch the USD exchange rate for a target currency.

:param api_url: API URL including the API key.
:param target_currency: The target currency to fetch the exchange rate for.
:return: The exchange rate for the target currency in USD or `None` if not found.
"""
try:
response = requests.get(api_url, timeout=120)
response.raise_for_status()
rates = response.json().get("rates", {})
return rates.get(target_currency, None)
except requests.RequestException as exception:
print(f"Failed to fetch exchange rates: {exception}")
return None


def convert_currency(
api_url: str, amount: float, target_currency: str
) -> Optional[float]:
"""Convert the amount using the provided exchange rate in USD.

:param api_url: API URL including the API key.
:param amount: The amount to convert.
:param target_currency: The target currency to fetch the exchange rate for.
:return: The amount in the target curreny.
"""
rate = fetch_usd_exchange_rate(api_url, target_currency)
if rate is not None:
return amount * rate
return None


def main(api_url: str) -> None:
"""Main function for the currency converter.

:param api_url: API URL including the API key.
"""
while True:
target_currency = input("Convert USD to currency (Type 'exit' to quit): ")
if target_currency.lower() == "exit":
break

try:
amount = float(input("Amount in USD: "))
target_amount = convert_currency(api_url, amount, target_currency)
if target_amount is not None:
print(f"{amount} USD is {target_amount} {target_currency}.")
else:
print(
"Failed to convert currency. Please check your inputs and try again."
)
except ValueError:
print("Please enter a valid amount.")


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Currency Converter")

API_URL_HELP = "URL to the currency conversion API including the API key"
parser.add_argument("api_url", type=str, help=API_URL_HELP)

args = parser.parse_args()
main(args.api_url)

Further Reading

If you want to learn more about programming and, specifically, Python and Java, see the following course:

Note: If you use my links to order, I’ll get a small kickback. So, if you’re inclined to order anything, feel free to click above.

--

--