手把手教你使用 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 ,項目功能介紹如下圖所示:
-
先跑起來,再理解
-
關鍵代碼解析
-
常見 Web 狀態碼含義
-
更多拓展
先跑起來,再理解
首先你需要有一個 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"}
-
將 api 設置爲你的 openai api key
-
jwt_secret_key 用於指定簽名 JWT(JSON Web Token)的密鑰,可以隨便設置,複雜點爲好(後面涉及相關代碼會再介紹)
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> 運行代碼:
- 初始化數據庫和數據 processing_data.py
processing_data.py 包含了初始化代碼,直接運行會自動在當前文件夾中的 file 文件夾下生成一個 chatgpt.db 數據庫文件,包含兩個表:users 和 tokens,默認初始化數據存在:./file/user.csv,可以根據需要修改~
# 初始化數據
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
'''
-
客戶端調用
-
獲取 Token 代碼
# 如果你在自己服務運行,請將 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()
- 發送 API 請求代碼
# 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
'''
關鍵代碼解析
- 使用 Flask-JWT-Extended 實現 token 生成和有效期管理
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 天。
- api 請求接口
# 設置單日用戶最大請求次數
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: 服務器內部錯誤
請求流程:
-
用戶發起 API 請求,包含 Token 和查詢參數 q。
-
服務端獲取 Token 對應的用戶信息。
-
如果 Token 不存在,返回錯誤提示信息,狀態碼 401。
-
獲取當前用戶訪問次數 count。
-
判斷訪問次數是否需要重置,如果上次請求日期與當前日期相差大於等於一天,且 count > 0,重置訪問次數。
-
判斷 Token 訪問次數是否達到限制 Request_Count。
-
如果 Token 訪問次數達到限制,返回錯誤提示信息,狀態碼 429。
-
發送用戶查詢請求給 GPT 模型。
-
捕獲 GPT 模型請求異常,返回錯誤提示信息,狀態碼 500。
-
增加用戶訪問次數 count,更新 Token 最後使用時間 last_use_time。
-
返回 API 響應,狀態碼 200。
- token 請求
# 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):響應信息,成功時包含以下字段:
-
username(string):用戶名。
-
token(string):生成的 Token。
-
expiration_time(string):Token 過期時間,格式爲 YYYY-MM-DD HH:MM:SS。
狀態碼:
200:服務器成功處理了請求,並返回了 JSON 格式的響應;
201:服務器成功創建了新資源,並返回了 JSON 格式的響應;
401:表示請求要求身份驗證,客戶端需要提供有效的用戶名和密碼;
500:服務器內部錯誤,無法完成請求的處理。
請求流程:
-
客戶端向服務器發送一個 POST 請求,請求的 URL 是'/token';
-
服務器接收到請求後,獲取請求體中的用戶名和密碼,並調用 get_user 函數查找數據庫中是否存在該用戶;
-
如果用戶不存在或密碼錯誤,服務器返回一個包含狀態碼 401 和錯誤信息的 JSON 響應;
-
如果用戶存在且密碼正確,服務器調用 get_token_info 函數查找該用戶是否已經有一個 token;
-
如果已經有一個 token,服務器返回一個包含狀態碼 200 和該 token 信息的 JSON 響應;
-
如果沒有 token,服務器調用 create_access_token 函數生成一個新的 token,並調用 insert_token 函數將該 token 信息插入到數據庫中;
-
如果生成和插入 token 過程中發生異常,服務器返回一個包含狀態碼 500 和異常信息的 JSON 響應;
-
服務器返回一個包含狀態碼 201 和新生成 token 信息的 JSON 響應。
注: 以上兩個接口請求流程是 ChatGPT 根據代碼描寫的。
常見 Web 狀態碼含義
在 Web 訪問中,當客戶端向服務器發起請求時,服務器會向客戶端返回一個狀態碼,用於告訴客戶端請求的處理情況。以下是一些常見的狀態碼及其含義:
-
200 OK:請求成功,服務器已成功處理了請求。
-
201 Created:請求成功並且服務器創建了新的資源。
-
204 No Content:請求成功,但是響應中沒有實體的主體部分。
-
301 Moved Permanently:請求的資源已經永久移動到新的 URL。
-
302 Found:請求的資源臨時從不同的 URL 響應請求,但是請求者應繼續使用原始 URL 訪問資源。
-
304 Not Modified:請求的資源未被修改,服務器返回此狀態碼時,不會返回資源的主體部分。
-
400 Bad Request:請求無效,服務器無法識別請求的格式,常見的原因包括請求中的參數有誤或者缺失。
-
401 Unauthorized:請求未被授權,需要客戶端進行身份驗證。
-
403 Forbidden:服務器已經理解請求,但是拒絕執行它,通常是因爲客戶端沒有足夠的權限。
-
404 Not Found:請求的資源不存在,服務器無法找到請求的資源。
-
429 Too Many Requests:這意味着客戶端發送的請求過多,超過了服務器可以處理的限制。
-
500 Internal Server Error:服務器遇到了意外的情況,無法完成請求。
更多拓展
也許你會有疑問,爲什麼只有 api 和 token 接口,沒有 register 註冊接口,每次給新用戶還得自己手動操作,太蠢了?
本應用是一個 Paas 層的 API 接口,所以沒有提供 register 這種應用層面接口,下一步會出一個 ChatWeb 項目,這個項目會有用戶登錄、註冊界面,這時候和 ChatAPI 結合起來,就是一個較爲完整的 Web 應用了。(描述和認知不一定準確,如果你有不同看法,歡迎留言指正、交流)
你還可以上 Github 搜索更多 ChatGPT 相關項目,或者其他有意思的項目學習練手,歡迎學習交流。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/1rmd14DCJTRFqqxleBJVng