chatGPTをコマンドラインから実行する術（いまさら）

# マウスは使わない派のために対話環境を一から作成する

最近流行しているchatGPTを利用するためにはブラウザから画面操作が必須であり
なんとなく便利な半面
WEB開発中などブラウザを都度切替しないといけないから不便。と思う人のために（自分

## アカウントを作成する

まずはこちらのページからアカウントを作成する
https://openai.com/product

すでにchatGPTをブラウザで利用している人は作成不要です（むしろ作成済）
openAIなのかchatGPTなのか分からなくなってきたのですが
気にしない方向で。

## API-KEYを発行する

プログラムから接続するために有効期限をもったAPI-KEYを発行する。
どこから遷移すればよいのかわからない人のためにリンク。
https://platform.openai.com/account/api-keys

手裏剣もそうですがIDとPasswordで認証するのはもう古いのですね。
そんな先進認証が必要。
ここで発行された長い文字列をコピーしておいてください
紛失すると再発行
漏洩するといいことありません。知らぬ間に鬼請求されてしまいそう。

## python環境を整える

前提として統合環境は利用しませんw
terminalから openaiをpip3でレッツインストール

```python
taro@MacBook-Air ~ % pip3 install openai
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
taro@Naoki-no-MacBook-Air ~ % 
```

うむむ。予期せぬエラー。

ひとまず業務PCは Windows10ないし Pop!_os の二択でしたが
今回は私用のため Macbook air を利用。環境が古かったかしら。

MacではXcodeが必要みたい。VScodeではない。V < X 。少し強め。
普段使いはサクラエディタですけど。

ひとまず容量がたりない。

そのため xcodeをいれるのではなく
CLI 環境だけ整える方向で。だって重たいし。やりたいことはコマンドライン。

```python
taro@MacBook-Air ~ % xcode-select --install
xcode-select: note: install requested for command line developer tools
taro@MacBook-Air ~ % 
```

ダウンロードに30時間必要というダイアログ表示。まじか。また明日。

```python
taro@MacBook-Air ~ % pip3 install openai   
Traceback (most recent call last):
  File "/Library/Developer/CommandLineTools/usr/bin/pip3", line 6, in <module>
    from pip._internal import main
      　；
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 26, in <module>
    from pip._internal.index import PackageFinder
ImportError: cannot import name 'PackageFinder' from 'pip._internal.index' (/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/site-packages/pip/_internal/index/__init__.py)
```
PackageFinderが存在しないと。なんだそれは。
いつもの通り pythonのエラーメッセージを見てもなにしてよいかわからない気がする。

```python
taro@MacBook-Air ~ % python --version
Python 2.7.16
taro@MacBook-Air ~ % brew --version
zsh: command not found: brew
taro@MacBook-Air ~ % 
```

pythonバージョン古いし。brewはいってないし。草。
このままなし崩し的な作業を後続。
brewインストール
```python
taro@MacBook-Air ~ % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
python3系をインストール。
```python
taro@MacBook-Air ~ % brew install python
```
仮想環境作成して有効化してからopenaiをインストール
```python
taro@MacBook-Air ~ % python3 -m venv taro
taro@MacBook-Air ~ % source taro/bin/activate
(taro) taro@MacBook-Air ~ % pip3 install openai
Collecting openai
  Downloading https://files.pythonhosted.org/packages/47/21/d909d8e92d1867f3daeb8d5c40936e3d37e27ad1ae187c754fefeadcbd4f/openai-0.27.2-py3-none-any.whl (70kB)
 ;
WARNING: You are using pip version 19.2.3, however version 23.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(taro) taro@MacBook-Air ~ % pip install --upgrade pip
```
pipが古いといわれるいつものやつに遭遇したのでアップデートしておく。

できた！

```python
(taro) taro@MacBook-Air src % python hello.py 侍ジャパンとは何かを教えてください
質問内容；侍ジャパンとは何かを教えてください

侍ジャパンは、日本のプロ野球選手たちで構成された国際大会代表チームのことを指します。2005年に結成され、日米野球やWBC（ワールド・ベースボール・クラシック）などの国際大会に出場しています。侍ジャパンという名称は、日本の伝統的な文化である「侍」を意味する言葉に由来しています。また、チームのイメージカラーは赤と白で、日の丸をモチーフにしたデザインが特徴的です。
(taro) taro@MacBook-Air src % 
```

開発の手助けにしたい場合もコマンドラインから質問できます。
```python
質問内容；pythonを利用して文字列を音声に変換する方法を教えてください。

Pythonで文字列を音声に変換するには、音声合成ライブラリを使用する必要があります。以下は、Pythonのテキスト読み上げライブラリを使用した例です。

1. pyttsx3ライブラリをインストールします。

pip install pyttsx3

2. コードを書きます。

import pyttsx3

# インスタンスを作成
engine = pyttsx3.init()

# テキストを指定
text = "Hello, World!"

# 読み上げ
engine.say(text)
engine.runAndWait()

上記の例では、`pyttsx3`ライブラリを使用して、テキストを音声に変換しています。`init()`関数は、テキスト読み上げエンジンを初期化し、`runAndWait()`関数は、コードを処理するためにエンジンを実行します。

このようにして、Pythonで文字列を音声に変換することができます。
```

## ブラウザいらないソースコード :money_with_wings: 

みなさまよりご指摘いただいたので若干修正しております

そういえば自分が質問した内容だけ保持すると chatGPTからの回答と
会話が成り立たないことが判明したので手元のソース修正してました

再掲。
・質問と回答を保持して chatGPTに投げかけする
・過去の質疑は sqlite3 に格納してあとで確認できるようにする

```python
# Import necessary packages/libraries.
import openai
import sys
import sqlite3
import os
from datetime import datetime

# Initialize
openai.api_key = os.environ.get('OPENAI_API_KEY')
if not openai.api_key:
    print(f"OPENAI_API_KEY environment variable doesn't exist, please restart again.")
    sys.exit(1)

messages = []
query = ""

# Define helper functions.
def create_connection(database_file):
    # Create a database connection
    conn = None
    try:
        conn = sqlite3.connect(database_file)
    except sqlite3.Error as e:
        print(e)

    return conn

def create_table(conn):
    # Create a table if it does not exist.
    try:
        cursor = conn.cursor()
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS chatgpt_qa (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                question TEXT NOT NULL,
                answer TEXT NOT NULL,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
                conversation_id TEXT,
                delete_flag VARCHAR(1) default '0'
            );
        """)
    except sqlite3.Error as e:
        print(e)

def multi_line_input(query):
    """
    Get user input line by line.
    :param query: message to show to the user
    :return: String with all the user input.
    """
    lines = []
    print(query)
    while True:
        line = input().rstrip()
        if line == '^D':
            break
        else:
            lines.append(line)
    return "\n".join(lines)


def save_qt(question, answer, id):
    """
    Save the question and answer into the database.
    :param question: String
    :param answer: String
    :return: None
    """
    timestamp = datetime.now()
    conn.execute("INSERT INTO chatgpt_qa (question, answer, timestamp, conversation_id) VALUES (?, ?, ?, ?)", (question, answer, timestamp, id))
    conn.commit()


def main():
    # Declare 'query' and 'conn' as global variables to use it inside the functions.
    global query, conn  
    conversation_id = ""
    if len(sys.argv) > 1:
        conversation_id = sys.argv[1]
        print(f"conversation_id={conversation_id}")
        
    # If no argument is passed, prompt the user for a question with 'multi_line_input' function.
    print("Please ask a question to ChatGPT. If you want to input multiple lines, enter '^D' at the end.")
    query = multi_line_input('query: ')

    database = "chatgpt_qa.db"
    # Create a connection to the database.
    conn = create_connection(database)
    # If the connection is created successfully, create a table.
    if conn is not None:
        create_table(conn)
    else:
        print("Error! Cannot create database connection.")

    id = None

    while True:
        # Append user's question to 'messages'.
        messages.append(
            {"role": "user", "content": query},
        )

        # Retrieve response from ChatGPT API using 'openai' library.
        response = openai.ChatCompletion.create(
            model="gpt-4",
#            model="gpt-3.5-turbo",
            messages=messages,
        )

        # Store the answer returned by 'ChatGPT' API and print it.
        answer = response["choices"][0]["message"]["content"].strip()
        if id is None:
            id = response["id"]
        
        print(f"Answer({id}):")
        print(answer)
        print("---")

        # Save the question and answer to the database.
        save_qt(query, answer, id)  

        # Append chatGPT's answer to 'messages'.
        messages.append(
            {"role": "assistant", "content": answer},
        )

        # Prompt the user for a new question.
        query = multi_line_input('query: ')
        if query == '':
            conn.close()
            break

# Call the main function when this script is invoked.
if __name__ == '__main__':
    main()

# 2023/03/13 複数行の問合せと繰り返し質問に対応
# 2023/08/09 繰り返し質問と回答を保持。問合せをsqlite3に格納。
```

これで日々コマンドプロンプトを開きながら開発ができること間違いない。
音声変換して話させようと思ったけど、ソースコード読まれても不便な罠。

時間がなくなってきたので本日はここまで。

## コマンドラインよりもダブルクリック派閥

そういえば python でchatGPTを利用する場合
毎回コマンドプロンプト起動して `python hello.py` って実行していましたが
Windows だったら結構面倒。
やっぱり庶民はマウスのみで全ての情報管理（やりすぎ。

ダブルクリックですよね。

python でも Windows の exe が作成できるので加筆。
まず pyinstaller をインストールして（表現が冗長

```python
C:\apl\openai>pip install pyinstaller
Collecting pyinstaller
  Downloading pyinstaller-5.9.0-py3-none-win_amd64.whl (1.3 MB)
     ---------------------------------------- 1.3/1.3 MB 8.0 MB/s eta 0:00:00
Collecting pywin32-ctypes>=0.2.0
  Downloading pywin32_ctypes-0.2.0-py2.py3-none-any.whl (28 kB)
Collecting pefile>=2022.5.30
  Downloading pefile-2023.2.7-py3-none-any.whl (71 kB)
     ---------------------------------------- 71.8/71.8 kB 2.0 MB/s eta 0:00:00
Collecting pyinstaller-hooks-contrib>=2021.4
  Downloading pyinstaller_hooks_contrib-2023.1-py2.py3-none-any.whl (256 kB)
     ---------------------------------------- 256.8/256.8 kB 8.0 MB/s eta 0:00:00
Requirement already satisfied: setuptools>=42.0.0 in c:\apl\python38\lib\site-packages (from pyinstaller) (47.1.0)
Collecting altgraph
  Downloading altgraph-0.17.3-py2.py3-none-any.whl (21 kB)
Installing collected packages: pywin32-ctypes, altgraph, pyinstaller-hooks-contrib, pefile, pyinstaller
Successfully installed altgraph-0.17.3 pefile-2023.2.7 pyinstaller-5.9.0 pyinstaller-hooks-contrib-2023.1 pywin32-ctypes-0.2.0
```

次にexeを作成する
```python
C:\apl\openai>pyinstaller --onefile hello.py
595 INFO: PyInstaller: 5.9.0
595 INFO: Python: 3.8.5
596 INFO: Platform: Windows-10-10.0.19041-SP0
605 INFO: UPX is not available.
612 INFO: Extending PYTHONPATH with paths
　；
324794 INFO: checking PKG
324795 INFO: Building PKG because PKG-00.toc is non existent
324797 INFO: Building PKG (CArchive) hello.pkg
521395 INFO: Building PKG (CArchive) hello.pkg completed successfully.
521869 INFO: Bootloader c:\apl\Python38\lib\site-packages\PyInstaller\bootloader\Windows-64bit-intel\run.exe
521869 INFO: checking EXE
521871 INFO: Building EXE because EXE-00.toc is non existent
521871 INFO: Building EXE from EXE-00.toc
521892 INFO: Copying icon to EXE
521897 INFO: Copying icons from ['c:\\apl\\Python38\\lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-console.ico']
521902 INFO: Writing RT_GROUP_ICON 0 resource with 104 bytes
521903 INFO: Writing RT_ICON 1 resource with 3752 bytes
521903 INFO: Writing RT_ICON 2 resource with 2216 bytes
521905 INFO: Writing RT_ICON 3 resource with 1384 bytes
521906 INFO: Writing RT_ICON 4 resource with 37019 bytes
521907 INFO: Writing RT_ICON 5 resource with 9640 bytes
521907 INFO: Writing RT_ICON 6 resource with 4264 bytes
521908 INFO: Writing RT_ICON 7 resource with 1128 bytes
521914 INFO: Copying 0 resources to EXE
521916 INFO: Embedding manifest in EXE
521920 INFO: Updating resource type 24 name 1 language 0
521927 INFO: Appending PKG archive to EXE
524934 INFO: Fixing EXE headers
535761 INFO: Building EXE from EXE-00.toc completed successfully.
```

できたｗ

カレントの dist\ 配下に hello.exe が作成されています。

```python
C:\apl\openai\dist> hello.exe
Please ask a question to ChatGPT. If you want to input multiple lines, enter '^D' at the end.
query:
BingでchatGPTが使えるようになった理由を教えてください
^D
Answer:
BingがchatGPTを利用できるようになった理由は、MicrosoftとOpenAIの間のパートナーシップであり、MicrosoftがOpenAIに投資した ことにより、OpenAIの技術をBingに統合することができたためです。chatGPTは、OpenAIが開発した最先端の自然言語処理技術であり 、Bingを使うユーザーは、chatGPTを利用して、より人間らしい対話体験を得ることができます。
---
query:
^D

C:\apl\openai\dist> dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 42FE-87C6 です

C:\apl\openai\dist> のディレクトリ

2023/03/28  07:45    <DIR>          .
2023/03/28  07:45    <DIR>          ..
2023/03/28  07:45            12,288 chatgpt_qa.db
2023/03/28  07:38       281,973,394 hello.exe
               2 個のファイル         281,985,682 バイト
               2 個のディレクトリ  10,970,648,576 バイトの空き領域

C:\apl\openai\dist>
```

ちゃんとexeを実行したらsqliteを利用して会話記録をDB化しているし
問題なさげ。
ちょっと python から実行するときよりも遅い気がするのがネック首。