使用docker部署Python-Flask实现ChatGPT的使用
首先说下背景:
自从申请ChatGPT到现在也有个把月了,余额一直还很多,想想三月下旬就过期了,还是计划把里面的18美刀用掉,于是结合着之前做的Django简单cv一个"简易网站"。
简单说一下实现原理:
先写界面,计划半天,由于没有VUE上云的经验,还是用最基础的超文本标记语言吧(主要是简单轻松,哈)HTML+css
后台用Flask,解释器Python3.9,官网给好的框架可轻松实现一个简易网站的搭建
部署的时候用docker,写好Dockerfile,直接在容器里面把环境码好了
一、创建环境
1、flask插件 2、Python依赖的模块 openAI, Flask, render_template, request, flash, jsonify
二、代码部分
2.1、功能代码
# -*- coding:utf-8 -*- # !/usr/bin/python3 ##################################################################### # Author : zhoujt # Tel : 186xxxxxxxx # Date : 2023-02-14 # FileName : openaigpt.py # Description: web requests ##################################################################### import json import time import openai import requests from flask import Flask, render_template, request, flash, jsonify import re app = Flask(__name__) app.secret_key = 'security-guard' def zhoujt_chatgpt(userinfo): # 获取当前时间 now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) result = '[%s] %s\n' % (now, userinfo) headers = { 'Content-Type': 'application/json' } # msg_info = result msg_info = str(result).replace("\n", "") payload = { "msgtype": "text", "text": { "content": msg_info } } zhou = requests.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4478aey3dea-2c8e-4d6e-acc7-1c1n3n39ty47", data=json.dumps(payload), headers=headers)
# 这里一定要关闭请求,否则请求会逐渐增加 zhou.close() # Answer the last piece of information def answer_meg(question): openai.api_key = "sk-tPYjaksdhf23e3ccJ4uSaT3BlbkFJ2U40tFsz9EzmhfuqeyY87Z" completion = openai.Completion.create( engine="text-davinci-003", prompt=question, max_tokens=1024, temperature=1 ) an_info = completion.choices[0].text return an_info # 路由 @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': ip_req = request.form.get('requestivr') print(ip_req) try: shell = answer_meg(question=ip_req) print(shell) shell = list(shell) resultsh = "".join(shell) flash(u'Q: %s\t' % ip_req) flash(u'%s\n' % resultsh) zhoujt_chatgpt(userinfo=ip_req) zhoujt_chatgpt(userinfo=resultsh) except Exception as e: flash(u'Q: %s\t\t' % ip_req) flash(u'\t抱歉,ChatGPT负载过高,请稍后重试\t%s' % e) zhoujt_chatgpt(userinfo=e) return render_template('send.html') if __name__ == '__main__': app.run(host='0.0.0.0',port=6666, debug=True)
2.2、前端页面
<!DOCTYPE html> <html> <head> <title>ChatGPT</title> <link href="https://files.cnblogs.com/files/security-guard/Porsche.ico" rel="shortcut icon"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link href="../static/style.css" rel="stylesheet" type="text/css" media="all"/> </head> <body> <div class="null"></div> <div class="null"></div> <!-- main --> <form method="post"> <input class="text" type="text" name="requestivr" placeholder="What would you like to ask ChatGPT?" required=""> <input type="submit" value="submit"> <div class="wthree-text"> <div class="clear"></div> <div style="text-align: center;"> <div class="w3copyright-zhoujt"> {% for message in get_flashed_messages() %}<br> {{ message }}<br> {% endfor %} </div> </div> </div> </form> <!-- copyright --> <div class="w3copyright-agile"> <p>Please input your requests<a href="" title="#"></a></p> <p>This link is for entertainment only and not for commercial use<a href="" title="#"></a></p> </div> </div> </body> </html>
2.3、css调试代码
可见有两个 @media 其功能是为了区分手机端和PC端
@media only screen and (max-width: 767px) { input[type="text"] { outline: none; padding: 1em; width: 88%; margin: 2em 1em auto; text-align: center; border-radius: 10px; } input[type="submit"] { font-size: 1em; color: #fff; background: #007bff; outline: none; border: none; cursor: pointer; padding: 1em; -webkit-appearance: none; width: 88%; margin: 2em 1em auto; border-radius: 10px; } input[type="submit"]:hover { background: #0000FF; -webkit-transform: translateY(8px); -ms-transform: translateY(8px); -o-transform: translateY(8px); transform: translateY(8px); -webkit-box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.58); -moz-box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.58); box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.58); -webkit-transition: .5s all; -moz-transition: .5s all; -o-transition: .5s all; transition: .5s all; } .clear { clear: both; } .w3copyright-agile { margin: 2em 0 1em; text-align: center; } /*两个最下面提示黑白*/ .w3copyright-agile p { font-size: 1em; color: #0f6a18; line-height: 1.8em; /*background: #007bff;*/ } .w3copyright-agile p a { color: #9e3a18; } .w3copyright-agile p a:hover { color: #343a40; transition: 0.5s all; -webkit-transition: 0.5s all; -moz-transition: 0.5s all; -o-transition: 0.5s all; -ms-transition: 0.5s all; } .w3copyright-zhoujt { outline: none; padding: 1em; width: 85%; margin: 2em 1em auto; text-align: center; border-radius: 10px; } } @media only screen and (min-width: 768px) { input[type="text"] { font-size: 1em; margin: 1em 35%; padding: 1em; width: 28%; border-radius: 10px; } input[type="submit"] { font-size: 1em; color: #fff; background: #007bff; outline: none; border: none; cursor: pointer; padding: 1em; -webkit-appearance: none; width: 30%; margin: 2em 35%; border-radius: 10px; } input[type="submit"]:hover { background: #0000FF; -webkit-transform: translateY(8px); -ms-transform: translateY(8px); -o-transform: translateY(8px); transform: translateY(8px); -webkit-box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.58); -moz-box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.58); box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.58); -webkit-transition: .5s all; -moz-transition: .5s all; -o-transition: .5s all; transition: .5s all; } .clear { clear: both; } .w3copyright-agile { margin: 2em 0 1em; text-align: center; } /*两个最下面提示黑白*/ .w3copyright-agile p { font-size: 1em; color: #343a40; line-height: 1.8em; } .w3copyright-agile p a { color: #343a40; } .w3copyright-agile p a:hover { color: #343a40; transition: 0.5s all; -webkit-transition: 0.5s all; -moz-transition: 0.5s all; -o-transition: 0.5s all; -ms-transition: 0.5s all; } }
2.4、打包代码
目录结构
[root@Huawei ~/chatgpt/chatGPT]# tree ./ ./ |-- app.py |-- Dockerfile |-- __pycache__ | `-- prod.cpython-39.pyc |-- requirements.txt |-- static | `-- style.css `-- templates `-- send.html 3 directories, 7 files
三、部署项目
3.1、传统方式部署
安装虚拟环境 pip3 install virtualenv 创建虚拟环境 virtualenv win_adduser 进入虚拟环境 source /data/csweb/bin/activate 退出虚拟环境 deactivate [root@windowsop-tx-9208 bin]# source /data/csweb/bin/activate (csgpt) [root@windowsop-tx-9208 bin]# 将Python3和pip3安装到此虚拟环境 (csgpt) [root@Huawei ~/chatgpt]# which python3 /data/wds/bin/python3 (csgpt) [root@Huawei ~/chatgpt]# which pip3 /data/wds/bin/pip3 (csgpt) [root@Huawei ~/chatgpt]# 虚拟环境安装所需的包 pip3 install -r requirement.txt 创建虚拟环境启动的服务 [root@Huawei ~/chatgpt]# cat /etc/systemd/system/csgpt_test.service [Unit] Description=csgpt test environment After=syslog.target network.target [Service] User=root Group=root Type=simple Restart=always WorkingDirectory=/data/csgpt # 工作目录 ExecStart=/data/csgpt/bin/python3 app.py runserver 0.0.0.0:6666 # 启动命令 ExecStop=/bin/kill -15 $MAINPID # 安全模式杀进程 StandardOutput=syslog StandardError=syslog #SyslogIdentifier=csgpt.com SyslogFacility=local0 SyslogLevel=info [Install] WantedBy=multi-user.target [root@Huawei ~/chatgpt]#
3.2、docker部署
docker部署方便的很,下载docker就成,力荐docker
3.2.1、写好Dockerfile,用于构建编译
[root@Huawei ~/chatgpt/chatGPT]# cat Dockerfile FROM python:3.9 WORKDIR /root/chatgpt/chatGPT COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.douban.com/simple/ COPY . . CMD [ "python", "./prod.py" ] [root@Huawei ~/chatgpt/chatGPT]#
3.2.2、打包上传运行
# docker构建镜像 docker build -t chatgpt:1.3 . # 查看镜像 [root@Huawei ~/chatgpt/chatGPT]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE chatgpt 1.3 933455e34545 26 hours ago 932 MB # 测试环境 docker run -it --rm -p 8888:6666 chatgpt:0.1 # 生产环境 docker run -d -p 8888:6666 --name chatgpt2.3 chatgpt:1.3 # -d :使容器在后台运行 # -p :端口映射,即访问本机的前者(8888)相当于访问docker容器中的后者(6666) # 查看容器 [root@Huawei ~/chatgpt/chatGPT]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aef043d82ddd chatgpt:1.3 "python ./prod.py" 26 hours ago Up 26 hours 0.0.0.0:6201->8888/tcp chatgpt2.3 # docker查看镜像日志 docker logs -f --since 30m aef043d82ddd # 删除测试后无用的容器 docker ps -a | grep chatgpt1. | awk -F ' ' '{print $13}' | xargs docker rm # 停止类似Java的其他服务 docker ps | grep java | awk -F ' ' '{print $NF}' | xargs docker stop # 进入docker镜像环境 docker run -it chatgpt2.3 /bin/bash docker exec -it e621d1e639b1 bash # 运行中的容器 # docker查看镜像日志 docker logs -f --since 30m aef043d82ddd
四、查看效果
除了机器人,整个这个还算是不错的
完活收工~
中间遇到的问题:
1、请求数过多导致的,请求完后要关闭请求,close
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='qyapi.weixin.qq.com', port=443): Max retries exceeded with url: /cgi-bin/webhook/send?key=4d4effea-2c8e-4d6e-acc7-1c1b8d8ecb47 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f1796e65eb0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))
he debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.
You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:
dump()
shows all variables in the framedump(obj)
dumps all that's known about the object
2、证书问题
移除ssl认证 verify=False
response = requests.get(url, headers=headers,verify=False)
print(response)
# 但是可能会出现 InsecureRequestWarning 警告,
# 虽然不影响代码采集但是看着不舒服,可以加上下面两行:
import urllib3
urllib3.disable_warnings()