OpenAI API のアプデは本当に破壊的だった。

相変わらず初心者プログラマーなので、温かい目で見てください。内容はお吸い物ぐらい薄いです
こんなやつもいるんだなというくらいの気持ちで見ていただけますと幸いです。
# ストレス発散と次回予告(レガシー)

```
やめて！OpenAIの破壊的なAPIアプデで、リクエストの生成方法を根本的に変換されたら
よくわかんない英語を読みまくって実装してエラー三昧になりながらも、よなべしてまでがんばって
PythonCLIツールを作った松本の精神まで燃え尽きちゃう！


お願い、根本的な生成方法は頻繁に変えないでOpenAI！


あんたがそんなに書式を書き換えていったら、あたしみたいな弱小大学生プログラマーはどうなっちゃうの？


カフェイン製剤（愛用）はまだ残ってる。ここを耐えれば、NotFoundErrorに勝てるんだから！



次回「松本 死す」徹夜コーディング スタンバイ！
```
（公式の皆様。大変申し訳ございません。）

死んでないです。とてもナイーブになりながら修正していきました。

改めてリファクタリングで可読性の高いコードの作成を目指すのは徹底するべきだと感じました。











## 何がどうしてこうなった

多分、VisionAPIが公開された頃、一緒に出てきた書き方なのかなとは薄々感づいていたのですが、触っていないうちにサポート外となっていたっぽい...?
あの頃、エラーをキャッチする際の書式が変わっていたのは把握していたのですが、その頃の書式がレガシー扱いになって使えなくなったっぽいです。

## 具体的には何があったのさ
今まで、PythonのOpenAIによるライブラリを用いてAPIキーやbase_urlを指定する際は、
```
import openai

openai.api_key = "any"
openai.base_url = "any"

```
といった書き方で指定し、その後ろで

```
response = openai.chat.completions.create(
            model=using_model,
            messages=messages,
            max_tokens=2000
        )
response.choices[0].message.content
```
といった感じで、どのモデルを使用して、どういったメッセージを渡すかを指定していました。

そんでもって、エラーをキャッチする際は、
`openai.NotFoundError`
とか
`openai.AuthenticationError`
とかを使ってやればよかったので、まだ理解できました。

　
もう大学3年生なので、就活をやっていると制作物の説明とかをするんですよ。
久しぶりに動かしてみて、大学で提供されているAI-MOP上のOpenAI APIは普通に動いたんですよ。
ただ、いざ個人で契約しているAPIキーと通常のURLの組み合わせで実行しようとすると、ずっとNotFoundErrorを吐くんですよ

「APIキーを間違えたのかな？　URLがそういえば初期の頃から変わっていたはずだしなにか間違えてるかも」

とか思いつつ新しくAPIキーを発行したりしても
```
openai.NotFoundError: Error code: 404 - {'error': {'type': 'invalid_request_error', 'code': 
'unknown_url', 'message': 'Unknown request URL: GET /models/gpt-4. Please check the URL for 
typos, or see the docs at https://platform.openai.com/docs/api-reference/.', 'param': None}}
```
経験の浅い自分はもうここで頭の中が「???」ですね
ネットの記事を漁ってみると課金状況によってはGPT-4を利用できないとかなんとか
じゃあ追加すれば良いんかな？
と思って少ない収入から捻出しても
`openai.NotFoundError`

ただOpenAIに追い献金しただけでした。
というのが事の発端です。










## 何をどう変えたら治ったの？
結局、困ったらドキュメントを読めということで、言われた通りに
```
from openai import OpenAI
client = OpenAI()
```
として自分のアプリの基幹になっていた以下のコードを書き換えてみると、
```
# openai.models.retrieve(using_model)↓に変換
client.models.retrieve(using_model)
```
すると、
```
openai.OpenAIError: The api_key client option must be set either by passing api_key to the 
client or by setting the OPENAI_API_KEY environment variable
```

ほうほう。これだったら

```
client = OpenAI(api_key="hogehoge", base_url="https://api.openai.com/v1/")
```
としてから実行したら

```
SyncPage[Model](data=[Model(id='whisper-1', created=1677532384, object='model', owned_by='openai-internal'), Model(id='davinci-002', created=1692634301,....
```
出てきました。
つまり、今まで 

**モジュールにて直接APIKEYやbase_urlを定義してきた** のが、
**クラスをインポートしてきて、その中でapi_keyやbase_urlを定義する**
方針に変わったわけですね。 (こんなことはもっと早い段階で情報が出ていたのに、楽観視していた自分が悪かったです)

というわけで、原因はわかったし何をどうすればいいかまで追求できました。
ただ、問題はここからで

いままで関数ごとに定義していたところを、作成した **client変数** を色んなところに配置していかないと行けないわけですね。

## エラーのキャッチアップ
ただ、エラーのキャッチアップ方法は変わっていないみたいで、
キャッチアップも行う際は、
```
import openai
from openai import OpenAI
client = OpenAI(api_key="hogehoge", base_url="arekore")
try:
    .....
except openai.PermissionDeniedError as f:
    .....
```
といった感じにするか、

```
import openai
client = openai.OpenAI(api_key="hogehoge", base_url="arekore")
try:
    .....
except openai.PermissionDeniedError as f:
    .....

```
といった感じにするみたいです
公式では、最初の書き方が推奨(?)されてるみたい
ややこしく感じるのは僕だけでしょうか

[公式ドキュメントの該当箇所](https://platform.openai.com/docs/guides/error-codes/handling-errors)

ほんと疲れました。
こんなことで疲れていてはまだまだですね。勉強を積みます










## 結論
・制作物で使用した技術やライブラリは定期的に巡回して、自身の知識をアップデートしていかないといけない
・pipインストールなどによるライブラリの更新は、本当に必要かどうかを考えてから＋心と体の準備を行ってから望む
・自分の扱っている手法が非推奨になったりレガシーになっていたら、早い段階で対策をしておく。後が大変


ドキュメントを読むことの大切さを改めて実感した一日でした。