見出し画像

ChatGPTのAPIを利用するGUIプログラムを書いてみました。

GUIのプログラムを書かないと業務システムの運用を渡せない!

事務員が退職し、30数年ぶりに事務作業を始めました。バックオフィースの実務は細かい作業で疲れます。「手順手続きは全てプログラム化できる」と騒いできましたので、実証を兼ねてChatGPTを利用してPythonでプログラムを書いてみました。給与振込などの仕分ができあがれば大体目処が着く状態になりました。
そろそろ社員に運用を任せる段階になり、「GUI化をしないとまずい!」と考えPythonを利用してGUI化をする方法をネットで色々探しました。

GUIのライブラリー TkEasyGUI 

PySimpleGUIが良さそうだと思いましたが「有料化」しており、初心者ではそんなに高度な利用方法は行わないので、他にないかと探しました。「TkEasyGUI」を見つけました。日本人の方(くじらはんどさん)が書いています。

サンプルプログラムも色々書いてくださっており、理解するのには最適かと思いトライしました。。

ChatGPTのAPIを利用するプログラムを書いてみる

APIを利用すると利用料金も大変安いと聞いておりました。社内で利用するのにはAPIの方が良いかと考え、イタズラを始めてみました。料金の支払いは、支払い上限金額を設定することができます。

OpenAI API利用料の支払い情報の登録方法をわかりやすく解説!

OpenAIのAPIは、バージョンアップが頻繁に行われるようです。素人にはついて行くのが難しいとの思いが強いです。しかし、極めて簡単な問い合わせで結果が得られます。
APIを利用するためのプログラムを書くのには、GUIを学習するのに最適だと考えトライをしてみました。
画像生成を社内で簡単に利用できるようにDALL-E3が画像をアップロードして修正できるようになったらGUIの画像生成のプログラムを書きたいと考えています。

プログラム開発過程

先ずは幾つかのサンプルプログラムをChatGPTに解説してもらう

「TkEasyGUIはPySimpleGUI と互換性を持つライブライーです。 以下のプログラムを詳細に解説してもらえますか。 」と問い合わせを行いました。
GTP-4oで詳細な返答が返ってきました。理解できない部分はさらに質問すると教えてくれます。学習効率が極めて高いです。学習のあり方が変わりそうです。

作りたいプログラムの概要を書いてプログラムの生成をお願いする

GPTのAPIを利用してチャットを継続するプログラムをPythonでGUIを利用して作ろうとしています。GUIのモジュールはPySimpleGUIと互換性のあるTkEasyGUIを利用します。 GPTのmodelは、"gpt-3.5-turbo”と”gtp-4o”を選択して使います。 "content"は、テキストボックスに書きます。 送信した質問の回答は、別のテキストボックスに表示されます。 会話を終了する場合には”Exit”ボタンを押して終了します。 プログラムを書いてもらえますか。

以下のプログラムが返ってきました。

import os
import openai
import TkEasyGUI as sg

# OpenAI APIキーを設定
openai.api_key = 'YOUR_API_KEY'

# ウィンドウのレイアウトを定義
layout = [
    [sg.Text('Select GPT Model:'), sg.Combo(['gpt-3.5-turbo', 'gpt-4'], key='-MODEL-', default_value='gpt-3.5-turbo')],
    [sg.Text('Your Question:')],
    [sg.Multiline(size=(70, 10), key='-INPUT-')],
    [sg.Button('Send', key='-SEND-')],
    [sg.Text('Response:')],
    [sg.Multiline(size=(70, 20), key='-OUTPUT-', disabled=True)],
    [sg.Button('Exit', key='-EXIT-')]
]

# ウィンドウを作成
window = sg.Window('GPT Chat', layout)

# イベントループ
while True:
    event, values = window.read()
    if event in (sg.WINDOW_CLOSED, '-EXIT-'):
        break
    
    if event == '-SEND-':
        model = values['-MODEL-']
        user_input = values['-INPUT-'].strip()
        
        if user_input:
            try:
                response = openai.ChatCompletion.create(
                    model=model,
                    messages=[{'role': 'user', 'content': user_input}]
                )
                response_text = response['choices'][0]['message']['content']
            except Exception as e:
                response_text = f"Error: {e}"
            
            # 回答をテキストボックスに表示
            window['-OUTPUT-'].update(response_text)

window.close()

さらに詳細の説明がついてきました。

動かしたら動かない! 原因を探す。

API 公式ドキュメントを見たら問い合わせ方が違っていました。爆速で進化しており素人には対応が難しいです。

from openai import OpenAI

client = OpenAI()

stream = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Say this is a test"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="")

APIを利用した基礎の基礎のGUIプログラムを作成

黄色の場所に問い合わせを書き、Send を押すと下に答えが表示されます。右の「問い合わせ結果」は履歴が表示されます。Exit を押すとポップUPが表示され全ての問い合わせ履歴が日時を付けたファイル名でテキストとして保存されます。
APIキーを取得して 環境変数を利用しない場合は、api-key に直接代入すれば動くはずです。

from openai import OpenAI
import os
from dotenv import load_dotenv  # 環境変数を利用するため
import TkEasyGUI as eg

# SAVE ファイル名を作成するため
from datetime import datetime
# 現在の日付と時刻を取得
now = datetime.now()

syori_date = str(now)[2:19]  # 文字を取得
syori_date = syori_date.replace('-','').replace(':',':')
SAVE_FILE = './gpt_txt/' + syori_date + ' GPT.txt'

# OpenAI APIキーを設定
 #api_key = "sk-XXX ・・・  "  #ここにkey を記述

load_dotenv()  # 環境変数 を利用する場合 
api_key = os.environ.get('OPENAI_API_KEY')

client = OpenAI(api_key=api_key)

font_14 = ("Arial", 14)
font_16 = ("Arial", 16)
layout = [
    [
        eg.Frame(
            "",
            [
                [eg.Text('Select Model:', font=("Arial", 20)), eg.Combo(['gpt-3.5-turbo', 'gpt-4o'], key='-MODEL-', default_value='gpt-3.5-turbo', font=font_16 )],
                [eg.Text('Your Question:')],
                [eg.Multiline(size=(70, 10), key='-INPUT-', background_color="#fff3b8")],
                [eg.Button('Send', key='-SEND-', font=("Arial", 20), text_color="red")],
                [eg.Text('Response:')],
                [eg.Multiline(size=(70, 20), key='-OUTPUT-', expand_y=True, expand_x=True, background_color="#dbebc4")],
                [eg.Button('Exit', key='-EXIT-', font=("Arial", 20))]
            ],
        ),
        eg.Frame(
            "問い合わせ履歴",
            [
                [eg.Multiline(size=(70, 40), key='-RECORD-', expand_y=True, expand_x=True, background_color="#fef9fb", font=font_14)],
            ],
        ),
    ],
]
window = eg.Window(
    'ChatGPT 問い合わせ(文書)', layout,
    )

record = ""
anser = ""
# event loop
# イベントループ
while True:
    event, values = window.read()
    if event in (eg.WINDOW_CLOSED, '-EXIT-'):
        #  履歴を保存
        with open(SAVE_FILE, "w", encoding="utf-8") as f:
            f.write(values['-RECORD-'])
        eg.popup("Saved")
        break

    if event == '-SEND-':
        model = values['-MODEL-']
        user_input = values['-INPUT-'].strip()

        response_text = None
        if user_input:
            try:
                response = client.chat.completions.create(
                    model=model,
                    messages=[{'role': 'user', 'content': user_input}]
                )
                response_text = response.choices[0].message.content

                # response_text = "返答"
                print(response_text)
                window['-OUTPUT-'].update(response_text)

                record += "ー問いー\n" + user_input + "\n" + "ー答えー\n" + response_text + "\n"

                window['-RECORD-'].update(record)
                window['-INPUT-'].update("")

            except Exception as e:
                response_text = f"Error: {e}"
                break

window.close()

少ししか利用していませんが、使用料金の安さに驚きました

5月の使用料

Webで同じ問い合わせをした場合は異なる答えが返ってきました。🤣
DALL-E3 で画像生成も可能なので社内で利用するのにはAPIの利用は効率的だと思われます。このページの画像も生成したものです。
社員が簡単に利用できるように画像生成用のGUIプログラムも作ってみたいと考えています。


この記事が気に入ったらサポートをしてみませんか?