手把手教你使用 Python 調用 ChatGPT-3-5-API

大家好,我是老表。

手把手教你使用 Python 調用 ChatGPT-3.5-API。Hands teach you to use Python to call ChatGPT-3.5-API.https://github.com/XksA-me/ChatGPT-3.5-API

這是 手把手教你使用Python調用 ChatGPT-3.5-API系列第二篇文章,也是第二個項目:ChatAPI ,項目功能介紹如下圖所示:

先跑起來,再理解

首先你需要有一個 openai 賬號,如何註冊我就不多說了,網上教程很多,而且很詳細,如果有問題可以加我微信:pythonbrief,添加通過後請直接描述你的問題 + 問題截圖。

訪問下面頁面,登錄 openai 賬號後,創建一個 api keys。

# api keys 創建頁面
https://platform.openai.com/account/api-keys

接下來很簡單了,

1> 下載項目代碼:

git clone https://github.com/XksA-me/ChatGPT-3.5-API.git

# 如果慢使用下面指令(加了個國內源)
git clone https://ghproxy.com/https://github.com/XksA-me/ChatGPT-3.5-API.git

目錄結構:

.
├── ChatAPI      # 實現 ChatGPT API 服務,Paas應用
├── ChatCMD      # 實現控制檯 ChatGPT 多輪對話應用
├── LICENSE  
├── README.md    # 項目總說明
├── blog         # 各個應用實現、使用教程
├── envs         # 存放 key 和各種配置
└── static       # 存放文檔靜態數據

2> 修改配置文件:

配置文件在 envs/configs,文件內容如下:

{"api""你的 api key""jwt_secret_key""你的 JWT_SECRET_KEY"}

3> 進入項目目錄,安裝依賴:

cd ChatGPT-3.5-API/ChatAPI
# ChatAPI 項目目錄介紹
'''
.
├── README.md            # 項目說明文件
├── chatapi.py           # web 服務主程序
├── chatapi_test.ipynb   # 測試代碼
├── chatgpt.py           # 請求 chatgpt 代碼
├── file                 # 項目文件
│   ├── chatgpt.db       # sqlite 數據庫
│   └── user.csv         # user 表測試數據
├── processing_data.py   # sqlite 數據庫操作代碼
├── ../envs             # 上級目錄下的 envs 文件夾,存放 key
└── requirements.txt     # 項目依賴
'''

安裝依賴:

# 注意現在是在:ChatGPT-3.5-API/ChatAPI 目錄下
pip install requirements.txt

4> 運行代碼:

# 初始化數據
python processing_data.py
- 生成token : http://127.0.0.1:5000/token
- 調用api : http://127.0.0.1:5000/api

如果使用的服務器,將 chatapi.py 代碼中 127.0.0.1 改成服務器 IP 地址即可。

python chatapi.py

'''
* Serving Flask app 'chatapi'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.31.225:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 929-327-786
'''
# 如果你在自己服務運行,請將 127.0.0.1 改成你自己服務器地址
import requests

# 1. 獲取Token
def get_token(username, password):
    url = 'http://127.0.0.1:5000/token'
    data = {
        'u': username,
        'p': password
    }
    response = requests.post(url, json=data)
    print(response.text)
    if response.status_code in {200, 201}:
        return response.json()['message']['token']
    # 其他情況在 服務 裏會處理
    return response.json()

# 2. 發送API請求
import requests
def call_api(token, q):
    url = 'http://127.0.0.1:5000/api'
    headers = {
        'Authorization''Bearer ' + token
    }
    response = requests.get(url, headers=headers, params={"q": q})
    if response.status_code == 200 and response.json()['statu']:
        return response.json()['message']
    else:
        # 其他情況在 服務 裏會處理
        return response.json()

'''
127.0.0.1 - - [11/Mar/2023 14:42:51] "POST /token HTTP/1.1" 200 -
127.0.0.1 - - [11/Mar/2023 15:06:14] "GET /api?q=你好,python寫一個合併多個+excel+xls文件的案例,每個excel表頭一樣 HTTP/1.1" 200 
'''

關鍵代碼解析

from flask import Flask, jsonify, request
from flask_jwt_extended import (
    JWTManager, jwt_required, create_access_token, get_jwt_identity
)
from datetime import datetime, timedelta
from chatgpt import *
from processing_data import (
    get_user, insert_token, get_token_info, update_token, day_diff, get_config
)


app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = get_config()['jwt_secret_key']  # JWT_SECRET_KEY 隨機只有自己知道就行,可在 ../envs/configs 裏修改
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=30)  # Token有效期爲30天
jwt = JWTManager(app)

這段代碼使用了 Flask 框架和 Flask-JWT-Extended 擴展庫,實現了對 RESTful API 訪問的身份認證和授權控制。

其中JWT_ACCESS_TOKEN_EXPIRES爲生成 token 的有效期,上面設置的是 30 天。

# 設置單日用戶最大請求次數
Request_Count = 10

# API接口路由
@app.route('/api'methods=['GET'])
@jwt_required()
def api():
    # 獲取當前Token對應user
    user = get_jwt_identity()
    q = request.args.get('q')
    # 檢查 token 對應 user 是否存在
    token_info = get_token_info(user)
    if not token_info:
        return jsonify({'statu': False, 'message''Token does not exist. Please contact the administrator to apply.'})401
    # 獲取用戶訪問次數
    count = token_info[2]
    
    # 檢查訪問次數是否需要重置(每日需要重置下次數)
    # 上次請求日期與當前日期相差大於等於一天,且count > 0
    if day_diff(datetime.now().date(), token_info[4]) and count > 0:
        # 重置訪問次數
        count = 0

    # 檢查Token訪問次數是否達到限制
    if count >= Request_Count:
        return jsonify({'statu': False, 'message''Token access limit reached.'})429
    try:
        messages = [{"role""user""content": q}]
        rsp = ask_gpt(messages)
    except Exception as e:
        return jsonify({'statu': False, 'message': f'An error occurred in the chatgpt request, {e}'})500
    # 增加Token訪問次數
    count+= 1
    last_use_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    update_token(username=token_info[0]count=count, last_use_time=last_use_time)
    # 返回API響應
    return jsonify({'statu': True, 'message': rsp})200

jwt_required() 裝飾器用於保護需要授權才能訪問的接口;
get_jwt_identity() 函數用於獲取當前 Token 的身份標識;
jsonify() 函數用於將 Python 數據結構轉換爲 JSON 格式;

基本說明:
方法:GET
路由:/api
認證:JWT
功能:根據用戶提供的問題返回機器人回答
請求參數:
q: 用戶提問內容
返回結果:
statu: 返回結果狀態
message: 返回信息內容
狀態碼:
200: 請求成功
401: Token 不存在或已失效
429: Token 請求次數超出限制
500: 服務器內部錯誤

請求流程:

  1. 用戶發起 API 請求,包含 Token 和查詢參數 q。

  2. 服務端獲取 Token 對應的用戶信息。

  3. 如果 Token 不存在,返回錯誤提示信息,狀態碼 401。

  4. 獲取當前用戶訪問次數 count。

  5. 判斷訪問次數是否需要重置,如果上次請求日期與當前日期相差大於等於一天,且 count > 0,重置訪問次數。

  6. 判斷 Token 訪問次數是否達到限制 Request_Count。

  7. 如果 Token 訪問次數達到限制,返回錯誤提示信息,狀態碼 429。

  8. 發送用戶查詢請求給 GPT 模型。

  9. 捕獲 GPT 模型請求異常,返回錯誤提示信息,狀態碼 500。

  10. 增加用戶訪問次數 count,更新 Token 最後使用時間 last_use_time。

  11. 返回 API 響應,狀態碼 200。

# Token生成路由
@app.route('/token'methods=['POST'])
def token():
    # 獲取用戶名和密碼
    username = request.json.get('u', None)
    password = request.json.get('p', None)
    user = get_user(username)
    # 檢查用戶名和密碼是否正確
    if not user or password != user[2]:
        return jsonify({'statu': False, 'message''Invalid username or password'})401
    try:
        # 每個用戶只能有一個token
        token_info = get_token_info(username)
        if token_info:
            return jsonify({'statu': True, 'message'{'username': username, 'token': token_info[1]'expiration_time': token_info[3]}})200
        # 生成Token
        token = create_access_token(identity=username)
        # 記錄到數據表
        expiration_time = (datetime.now() + timedelta(days=30)).strftime("%Y-%m-%d %H:%M:%S")
        insert_token(username, token, expiration_time)
    except Exception as e:
        return jsonify({'statu': False, 'message': f'Error in create token, Exception: {e}'})500
    # 返回Token
    return jsonify({'statu': True, 'message'{'username': username, 'token': token, 'expiration_time': expiration_time}})201

create_access_token() 函數用於生成 Token;

基本說明:
方法:POST
路由:/token
功能:用於生成 Token
請求參數:
u(string):用戶名,必填。
p(string):密碼,必填。
返回結果:
status(bool):請求狀態,成功爲 true,失敗爲 false。
message(object):響應信息,成功時包含以下字段:

狀態碼:
200:服務器成功處理了請求,並返回了 JSON 格式的響應;
201:服務器成功創建了新資源,並返回了 JSON 格式的響應;
401:表示請求要求身份驗證,客戶端需要提供有效的用戶名和密碼;
500:服務器內部錯誤,無法完成請求的處理。

請求流程:

  1. 客戶端向服務器發送一個 POST 請求,請求的 URL 是'/token';

  2. 服務器接收到請求後,獲取請求體中的用戶名和密碼,並調用 get_user 函數查找數據庫中是否存在該用戶;

  3. 如果用戶不存在或密碼錯誤,服務器返回一個包含狀態碼 401 和錯誤信息的 JSON 響應;

  4. 如果用戶存在且密碼正確,服務器調用 get_token_info 函數查找該用戶是否已經有一個 token;

  5. 如果已經有一個 token,服務器返回一個包含狀態碼 200 和該 token 信息的 JSON 響應;

  6. 如果沒有 token,服務器調用 create_access_token 函數生成一個新的 token,並調用 insert_token 函數將該 token 信息插入到數據庫中;

  7. 如果生成和插入 token 過程中發生異常,服務器返回一個包含狀態碼 500 和異常信息的 JSON 響應;

  8. 服務器返回一個包含狀態碼 201 和新生成 token 信息的 JSON 響應。

注: 以上兩個接口請求流程是 ChatGPT 根據代碼描寫的。

常見 Web 狀態碼含義

在 Web 訪問中,當客戶端向服務器發起請求時,服務器會向客戶端返回一個狀態碼,用於告訴客戶端請求的處理情況。以下是一些常見的狀態碼及其含義:

更多拓展

也許你會有疑問,爲什麼只有 api 和 token 接口,沒有 register 註冊接口,每次給新用戶還得自己手動操作,太蠢了?

本應用是一個 Paas 層的 API 接口,所以沒有提供 register 這種應用層面接口,下一步會出一個 ChatWeb 項目,這個項目會有用戶登錄、註冊界面,這時候和 ChatAPI 結合起來,就是一個較爲完整的 Web 應用了。(描述和認知不一定準確,如果你有不同看法,歡迎留言指正、交流)

你還可以上 Github 搜索更多 ChatGPT 相關項目,或者其他有意思的項目學習練手,歡迎學習交流。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/1rmd14DCJTRFqqxleBJVng