Python Authenticator

Hello! I am making an authenticator for OTP’s in Python, but I need help with the code. I am getting an attribue error. Here is the code if that helps.

import pyotp
import pyqrcode
import tkinter as tk
from tkinter import messagebox

class AuthenticatorApp:
    def __init__(self, master):
        self.master = master
        master.title("Authenticator App")
        
        # Generate a random secret key and create a TOTP object
        self.secret_key = pyotp.random_base32()
        self.totp = pyotp.TOTP(self.secret_key)
        
        # Generate a QR code image and convert it to a Tkinter PhotoImage object
        self.qr_data = self.totp.provisioning_uri("user@example.com")
        self.qr_code = pyqrcode.create(self.qr_data)
        self.qr_image_data = self.qr_code.png_as_bytes(scale=5)
        self.qr_image = tk.PhotoImage(data=self.qr_image_data)
        
        # Create the user interface
        self.label = tk.Label(master, text="Scan this QR code with your authenticator app:")
        self.label.pack()
        
        self.qr_label = tk.Label(master, image=self.qr_image)
        self.qr_label.pack()
        
        self.code_label = tk.Label(master, text="Enter the code from your authenticator app:")
        self.code_label.pack()
        
        self.code_entry = tk.Entry(master)
        self.code_entry.pack()
        
        self.button = tk.Button(master, text="Authenticate", command=self.authenticate)
        self.button.pack()
        
        # Start the update loop
        self.update()
    
    def update(self):
        # Update the current TOTP code
        self.current_code = self.totp.now()
        
        # Schedule the next update
        self.master.after(1000, self.update)
    
    def authenticate(self):
        # Get the code entered by the user
        entered_code = self.code_entry.get()
        
        if entered_code == self.current_code:
            messagebox.showinfo("Success", "Authentication successful!")
        else:
            messagebox.showerror("Error", "Incorrect code.")
    
if __name__ == "__main__":
    root = tk.Tk()
    app = AuthenticatorApp(root)
    root.mainloop()

Thank you!

Could we have the exact error please?

2 Likes
Traceback (most recent call last):
  File "main.py", line 58, in <module>
    app = AuthenticatorApp(root)
  File "main.py", line 18, in __init__
    self.qr_image_data = self.qr_code.png_as_bytes(scale=5)
AttributeError: 'QRCode' object has no attribute 'png_as_bytes'
1 Like

So…

^ Is invalid, lemme look up docs on pyqrcode

2 Likes

I’m about to log off for the night, I’ll come back at this in the morning. In the meantime, here’s a page from their docs that seems to cover what you want:
https://pythonhosted.org/PyQRCode/rendering.html

1 Like

So…
In here we can see the tkinter.PhotoImage accepts png file
In here we can see we only have a method returning the image data, which is encoded in base64
Therefore, we will need to decode it. In your code import base64 and use base64.b64decode(qr_image_data)

So in conclusion, try to import base64
Change

To

self.qr_image_encoded = self.qr_code.png_as_base64_str(scale=5)
self.qr_image_data = base64.b64decode(self.qr_image_encoded)

it should work, if not you can ask again with that new error

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.