当前位置: 首页 > news >正文

使用go语言、Python脚本搭建一个简单的chatgpt服务网站。

使用go语言、Python脚本搭建一个简单的GPT服务网站

前言

研0在暑假想提升一下自己,自学了go语言编程和机器学习相关学习,但是一味学习理论,终究是枯燥的,于是自己弄点小项目做。

在这之前,建议您需要掌握以下两个技巧,我在这里不赘述了

  1. 一个openAI账号,并申请了KEY(b站有教程)
  2. 魔法的method(自己摸索哈~网上应该也有教程嘿嘿~)

现在开始!!!

文章目录

  1. Python准备
  2. go服务器与html页面
  3. 总结与效果展示

一、准备一个Python脚本

第一步:利用pip下载OpenAi依赖包

pip install openai

第二步:将openai的操作封装成一个类,OpenAi.py

import openaiclass OpenAi:def __init__(self, key):"""传入一个key:param key: 你申请的key"""openai.api_key = key # 这里设置keyself.model_name = "gpt-3.5-turbo"  # 使用默认chatgpt3.5模型self.role = "user"  # 使用user的角色,此外还有system等角色,可以自己改着来玩玩def submit(self, question):"""这个方法向gpt发送你想发给gpt的message, 返回一个response对象,是json格式的"""response = openai.ChatCompletion.create(model=self.model_name,  # 使用ChatGPT引擎messages=[{"role": "user", "content": question},],temperature=0,# stream=True  # this time, we set stream=True)return response

第三步:编写Python脚本 testGPT2.py,注意修改自己的key

import os, sys
# 这里我们导入刚才封装的类
import OpenAI as opdef main():# 接受命令行参数args = sys.argv[1:]message = " ".join(args)open_ai_object = op.OpenAi("把你申请的key复制到这里来")response = open_ai_object.submit(message)# 取出gpt的回答gpt_answer = response["choices"][0]["message"]["content"]# 以utf-8的形式输出到命令行,避免中文乱码,后续go语言将会读取print(gpt_answer.encode('utf-8'))if __name__ == '__main__':main()

第四步:测试一下下,启动cmd,cd到testgpt2.py的目录下

python testgpt2.py 你是谁啊?
python testgpt2.py who are you?

在这里插入图片描述
可以发现当询问中文时,脚本会返回中文的utf-8编码,询问英文的时候,会返回英文内容。
运行成功!!!!!!

小结:截至目前,python脚本准备好了,我们接下来使用go搭建一个简单的服务器。

二、搭建一个go服务器和一个html页面,注意修改自己的路径

这里需要准备一个服务器代码和一个html页面,这里直接提供给大家。
初学go!可能有漏洞,欢迎大家指正!

server.go

package mainimport ("bytes""encoding/json""fmt""io""net/http""os""os/exec""strings"
)var count int = 0func main() {// 注册处理函数http.HandleFunc("/data", askForGpt)http.HandleFunc("/", helloHandler)// 启动服务器,监听在指定的端口port := 8080fmt.Printf("Server started at :%d\n", port)err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)if err != nil {fmt.Println("Error:0", err)}
}const (// 这里大家改成自己html页面的路径即可HTML_PATH = "C:\\Users\\45191\\Desktop\\test8.html"
)// 这个函数调用后会向前端返回一个html页面
func helloHandler(w http.ResponseWriter, r *http.Request) {countUsers()responseHtmlContent := readHtmlFileAll(HTML_PATH)// 向客户端发送响应fmt.Fprint(w, responseHtmlContent)
}// 服务器读取本地html页面
func readHtmlFileAll(path string) string {// 打开文件file, err := os.Open(path)if err != nil {fmt.Printf("Error: %v\n", err)return "ERROR"}defer file.Close()// 读取文件内容content, err := io.ReadAll(file)if err != nil {fmt.Println("Error:", err)return "Error"}return string(content)
}// 简单地统计一下多少个用户访问
func countUsers() {count++fmt.Printf("第%d个用户访问服务器!\n", count)
}// 这个函数负责从前端发来的请求中解析出用户要问gpt的问题,然后执行python脚本,
// 将答案返回
func askForGpt(w http.ResponseWriter, r *http.Request) {countUsers()// 读取 POST 请求的内容body, err := io.ReadAll(r.Body)if err != nil {http.Error(w, "Error reading request body", http.StatusInternalServerError)return}defer r.Body.Close()question := parseJson(body)answer := execPythonScript(question)answerJsonObject := ResponseData{Answer: answer,}data, err := json.Marshal(answerJsonObject)fmt.Fprint(w, string(data))
}// 定义一个接受json数据的内容,用来接受前端发来的json格式数据
type RequestData struct {Content string `json:"content"`
}// 定义一个reponse数据
type ResponseData struct {Answer string `json:"answer"`
}// 解析json格式数据
func parseJson(body []byte) string {var requestData RequestDataerr := json.Unmarshal(body, &requestData)if err != nil {fmt.Printf("Error parseJson: %v", err)}fmt.Printf("requestData: %v\n", requestData)return requestData.Content
}const (// 这里大家改成自己的python脚本路径即可SCRIPT_PATH = "D:\\pyprojects\\MachineLearning\\testGPT2.py"
)// 运行python脚本的函数
func execPythonScript(question string) string {// 定义要运行的Python参数scriptArgs := []string{question}// 创建一个Command对象运行Python脚本cmd := exec.Command("python", append([]string{SCRIPT_PATH}, scriptArgs...)...)fmt.Println(cmd)var stdout, stderr bytes.Buffer// 设置命令的输出和错误输出cmd.Stdout = &stdoutcmd.Stderr = &stderr// 执行命令等待完成err := cmd.Run()if err != nil {fmt.Println("Error running Python script: ", err)return ""}fmt.Println("Python script completed")// 从python脚本的输出中获得答案rawString := strings.TrimSpace(stdout.String())[2:]rawString = rawString[:len(rawString)-1]s := strings.ReplaceAll(rawString, "\\n", "\n")return s
}

test8.html

偷偷告诉大家这个代码大部分是我叫gpt帮我写的,哈哈哈哈,毕竟搞不来前端,我只是改了少量内容,比如js部分代码。

<!DOCTYPE html>
<html>
<head><title>精美左右布局页面</title><style>body {font-family: Arial, sans-serif;margin: 0;padding: 0;background-color: #f5f5f5;}.container {display: flex;justify-content: space-between;align-items: stretch;height: 100vh;background-color: #fff;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);border-radius: 5px;margin: 20px auto;overflow: hidden;}.left {width: 40%;padding: 20px;padding-right: 30px;background-color: #f8f8f8;}.right {flex: 1;padding: 20px;padding-left: 30px;background-color: #fff;overflow: auto;border-left: 1px solid #ddd;}h1, h2 {margin: 0 0 10px;color: #333;}input[type="text"] {width: 100%;padding: 10px;margin-bottom: 15px;border: 1px solid #ccc;border-radius: 5px;font-size: 16px;box-sizing: border-box;}button {padding: 10px 20px;background-color: #007bff;color: #fff;border: none;border-radius: 5px;cursor: pointer;}pre {white-space: pre-wrap;word-wrap: break-word;}.history-icon {font-size: 20px;cursor: pointer;}</style>
</head>
<body><div class="container"><div class="left"><h2>输入问题:</h2><input type="text" id="question" name="question"><button onclick="getAnswer()">获取答案</button><details><summary><span class="history-icon">&#x1F4DD;</span> 查看历史问题</summary><ul><li>历史问题 1</li><li>历史问题 2</li><li>历史问题 3</li><!-- 在这里添加更多历史问题 --></ul></details></div><div class="right"><h2>答案:</h2><pre id="answer"></pre></div></div><script>function getAnswer() {// 获取输入框内容var questionInput = document.getElementById("question");var answerPre = document.getElementById("answer");// 构造 POST 请求的数据var data = {content: questionInput.value};// 发送 POST 请求fetch("http://localhost:8080/data", {method: "POST",headers: {"Content-Type": "application/json"},body: JSON.stringify(data)}).then(response => response.json()).then(data => {// 将 UTF-8 编码的字节序列转换为 Uint8Arrayvar byteString = data.answervar decodedString = decodeUtf8(byteString)answerPre.textContent = decodedString}).catch(error => {});}// 自己写的utf-8格式转文本函数function decodeUtf8(byteString){var resStr = ""var subStr = ""var count = 0for (var i = 0;i<byteString.length-1;){if (byteString[i] == '\\' && byteString[i+1] == 'x'){subStr += byteString.substr(i+2,2)i = i + 4count ++if (count == 3){resStr += hexToUtf8String(subStr)subStr = ""count = 0}} else {resStr += byteString[i]i ++}   }return resStr}function hexToUtf8String(hex) {const bytes = [];for (let i = 0; i < hex.length; i += 2) {bytes.push(parseInt(hex.substr(i, 2), 16));}return new TextDecoder().decode(new Uint8Array(bytes));}</script>
</body>
</html>

三、总结与效果展示

通过以上步骤,就已经实现了本题目的简单的要求,下面进行效果展示。

前端页面输出,访问127.0.0.1:8080

在这里插入图片描述

后台服务器输出

在这里插入图片描述

后续,我将继续学习,继续完善加强这个小项目,添加更多功能,欢迎关注!!!如果有什么问题,欢迎在评论区发表,一起学习,一起纠错!!!

相关文章:

使用go语言、Python脚本搭建一个简单的chatgpt服务网站。

使用go语言、Python脚本搭建一个简单的GPT服务网站 前言 研0在暑假想提升一下自己&#xff0c;自学了go语言编程和机器学习相关学习&#xff0c;但是一味学习理论&#xff0c;终究是枯燥的&#xff0c;于是自己弄点小项目做。 在这之前&#xff0c;建议您需要掌握以下两个技…...

基于java会议室预约系统设计与实现

摘要 一个企业的发展离不开相关的规定流程。信息化到来的今天在我们的生活当中。离不开各种信息化的支持。比如钉钉会议预约、美团买菜、扫码签到等各种信息化软件。他们涉及我们生活中的方方面面给我们的生活提供了更大的便利性。大到政府、企业办公小到人们的衣食住行都离不开…...

Ubuntu18.04 交叉编译curl-7.61.0

下载 官方网址是&#xff1a;curl 安装依赖库 如果需要curl支持https协议&#xff0c;需要先交叉编译 openssl,编译流程如下&#xff1a; Ubuntu18.04 交叉编译openssl-1.1.1_我是谁&#xff1f;&#xff1f;的博客-CSDN博客 解压 # 解压&#xff1a; $tar -xzvf curl-7.61.…...

Android相机-HAL子系统

引言 应用框架要通过拍照预览摄像获得照片或者视频,就需要向相机子系统发出请求, 一个请求对应一组结果 一次可发起多个请求&#xff0c;并且提交请求是非阻塞的&#xff0c;始终按照接收的顺序以队列的形式先进先出地进行顺序处理 一个请求包含了拍摄和拍照配置的所有信息&…...

PostgreSQL-研究学习-介绍与安装

PostgreSQL-预研 是个很厉害的数据库的样子 ψ(*&#xff40;ー)ψ 官方文档&#xff1a;http://www.postgres.cn/docs/12/ 总的结论和备注 PgSQL 支持对JSON的支持很强大&#xff0c;以及提供了很多数学几何相关的数据类型【例&#xff1a;点&#xff0c;线条&#xff0c;几何…...

【Unity细节】Unity制作汽车时,为什么汽车会被弹飞?为什么汽车会一直抖动?

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…...

Android初学之android studio运行java/kotlin程序

第一步骤&#xff1a;File—>New—>New Module&#xff0c;然后弹出一个框&#xff0c;&#xff08;左边&#xff09;选择Java or Kotlin Library&#xff0c;&#xff08;右边&#xff09;编辑自己的图书馆名、包名、类名&#xff0c;选择Java一个语言&#xff0c;然后F…...

使用自定义 C ++类扩展 TorchScript

使用自定义 C 类扩展 TorchScript 本教程是自定义运算符教程的后续教程&#xff0c;并介绍了我们为将 C 类同时绑定到 TorchScript 和 Python 而构建的 API。 该 API 与 pybind11 非常相似&#xff0c;如果您熟悉该系统&#xff0c;则大多数概念都将转移过来。 在 C 中实现和…...

UITableView自定义TableHeader和TableFooter

UITableView自定义TableHeader和TableFooter 我猜你希望的效果是这样的 我猜你希望的效果是这样的 自定义页眉视图 让我们创建一个文件名 UITableViewHeaderFooterView 的 CustomerHeaderView 子类。 现在让我们创建视图的 Xib 文件并将其命名为 CustomHeaderView。 更改高度标…...

【TA 挖坑03】雾效 | 透光材质 | Impostor | 厚度转球谐

仍旧是记录下半年想要做的东西&#xff0c;很有趣&#xff0c;实现“一团雾效” “面片也有立体感” 等等效果的一些技术上的方法。 仅粗浅记录&#xff0c;保证之后自己填坑的时候看得懂就行&#xff01; 透光 -> 透光材质ShadingModel 《永劫无间》透光材质的渲染&…...

案例-基于MVC和三层架构实现商品表的增删改查

文章目录 0. 项目介绍1. 环境准备2. 查看所有2.1 编写BrandMapper接口2.2 编写服务类&#xff0c;创建BrandService&#xff0c;用于调用该方法2.5 编写Servlet2.4 编写brand.jsp页面2.5 测试 3.添加3.1 编写BrandMapper接口 添加方法3.2 编写服务3.3 改写Brand.jsp页面&#x…...

Java——一个简单的计算器程序

该代码是一个简单的计算器程序&#xff0c;使用了Java的图形化界面库Swing。具体分析如下&#xff1a; 导入必要的类和包&#xff1a; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Objects; import javax.…...

自定义滑动到底部触发指令,elementUI实现分页下拉框

在 main.js 中添加 // 自定义滑动到底部指令 Vue.directive(selectLoadMore, {bind(el, binding) {// 获取element-ui定义好的scroll盒子const SELECTWRAP_DOM el.querySelector(.el-select-dropdown .el-select-dropdown__wrap)SELECTWRAP_DOM.addEventListener(scroll, fun…...

【Windows 常用工具系列 10 -- linux ssh登录脚本输入密码】

文章目录 脚本输入SSH登录密码scp 脚本免密传输 脚本输入SSH登录密码 sshpass 是一个用于运行时非交互式ssh密码提供的工具&#xff0c;它允许你直接在命令行中为ssh命令提供密码。这就意味着你可以在脚本中使用ssh命令&#xff0c;而不需要用户交互地输入密码。 一般来说&am…...

C#的索引器

索引器 在 C# 中&#xff0c;索引器&#xff08;Indexer&#xff09;是一种特殊的属性&#xff0c;允许通过类的实例像访问数组一样访问对象的元素。索引器允许将类的实例作为集合来使用&#xff0c;可以按照自定义的方式访问类中的元素。 索引器的定义类似于属性&#xff0c…...

软件配置安装(破解)--- maven下载配置

检查环境是否已有 首先检查一下电脑里有无maven环境&#xff0c;有的话就不用安装了 查看path环境中没有maven&#xff0c;开始准备接下来的重头戏 下载maven 下载bin.zip版 解压mavenxxxbin.zip &#xff08;建议把解压的文件放在一个文件夹内&#xff0c;命名英文的env…...

python解析小说

前言 在信息爆炸的时代&#xff0c;网络上充斥着大量的小说资源&#xff0c;让人们能够随时随地尽享阅读的乐趣。然而&#xff0c;有些小说网站要求用户付费才能获取完整的内容&#xff0c;这给许多人带来了困扰&#xff0c;尤其是像我这类对金钱概念模糊的人。不过&#xff0…...

SQL Server 执行报错: “minus“ 附近有语法错误。

sql server 执行带 minus 的语句一直报错&#xff0c;如下图&#xff1a; 找了好久才知道minus是Oracle里面的语法&#xff0c;SQL server 应用 EXCEPT。...

kali linux查看局域网下所有IP,并对指定IP攻击

kali linux查看局域网下所有IP&#xff0c;并对指定IP实施局域网内攻击 首先我们打开我们熟悉的kali linux操作系统&#xff0c;利用指令&#xff1a; ifconfig来确认本机的ip地址 确认了本机的ip地址之后&#xff0c;利用一下的指令查看局域网下所有ip: fping -g 本机IP地址…...

基于QCC_BES 平台的LMS自适应滤波算法实现

+我V hezkz17进数字音频系统研究开发交流答疑群(课题组) LMS算法是最小均方(Least Mean Square)算法的缩写。它是一种自适应滤波算法,常用于信号处理、系统辨识和自适应滤波等领域。 LMS算法的目标是通过对输入信号和期望输出信号之间的误差进行最小化,来调整滤波器的权重…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...