chat2db调用ollama实现数据库的操作。

news2024/12/22 16:07:20

只试了mysql的调用。

其它的我也不用,本来想充钱算了。最后一看单位是美刀。就放弃了这分心。于是折腾了一下。

本地运行chat2db 及chat2db ui

https://gitee.com/ooooinfo/Chat2DB
clone 后运行起来 chat2db的java端,我现在搞不清这一个项目是有没有链接到数据库里去。
在idea项目中运行
在这里插入图片描述
在这里插入图片描述

前端在:chat2db-client中。我的环境是 node 20 ,yarn , 注意可能需要 yarn add electron
直接运行:yarn start
在这里插入图片描述

安装ollama 以及模型 qwen2.5 这里我也不懂。不知装那一个好。

https://ollama.com/
在这里插入图片描述
在powershell下运行:ollama run qwen2.5 或 ollama pull qwen2.5
最终你要保证ollama启运。

仿一下openai的接口 调用ollama 提供给chat2db:

chat2db中这样设置,所以需要我自己写一个app.py 去做一下代理请求ollama,不是我不想写自定义,主要是总不成功。不如直接仿openai .
在这里插入图片描述

app.py的部分代码。

我用的conda 创建的3.9的环境:
requirements.txt

fastapi==0.104.1
uvicorn==0.24.0
httpx==0.25.1
tenacity==8.2.3
backoff

相关的app.py的代码:

from fastapi import FastAPI, HTTPException, Request, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, StreamingResponse
import httpx
import uvicorn
import traceback
import sys
import time
import json
import asyncio
import re
import backoff  # 确保已安装 backoff 库

app = FastAPI(
    title="Ollama API Adapter",
    description="An adapter for Ollama API that mimics OpenAI API format",
    version="1.0.0"
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

API_KEY = "sk-123456"
OLLAMA_BASE_URL = "http://127.0.0.1:11434"
DEFAULT_MODEL = "qwen2.5:latest"
def verify_api_key(request: Request):
    authorization: str = request.headers.get('authorization')
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header is missing.")

    token_type, _, token = authorization.partition(' ')
    if token_type.lower() != 'bearer' or token != API_KEY:
        raise HTTPException(status_code=401, detail="Unauthorized: API Key is invalid or missing.")


@app.get("/v1", dependencies=[Depends(verify_api_key)])
async def root():
    """
    Root endpoint that returns API information
    """
    return {
        "version": "1.0.0",
        "status": "ok",
        "endpoints": [
            "/v1/chat/completions",
            "/v1/models",
            "/health"
        ]
    }

@app.get("/v1/models", dependencies=[Depends(verify_api_key)])
async def list_models():
    """
    List available models
    """
    try:
        async with httpx.AsyncClient(timeout=10.0) as client:
            response = await client.get(f"{OLLAMA_BASE_URL}/api/tags")
            if response.status_code == 200:
                models = response.json().get("models", [])
                return {
                    "data": [
                        {
                            "id": model["name"],
                            "object": "model",
                            "created": 0,
                            "owned_by": "ollama"
                        }
                        for model in models
                    ]
                }
            else:
                raise HTTPException(status_code=503, detail="Ollama service unavailable")
    except Exception as e:
        print(f"Error listing models: {str(e)}")
        raise HTTPException(status_code=503, detail=str(e))

@app.get("/health", dependencies=[Depends(verify_api_key)])
async def health_check():
    """
    健康检查接口
    """
    try:
        async with httpx.AsyncClient(timeout=5.0) as client:
            response = await client.get(f"{OLLAMA_BASE_URL}/api/tags")
            if response.status_code == 200:
                print("Ollama service is healthy.")
                return {"status": "healthy", "message": "服务运行正常"}
            else:
                print("Ollama service is not healthy.")
                raise HTTPException(status_code=503, detail="Ollama 服务不可用")
    except httpx.HTTPStatusError as exc:
        print(f"HTTP error occurred: {exc.response.status_code}")
        raise HTTPException(status_code=exc.response.status_code, detail=str(exc))
    except httpx.RequestError as exc:
        print(f"An error occurred while requesting {exc.request.url!r}.")
        raise HTTPException(status_code=500, detail=str(exc))

async def generate_sse_response(content):
    # 提取 SQL 语句并添加换行
    sql_match = re.search(r'```sql\n(.*?)\n```', content, re.DOTALL)
    sql = sql_match.group(1).strip() if sql_match else content
    
    # 添加换行符
    formatted_content = f"{sql}\n"
    
    # 构造 OpenAI API 格式的响应
    response_data = {
        "id": f"chatcmpl-{int(time.time())}",
        "object": "chat.completion.chunk",
        "created": int(time.time()),
        "model": "gpt-3.5-turbo",
        "choices": [{
            "delta": {
                "content": formatted_content  # 使用带换行的内容
            },
            "finish_reason": None,
            "index": 0
        }]
    }
    
    # 发送主要内容
    yield f"data: {json.dumps(response_data, ensure_ascii=False)}\n\n"
    
    # 发送结束消息
    finish_response = {
        "id": f"chatcmpl-{int(time.time())}",
        "object": "chat.completion.chunk",
        "created": int(time.time()),
        "model": "gpt-3.5-turbo",
        "choices": [{
            "delta": {},
            "finish_reason": "stop",
            "index": 0
        }]
    }
    
    yield f"data: {json.dumps(finish_response, ensure_ascii=False)}\n\n"
    yield "data: [DONE]\n\n"

# 重试策略装饰器
@backoff.on_exception(backoff.expo, httpx.ReadTimeout, max_tries=5, max_time=300)
async def send_request(ollama_request):
    timeout_config = httpx.Timeout(10.0, read=120.0)  # 连接超10秒,读取超时120秒
    async with httpx.AsyncClient(timeout=timeout_config) as client:
        try:
            response = await client.post(
                f"{OLLAMA_BASE_URL}/api/chat",
                json=ollama_request
            )
            print(f"Response received with status {response.status_code}")
            return response
        except httpx.RequestError as exc:
            print(f"An error occurred while requesting {exc.request.url!r}.")
            raise HTTPException(status_code=500, detail=str(exc))

@app.post("/v1/chat/completions", dependencies=[Depends(verify_api_key)])
@app.post("/chat/completions", dependencies=[Depends(verify_api_key)])
@app.post("/", dependencies=[Depends(verify_api_key)])
async def chat_completions(request: Request):
    try:
        body = await request.json()
        messages = body.get("messages", [])
        stream = body.get("stream", True)

        print(f"Received request with body: {body}")  # 使用 print 打印请求体

        ollama_request = {
            "model": DEFAULT_MODEL,
            "messages": messages,
            "stream": False
        }
        
        response = await send_request(ollama_request)
        print(f"Received response: {response.text}")  # 使用 print 打印响应文本
        
        if response.status_code != 200:
            print(f"Failed to get response from model, status code: {response.status_code}")
            raise HTTPException(status_code=400, detail="Failed to get response from model")
        
        ollama_response = response.json()
        content = ollama_response.get("message", {}).get("content", "")
        
        print(f"Processed content: {content}")  # 使用 print 打印处理后的内容

        if not stream:
            result = {
                "id": f"chatcmpl-{int(time.time())}",
                "object": "chat.completion",
                "created": int(time.time()),
                "model": DEFAULT_MODEL,
                "choices": [{
                    "message": {
                        "role": "database developer and expert",
                        "content": content
                    },
                    "finish_reason": "stop",
                    "index": 0
                }]
            }
            print(f"Returning non-stream response: {result}")  # 使用 print 打印非流响应
            return result
        
        headers = {
            "Content-Type": "text/event-stream",
            "Cache-Control": "no-cache",
            "Connection": "keep-alive"
        }
        
        return StreamingResponse(
            generate_sse_response(content),
            media_type="text/event-stream",
            headers=headers
        )
        
    except json.JSONDecodeError as e:
        print(f"JSON decoding error: {str(e)}")
        return JSONResponse(status_code=400, content={"message": "Invalid JSON data"})
    except Exception as e:
        print(f"Error during chat completions: {str(e)}")
        print(traceback.format_exc())  # 使用 print 打印堆栈跟踪
        return JSONResponse(
            status_code=500,
            content={"message": "Internal server error"}
        )
    
if __name__ == "__main__":
    print("Starting server on 0.0.0.0:8080")
    uvicorn.run(app, host="0.0.0.0", port=8080)

上面代码装key及model都写死,所以你一下要先下载下来相关的模型 。
python app.py
在这里插入图片描述
再注意以下本置:
在这里插入图片描述
在chat2db做好链接,再输入你的提示词。见下面效果:
在这里插入图片描述
响应速度几秒钟,当时看自己电脑响应速度了。都不花钱了,就不要什么自行车了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2240812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

主机型入侵检测系统(HIDS)——Elkeid在Centos7的保姆级安装部署教程

一、HIDS简介 主机型入侵检测系统(Host-based Intrusion Detection System 简称:HIDS);HIDS作为主机的监视器和分析器,主要是专注于主机系统内部(监视系统全部或部分的动态的行为以及整个系统的状态)。 HIDS使用传统的C/S架构,只需要在监测端安装agent即可,且使用用户…

qt中ctrl+鼠标左键无法进入

现象:qt中ctrl鼠标左键无法跳转部分函数,例如能跳到textEdit->toPlainText().,但无法跳转到toUtf8();但编译没有问题 排查1:我发现是交叉编译链的问题,使用linux自带就可以进,用ATK-I.MX6U就部分不能进…

Android gradle下载失败后 解决方案

Android 导入gradle一直失败,更新gradle源即可 比如项目里默认的是 distributionUrlhttps\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 用下面这个来替换distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-7.3.3-bin.zip

基于Java Springboot餐厅点餐系统(加入商家版)

一、作品包含 源码数据库设计文档万字全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA 数据库:MySQL5.7…

开源项目推荐——OpenDroneMap无人机影像数据处理

实景三维作为GIS最火的课题,最近在想做一套自己的三维构建工具,考察了几个开源项目,把自己的搜索过程用csdn记录下来,希望也能帮助到各位同仁。 OpenDroneMap(ODM)是一个开源项目,旨在处理无人…

手动安装Ubuntu系统中的network-manager包(其它包同理)

自己手闲把系统中的network-manager包给删了,导致的结果就是Ubuntu系统彻底没有网络。结果再装network-manager时,没有网络根本装不了,网上的方法都试了也没用,然后就自己源码装,这篇文章就是记录一下怎么手动下载包然…

【C++】从零实现 C++ 自定义 list 容器:双向链表与迭代器深度解析

个人主页: 起名字真南的CSDN博客 个人专栏: 【数据结构初阶】 📘 基础数据结构【C语言】 💻 C语言编程技巧【C】 🚀 进阶C【OJ题解】 📝 题解精讲 目录 📌 1. 引言📌 2. 内容概要📌 3. list 容…

Python Excel XLS或XLSX转PDF详解:七大实用转换设置

目录 使用工具 Python将Excel文件转换为PDF Python将Excel文件转换为带页码的PDF Python将Excel文件转换为特定页面尺寸的PDF Python将Excel文件转换为PDF并将内容适应到一页 Python将Excel文件转换为PDF/A Python将Excel文件中的工作表转换为单独的PDF Python将Excel工…

Centos 7 安装wget

Centos 7 安装wget 最小化安装Centos 7 的话需要上传wget rpm包之后再路径下安装一下。rpm包下载地址(http://mirrors.163.com/centos/7/os/x86_64/Packages/) 1、使用X-ftp 或者WinSCP等可以连接上传的软件都可以首先连接服务器,这里我用的…

LabVIEW 使用 Snippet

在 LabVIEW 中,Snippet(代码片段) 是一个非常有用的功能,它允许你将 一小段可重用的代码 保存为一个 图形化的代码片段,并能够在不同的 VI 中通过拖放来使用。 什么是 Snippet? Snippet 就是 LabVIEW 中的…

A3超级计算机虚拟机,为大型语言模型LLM和AIGC提供强大算力支持

热门大语言模型项目地址:www.suanjiayun.com/mirrorDetails?id66ac7d478099315577961758 近几个月来,我们目睹了大型语言模型(LLMs)和生成式人工智能强势闯入我们的视野,显然,这些模型在训练和运行时需要…

开源音乐分离器Audio Decomposition:可实现盲源音频分离,无需外部乐器分离库,从头开始制作。将音乐转换为五线谱的程序

今天给大家分析一个音频分解器,通过傅里叶变换和信封匹配分离音乐中的各个音符和乐器,实现音乐到乐谱的转换。将音乐开源分离为组成乐器。该方式是盲源分离,从头开始制作,无需外部乐器分离库。 相关链接 代码:https:…

35.3K+ Star!PhotoPrism:一款基于AI的开源照片管理工具

PhotoPrism 简介 PhotoPrism[1] 是一个为去中心化网络设计的AI照片应用,它利用最新技术自动标记和查找图片,实现自动图像分类与本地化部署,你可以在家中、私有服务器或云端运行它。 项目特点 主要特点 浏览所有照片和视频,无需担心RAW转换、重复项或视频格式。 使用强大的…

基于Spider异步爬虫框架+JS动态参数逆向+隧道代理+自定义中间件的猎聘招聘数据爬取

在本篇博客中,我们将介绍如何使用 Scrapy 框架结合 JS 逆向技术、代理服务器和自定义中间件,来爬取猎聘网站的招聘数据。猎聘是一个国内知名的招聘平台,提供了大量的企业招聘信息和职位信息。本项目的目标是抓取指定城市的招聘信息&#xff0…

计算机网络 (2)计算机网络的类别

计算机网络的类别繁多,根据不同的分类原则,可以得到各种不同类型的计算机网络。 一、按覆盖范围分类 局域网(LAN): 定义:局域网是一种在小区域内使用的,由多台计算机组成的网络。覆盖范围&#…

超好用shell脚本NuShell mac安装

利用管道控制任意系统 Nu 可以在 Linux、macOS 和 Windows 上运行。一次学习,处处可用。 一切皆数据 Nu 管道使用结构化数据,你可以用同样的方式安全地选择,过滤和排序。停止解析字符串,开始解决问题。 强大的插件系统 具备强…

【C#设计模式(9)——组合模式(Component Pattern)】

前言 组合模型是将对象组合成树形结构以表示“整体-部分”的层次结构,使客户终端代码更加简洁和灵活。 代码 //目录抽象类 public abstract class Directory {protected string _name;public Directory(string name){_name name;}public abstract void Show(); } …

Ubuntu下Xshell连接腾讯云服务器

1.在腾讯云上买好服务器后,找到控制台,找到自己的服务器重置密码,默认用户名时ubuntu 2.在Xshell连接服务器 然后出现一个秘钥接受,直接接受就好了,然后就出现下面 然后就可以了 查看当前登录的用户 whoami 查看当前服…

初识算法 · 位运算(3)

目录 前言: 两整数之和 题目解析 算法原理 算法编写 只出现一次的数字II 题目解析 算法原理 算法编写 前言: ​本文的主题是位运算,通过两道题目讲解,一道是只出现一次的数字II,一道是两整数之和。 链接分别…

微信小程序——01开发前的准备和开发工具

文章目录 一、开发前的准备1注册小程序账号2安装开发者工具 二、开发者工具的使用1创建项目2 工具的使用3目录结构4各个页面之间的关系5 权限管理6提交审核和发布 一、开发前的准备 开发前需要进行以下准备: 1 注册小程序账号2激活邮箱3 信息登记4 登录小程序管理后…