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

Django中使用流式响应,自己也能实现ChatGPT的效果

最近在研究ChatGPT的时候,想通过openai提供的接口使国内用户也可以无限制访问,于是打算基于django开发一款应用。页面的渲染也得想ChatGPT一样采用流式响应,django中StreamingHttpResponse是支持流式响应的一种方式。

django 代码

class ChatView(APIView):def get(self, request, *args, **kwargs):prompt= request.GET.get('prompt', '')chat_response = openai.ChatCompletion.create(model="gpt-3.5-turbo",stream=True,messages=[{'role': 'user','content': prompt,}])def get_streaming_content(chat_response):for chunk in chat_response:yield chunkresponse = StreamingHttpResponse(get_streaming_content(chat_response), content_type='application/octet-stream')return response

settings.py

TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR,'templates')],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]

遇到的问题

在本地通过python manage runserver启动项目后,通过浏览器访问(一开始是GET请求)是能明显看到效果的,但是当使用Nginx+uwsgi部署之后,发现流式响应失效了,于是研究了一下写下这篇文章备忘。

解决方案

首先Nginx和uwsgi的通信方式不能使用socket方式,必须使用http方式,还得修改部分Nginx配置

nginx部分配置

location / {proxy_pass http://127.0.0.1:8080;proxy_buffering off;  # 重点是这个配置
}

uwsgi部分配置

[uwsgi]
; 不能使用socket方式通信
;socket = /tmp/uwsgi_%(site_name).sock
; 使用http方式通信
http = 0.0.0.0:8080

GET请求直接在浏览器打开才有此问题,POST请求前端处理流没有哦

附上前端处理响应并实时渲染的代码

<!DOCTYPE html>
<html>
<head><title>Demo</title><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body><div class="container mt-5"><div class="row"><div class="col-md-6 offset-md-3"><div class="form-group"><label for="inputText">输入内容:</label><textarea class="form-control" id="inputText" placeholder="在这里输入内容"></textarea></div><button type="button" id="submitBtn" class="btn btn-primary">提交</button></div></div><div class="row mt-3"><div class="col-md-6 offset-md-3"><div id="responseContainer" class="border p-3"></div></div></div>
</div><script>$(document).ready(function () {$('#submitBtn').click(function () {var inputText = $('#inputText').val();function displayData(data) {var outputDiv = document.getElementById('responseContainer');outputDiv.innerText += data;}fetch('/api/chatgpt/chat/', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({'input': inputText}),}).then(function (response) {// 确保响应状态码正常if (!response.ok) {throw new Error('Response failed');}// 使用响应的ReadableStream来处理数据var reader = response.body.getReader();function read() {return reader.read().then(function (result) {// 处理读取到的数据if (!result.done) {var value = result.value;// 在这里处理接收到的数据,例如更新页面上的内容var decoder = new TextDecoder('utf-8')var chunk = decoder.decode(value)displayData(chunk)// 继续读取下一块数据return read();}});}return read();}).catch(function (error) {// 处理错误});});});
</script>
</body>
</html>

http://www.xdnf.cn/news/14471.html

相关文章:

  • CGAL 快速构建三维凸包
  • 20年架构师视角:SpringAI如何重塑Java技术栈?
  • 进程和线程区别、管道和套接字、共享变量、TCP三次握手,是否可以少一次握手、子进程和主进程区别和API——Nodejs
  • 206. 反转链表
  • ArkUI-X框架LogInterface使用指南
  • C++题解(36) 2025年顺德区中小学生程序设计展示活动(初中组C++)换位(二)
  • BeckHoff <---> Mitsubishi RH-20FR(三菱)水平关节机械手通过网桥(EL6692)通讯
  • C++队列的那些事儿
  • db2主从同步 逻辑复制 APPLY_THROTTLE参数
  • LangGraph AI 系统测试与高可用保障体系
  • SwiftHub 项目分析
  • Linux之Python定制篇——新版Ubuntu24.04安装
  • to avoid naming wrong index webpage for one website
  • DrissionPage如何通过截图的方式获取图片
  • 水果商城管理系统笔记
  • 零基础上手Conda:安装、创建环境、管理依赖的完整指南
  • 计算机硬件——主板
  • 架构设计的核心原则与基础理论
  • 什么是java jdk?
  • Eclise中Lombck配置
  • DC8靶机渗透
  • 数据赋能(259)——数据赋能业务——数据驱动业务转型
  • DAY 54 Inception网络及其思考
  • 进程上下文与中断上下文详解
  • Spring AI的ChatClient和ChatModel接口
  • YOLOv3 正负样本划分详解
  • OpenIPC-aviateur上位机程序编译环境配置
  • 【AI大模型】Elasticsearch9 + 通义大模型实现语义检索操作详解
  • Logos心法:一份认知进化的活地图
  • Spring Boot 实训项目 - 图书信息网站