DEV Community

Cover image for How to Build an Advanced ATM System Using Python, SQLite, Tkinter, and APIs
Code WithDhanian
Code WithDhanian

Posted on

How to Build an Advanced ATM System Using Python, SQLite, Tkinter, and APIs

Creating an ATM system is an excellent way to combine programming concepts with real-world applications. In this article, we’ll build a full-fledged ATM system with advanced features using:

  • Python for the core logic.
  • SQLite for database integration.
  • Tkinter for a graphical user interface (GUI).
  • APIs for real-time functionalities like currency conversion.

By the end, you’ll have a working ATM system with a modern interface and backend logic. Let’s dive in!

Step 1: Setting Up the Backend with SQLite

The backend serves as the core of our system. Using SQLite, we’ll create a database to store account information securely.

import sqlite3

class ATM:
    def __init__(self):
        self.connection = sqlite3.connect("atm_database.db")
        self.cursor = self.connection.cursor()
        self._create_tables()

    def _create_tables(self):
        self.cursor.execute("""
        CREATE TABLE IF NOT EXISTS accounts (
            account_number TEXT PRIMARY KEY,
            pin TEXT NOT NULL,
            balance REAL DEFAULT 0,
            transaction_history TEXT
        )
        """)
        self.connection.commit()
Enter fullscreen mode Exit fullscreen mode

Features:

  • Account Management: Store account details like account number, PIN, and balance.
  • Transaction History: Log all transactions for better tracking.

Step 2: Implementing Core ATM Operations

Next, we’ll add the main functionalities like creating accounts, depositing money, withdrawing money, and checking balances.

def create_account(self, account_number, pin, initial_balance=0):
    self.cursor.execute("INSERT INTO accounts (account_number, pin, balance) VALUES (?, ?, ?)", 
                        (account_number, pin, initial_balance))
    self.connection.commit()

def deposit(self, account_number, amount):
    self.cursor.execute("UPDATE accounts SET balance = balance + ? WHERE account_number = ?", 
                        (amount, account_number))
    self.connection.commit()

def withdraw(self, account_number, amount):
    self.cursor.execute("SELECT balance FROM accounts WHERE account_number = ?", (account_number,))
    current_balance = self.cursor.fetchone()[0]
    if amount > current_balance:
        raise ValueError("Insufficient funds.")
    self.cursor.execute("UPDATE accounts SET balance = balance - ? WHERE account_number = ?", 
                        (amount, account_number))
    self.connection.commit()
Enter fullscreen mode Exit fullscreen mode

These functions allow the ATM system to manage deposits, withdrawals, and account creation efficiently.

Step 3: Integrating Real-Time API Features

Let’s enhance the system by adding currency conversion using APIs like Open Exchange Rates.

import requests

def get_exchange_rate(self, target_currency):
    url = "https://open.er-api.com/v6/latest/USD"
    response = requests.get(url)
    if response.status_code == 200:
        rates = response.json().get("rates", {})
        return rates.get(target_currency.upper(), None)
    return None

def convert_balance(self, account_number, target_currency):
    self.cursor.execute("SELECT balance FROM accounts WHERE account_number = ?", (account_number,))
    balance = self.cursor.fetchone()[0]
    rate = self.get_exchange_rate(target_currency)
    return balance * rate if rate else "Exchange rate not available."
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Real-time conversion of balances to other currencies.
  • Connects the system to global financial data.

Step 4: Building a GUI with Tkinter

A user-friendly interface is crucial for an ATM system. Using Tkinter, we’ll design the GUI for account login and operations.

import tkinter as tk
from tkinter import messagebox

class ATMApp:
    def __init__(self, root):
        self.root = root
        self.root.title("ATM System")
        self.create_login_screen()

    def create_login_screen(self):
        tk.Label(self.root, text="Account Number").grid(row=0, column=0)
        tk.Label(self.root, text="PIN").grid(row=1, column=0)
        self.account_entry = tk.Entry(self.root)
        self.pin_entry = tk.Entry(self.root, show="*")
        self.account_entry.grid(row=0, column=1)
        self.pin_entry.grid(row=1, column=1)
        tk.Button(self.root, text="Login", command=self.login).grid(row=2, column=0, columnspan=2)

    def login(self):
        account = self.account_entry.get()
        pin = self.pin_entry.get()
        # Authenticate user...
Enter fullscreen mode Exit fullscreen mode

The GUI includes:

  • Login Screen: For user authentication.
  • Operations Panel: For performing deposits, withdrawals, balance checks, and currency conversions.

Step 5: Putting It All Together

With all components ready, here’s how to combine them:

  1. Create the database using SQLite.
  2. Implement backend logic for transactions and operations.
  3. Integrate APIs for advanced features.
  4. Design the GUI for a user-friendly experience.

Step 6: Future Enhancements

To further improve the system, consider adding:

  • Email Notifications for transactions using SMTP.
  • Mobile Banking Integration via SMS APIs like Twilio.
  • Enhanced Security with hashed PIN storage (using libraries like bcrypt).

Final Thoughts

You’ve just created a robust ATM system combining Python, SQLite, Tkinter, and APIs. Not only does it cover the basics, but it also includes advanced features like currency conversion and a user-friendly GUI.

Support me at https://t.co/E1nX8Am3gj to access more resources.

Top comments (0)