Currency Converter App with APILayer’s Fixer API and PyQt Framework

Yavuz ERTUĞRUL
Level Up Coding
Published in
10 min readDec 19, 2023

--

created with Dall-E 3 by author with ❤

Have you ever found yourself in need of a quick currency conversion, maybe while planning a vacation or during an international online shopping spree? Currency converter application will be there for you.

Hi there, I’m welcoming you from another post in my learning journey. I want start with saying thank you to all developers around you are making life easier. My latest project? A handy currency converter app.

Building this app was like putting together a puzzle, where each piece was a new learning experience, every step was a journey. And the best part? I combined my passion for coding with real-world application.

In the following paragraphs, I’ll share how I created this app. From the initial idea to the final product, it was fun, I hope you will also like it.

What is Json?

JSON, short for JavaScript Object Notation, is something I often encounter and work with in my programming projects. It’s a format for storing and transporting data, and I find it incredibly handy. Why? Because JSON structures data in a way that’s both easy for us humans to read and write, and easy for machines to parse and generate.

To me, JSON is like the digital equivalent of a well-organized filing cabinet. Each piece of data is stored in a structured format, quite similar to a dictionary. It has keys (like labels on a file) and values (the contents of the file). For instance, in a JSON file storing user information, ‘name’ would be a key, and ‘John Doe’ could be its corresponding value. For example let’s see who is John Doe:

{

“Name”: “John”,

“Surname”: “Doe”,

“Phone_Number” :3454543,

“Features”: {
“hobby”: “playing games”,

“job”: “Instructor”

}

}

Let’s say I’m using an API to fetch some data. More often than not, this data comes in JSON format. I can easily access this information, thanks to the structured format of JSON. If I want to find a user’s name, I simply look up the value associated with the key ‘name’. It’s this straightforward nature that makes JSON a go-to choice for developers.

Now, regarding Fixer.io, it’s a handy tool for anyone needing currency conversion data. The free version of Fixer.io provides essential functionalities, like real-time exchange rates and historical data for a limited number of currencies. It’s perfect for new learners, small projects or personal use where basic currency conversion data is sufficient.

However, the free version does come with its limitations. For instance, there’s a cap on the number of monthly API calls with 1000, and the data might not be as frequently updated as in the paid versions it is updated hourly. The premium plans, on the other hand, offer more features, like more currencies, more frequent updates, and additional data points like fluctuation information. These advanced features are particularly useful for businesses or applications that require more detailed financial data and higher request volumes.

Accessing and using the Fixer.io API is pretty straightforward. They provide clear documentation, and since the API returns data in JSON format, it’s easy to integrate into most web projects. The simplicity of JSON really shines here, as I can quickly parse the data and use it as needed in my application.

Note: For the most current and detailed information about Fixer.io’s offerings and the specific differences between their free and premium plans, I recommend checking their official website or contacting their support team, as the features and limitations can change over time.

created with Dall-E 3 by author with ❤

What is API?

Whenever I dive into the world of development, another term that constantly pops up is ‘API’, which stands for Application Programming Interface. But what does that really mean? Well, I like to think of an API as a menu in a restaurant. It’s a list of ‘dishes’ — or in this case, services and data — that a software program offers. Just like how I’d order a meal, my software requests specific information or services from another application or server using its API.

For me, the real magic of APIs lies in their ability to bridge the gap between different software systems. They’re like a common language that lets my applications talk to each other, exchange information, and even make requests. This communication is crucial, especially in today’s interconnected digital world where different applications need to work together seamlessly.

One aspect of APIs that makes my life easier is their abstraction. They hide all the complex, nitty-gritty details of their internal workings. It’s similar to driving a car; I don’t need to know every mechanical detail under the hood. I just need to know how to use the steering wheel, accelerator, and brakes. APIs work the same way — I use the ‘controls’ they provide without worrying about how they do what they do.

What is REST API?

REST, which stands for Representational State Transfer, is like a set of guidelines for creating smooth, efficient online conversations. It’s all about simplicity and using familiar web standards. For instance, when my application needs to fetch data, it uses a REST API through a straightforward HTTP request, much like how we browse websites.

The real beauty of REST APIs lies in their approach to handling resources, like the data or services offered by a server. They use simple URLs for these resources, and four basic actions — think of them as the web’s equivalent of create, read, update, and delete. This makes them incredibly intuitive. I use GET to grab data, POST to add something new, PUT to update it, and DELETE to, well, delete it.

Now, let’s talk about Fixer API. It’s a classic example of a REST API in action. It offers real-time exchange rates provided by the European Central Bank. The way it’s structured and the methods it uses for data retrieval and manipulation are REST. It’s streamlined and user-friendly, allowing me to interact with it using straightforward HTTP requests.

How to Use API?

First of all, let’s go over the documentation together on how to use this API

Documentation site has all we need so first you need to sign up and get API KEY which is crucial for us to use the service.

data.fixer.io/api/latest?access_key={your API key is going here} with running API Requst we get these dictionary like output:

JSON Output of API Request — Screenshot by author

So we will use these to create our convert currency app. In the following, we have error codes in case you get error check here.

Error Codes of Fixer API — Screenshot by author

We need 3 parameters to do conversion it is not required in API request but we need it for our application to get conversion rate.

Request Parameters Fixer API — Screenshot by author

Endpoint URLs

http://data.fixer.io/api/latest?access_key={YOUR_ACCESS_KEY}&base={base currency}&symbols={target currency}

For more detail I recommend you to check their documentation I am putting the links you can use: Quickstart Guide, API Documentation, Usage Statistics

What is Qt and PyQt5 ?

Currency Converter App — Screenshot by author

Let’s take a trip to an amusement park to understand what PyQt and PyQt5 are all about. Think of Qt as amusement park filled with various exciting rides and attractions. These rides represent different tools you can use to build applications. However, there’s a catch: all the instructions for the rides are in a language that’s quite complex to understand (e.g this language being C++).

Now, imagine if you had a special guidebook that translated all these instructions into a language you’re comfortable with. This guidebook is PyQt. It translates world of Qt into Python, a language known for its simplicity and ease of use.

PyQt5 is one of the latest edition of this guidebook. It’s updated with the newest rides and attractions. Using PyQt5, I can easily choose and enjoy the most advanced features in the Qt amusement park, but with the simplicity and comfort of Python. Whether I want build complex application or create a simple app, PyQt5 makes the experience straightforward and fun.

created with Dall-E 3 by author with ❤

If you are just starting out, PyQt5 is an invaluable resource. It allows you to explore the vast possibilities of software development in a user-friendly environment.

COMPLETE CODE

Designing and stuff — Screenshot by author

Importing and Initiating

Designing GUI with QtDesigner — Screenshot by author

In this part, I’m loading the GUI, tailoring the app window, initializing variables for both currency conversion and the GUI, and enhancing user interaction within the app.

import sys
import time
import requests
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QMessageBox

class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
uic.loadUi('currency_converter.ui', self) # This will load ui which we created with QtDesigner
self.setWindowTitle("Currency Converter App")
self.setFixedSize(703, 503)

# Initialize currency rate
self.rate = None

#Defining Variables on the GUI
self.base_currency = self.findChild(QtWidgets.QComboBox, 'base_comboBox')
self.target_currency = self.findChild(QtWidgets.QComboBox, 'target_comboBox')
self.base_value = self.findChild(QtWidgets.QLineEdit, 'basevalue_lineEdit')
self.target_value = self.findChild(QtWidgets.QLineEdit, 'targetvalue_lineEdit')
self.rate_currency = self.findChild(QtWidgets.QLineEdit,'currencyrate_lineEdit')

#Operations
self.base_currency.currentIndexChanged.connect(self.currency_changed)
self.target_currency.currentIndexChanged.connect(self.currency_changed)
self.base_value.editingFinished.connect(self.update_conversion_rate)
time.sleep(4)
self.base_value.editingFinished.connect(self.convert_currency)

Updating Conversion Rate

In this part of the code for currency converter app, I’m handling the crucial task of updating the conversion rate. First, I define my API key for accessing the currency data. Then, I fetch the selected currencies from the combo boxes in the GUI, which are the base and target currencies for conversion.

Next, I construct the URL for the API request, dynamically inserting the chosen base and target currencies along with my API key. The request is sent using requests.get, and the response, in JSON format, is stored.

I then extract the conversion rate from this response. If the API call is successful, the app updates the conversion rate. In case the rate is unavailable, or the target currency is not supported, the app shows an error message. Additionally, if there’s any other type of API error, like incorrect parameters or server issues, the app displays the specific error details.

This code is vital for keeping the app’s data current, ensuring that users always get the latest conversion rates based on their selected currencies.

def update_conversion_rate(self):
api_key = "YOUR API KEY GOES HERE"

base_index = self.base_currency.currentIndex()
self.base_text = self.base_currency.itemText(base_index)

target_index = self.target_currency.currentIndex()
self.target_text = self.target_currency.itemText(target_index)

if self.base_text and self.target_text:
url ="http://data.fixer.io/api/latest?access_key={}&symbols={}&base={}".format(api_key, self.target_text, self.base_text)
response = requests.get(url)
self.data = response.json()

if self.data["success"]:
self.rate = self.data['rates']["{}".format(self.target_text)]
self.rate_currency.setText("{:.2f}".format(self.rate))
if self.rate is None:
QMessageBox.critical(self, "API Error", f"Target currency {self.target_text} is not supported.")
else:
self.rate = None
error_info = self.data.get('error', {})
QMessageBox.critical(self, "API Error", f"Error {error_info.get('code')}: {error_info.get('info')}")
else:
QMessageBox.critical("Select Currencies you want to do conversion")

Converting the Currency

created with Dall-E 3 by author with ❤

The currency_changed() function is straightforward. Whenever a user selects a different base or target currency, this function clears the input and output on the GUI. This reset ensures that old values don’t interfere with new calculations when the currency selection changes.

The convert_currency() function is where the core action happens. It kicks in when there’s a need to convert an amount from the base currency to the target currency. First, it checks if the conversion rate (self.rate) is available.

If it is, the function attempts to convert the entered amount (grabbed from base_value) using this rate. The result is displayed on the GUI. To handle scenarios where the user might enter invalid data (like text instead of numbers), I’ve included a try-except block. If the input isn’t a valid number, the app shows a warning and clears the output field.

There’s also a provision for cases where the conversion rate might not be available — maybe due to an issue with the API or an unsupported currency. In such cases, the app alerts the user and clears both input and output fields, readying the app for another attempt once the issue is resolved.

Overall, these functions ensure my app is responsive, accurate, and user-friendly, providing a seamless experience in currency conversion.

def currency_changed(self):
self.base_value.clear()
self.target_value.clear()

def convert_currency(self):
# Check if rate is available
if self.rate is not None:
try:
amount = float(self.base_value.text())
converted_amount = self.rate * amount
self.target_value.setText("{:.2f}".format(converted_amount))
except ValueError:
QMessageBox.warning(self, "Input Error", "Please enter a valid amount.")
self.target_value.clear()
else:
QMessageBox.warning(self, "Conversion Error", "Conversion rate not available. Please check the base currency and try again.")
self.base_value.clear()
self.target_value.clear()

Main Part

This part is also straightforward, it is starting the application and opening the application.

if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Currency Converter App — Screenshot by author

Thank you for taking the time to read through this piece. I’m glad to share these insights and hope they’ve been informative. If you enjoyed this article and are looking forward to more content like this, feel free to stay connected by following my Medium profile. Your support is greatly appreciated. Until the next article, take care and stay safe! For all my links in one place, including more articles, projects, and personal interests, check out.

--

--