Non-blocking ChatGPT UI

I have a small Qt application written in Python that I use to access ChatGPT. It’s an app that has a built-in prompt database and editor, and has keyboard shortcuts that make it convenient for me to use.

The reason for writing this app was because it was getting annoying to log in to ChatGPT every time I wanted to use it, and the laggy ChatGPT UI left a lot to be desired. I wanted something that was fast and responsive, and made in a way that was designed to be useful for me and not designed for the lowest common denominator.

I’ve used it for some time now, and it’s been working well. However, there’s a tiny problem that has been bugging me for a while: the UI blocks whenever I make an API call to ChatGPT. This is because the API call is made in the main thread, and the UI is blocked until the API call returns.

Even worse; if the API call fails, the whole app crashes. I’ve lost some content because of this, and it’s not a good feeling. I decided that after not touching the code since I wrote it, it was time to go in once again and fix this problem.

The solution was to make the API call into a QThread. Instead of calling a method directly, you just call it from your QThread’s run() method, and send the result back to the main thread using a pyqtSignal. Here is the code I ended up using.

class ChatGptThread(QThread):
    gotResponse = pyqtSignal(str)

    def __init__(self, parent: QObject):
        super().__init__(parent)

    def run(self):
        response = chatgpt_response()
        self.gotResponse.emit(response)


def ask_question():
    t = ChatGptThread(app)

    def cb(resp):
        add_message(ChatMessage("assistant", resp))
        add_message(ChatMessage("user", ""))

    t.gotResponse.connect(cb)
    t.finished.connect(t.deleteLater)
    t.start()

Now the UI is no longer blocked when I make an API call, and I am happy.