From ebc5c01eb0a15e7a8120af21fd84bd2cbc4eae53 Mon Sep 17 00:00:00 2001 From: heshunme Date: Fri, 25 Oct 2024 20:53:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 ++ .idea/deployment.xml | 14 ++ .idea/hw_ocr_backend.iml | 8 ++ .idea/inspectionProfiles/Project_Default.xml | 52 +++++++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 32 +++++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + main.py | 115 +++++++++++++++ test.html | 132 ++++++++++++++++++ test.py | 36 +++++ test/__init__.py | 6 + test/clientTest.py | 33 +++++ test/test.py | 23 +++ test/test2.py | 13 ++ test_main.http | 11 ++ 16 files changed, 503 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/deployment.xml create mode 100644 .idea/hw_ocr_backend.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 main.py create mode 100644 test.html create mode 100644 test.py create mode 100644 test/__init__.py create mode 100644 test/clientTest.py create mode 100644 test/test.py create mode 100644 test/test2.py create mode 100644 test_main.http diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..c83a726 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/hw_ocr_backend.iml b/.idea/hw_ocr_backend.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/hw_ocr_backend.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..7392e88 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,52 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..58fc79d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,32 @@ + + + + + + + + + + EditorConfig + + + GitHub 操作 + + + 正则表达式 + + + 版本控制 + + + + + 用户定义 + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2fe251c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..7367f54 --- /dev/null +++ b/main.py @@ -0,0 +1,115 @@ +from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException, UploadFile, File +from fastapi.responses import StreamingResponse, HTMLResponse +from pydantic import BaseModel +from typing import List +import base64 +import asyncio +import openai + +app = FastAPI() +with open("key", "r") as f: + key = f.read() +client = openai.OpenAI(api_key=key, + base_url="https://open.bigmodel.cn/api/paas/v4/" + ) + + +@app.get("/") +async def root(): + return {"message": "Hello World"} + + +@app.get("/hello/{name}") +async def say_hello(name: str): + return {"message": f"Hello {name}"} + + +# WebSocket连接管理器 +class ConnectionManager: + def __init__(self): + self.active_connections: List[WebSocket] = [] + + async def connect(self, websocket: WebSocket): + await websocket.accept() + self.active_connections.append(websocket) + + def disconnect(self, websocket: WebSocket): + self.active_connections.remove(websocket) + + async def send_personal_message(self, message: str, websocket: WebSocket): + await websocket.send_text(message) + + async def broadcast(self, message: str): + for connection in self.active_connections: + await connection.send_text(message) + + async def broadcast_json(self, data: dict): + for connection in self.active_connections: + await connection.send_json(data) + + +manager = ConnectionManager() + + +# WebSocket端点 +@app.websocket("/event") +async def event(websocket: WebSocket): + await manager.connect(websocket) + try: + while True: + # 这里可以添加逻辑处理来自客户端的消息 + data = await websocket.receive_text() + print(f"Received message from client: {data}") + except WebSocketDisconnect: + manager.disconnect(websocket) + + +# POST请求端点 +@app.post("/predict") +async def predict(file: UploadFile = File(...)): + # 读取图片文件并转换为base64编码 + image_data = await file.read() + image_base64 = base64.b64encode(image_data).decode('utf-8') + + # 构造请求给API + response = client.chat.completions.create( + model="glm-4v", + messages=[ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "请描述该图片", + }, + { + "type": "image_url", + "image_url": { + "url": f"data:image/jpeg;base64,{image_base64}" + }, + }, + ], + } + ], + stream=True + ) + # 广播图片数据 + await manager.broadcast_json({"type": "image", "content": image_base64}) + + # 流式返回结果 + async def stream_response(): + for chunk in response: + content = chunk.choices[0].delta.content + if content: + yield content + # 同时将内容广播给所有WebSocket连接的客户端 + # await manager.broadcast(content) + await manager.broadcast_json({"type": "text", "content": content}) + + return StreamingResponse(stream_response(), media_type="text/plain") + + +@app.get("/test", response_class=HTMLResponse) +async def test(): + with open("test.html", "r", encoding="utf-8") as f: + return f.read() diff --git a/test.html b/test.html new file mode 100644 index 0000000..933786d --- /dev/null +++ b/test.html @@ -0,0 +1,132 @@ + + + + + + WebSocket 文本和图片接收器 + + + + +
+
+ Received Image +
+ + + + + + + + 复制 + 清空 + + +
+ + + + + + diff --git a/test.py b/test.py new file mode 100644 index 0000000..218b2e8 --- /dev/null +++ b/test.py @@ -0,0 +1,36 @@ +import base64 +import openai + +with open("test.png", "rb") as f: + image_data = f.read() +image_base64 = base64.b64encode(image_data).decode('utf-8') +with open("key", "r") as f: + key = f.read() +client = openai.OpenAI(api_key=key, + base_url="https://open.bigmodel.cn/api/paas/v4/" + ) +# 构造请求给API +response = client.chat.completions.create( + model="glm-4v", + messages=[ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "请描述该图片", + }, + { + "type": "image_url", + "image_url": { + "url": f"data:image/jpeg;base64,{image_base64}" + }, + }, + ], + } + ], + stream=True +) + +for chunk in response: + print(chunk.choices[0].delta.content) \ No newline at end of file diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..6d7254f --- /dev/null +++ b/test/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# @Time : 2024/10/25 下午5:18 +# @Author : 河瞬 +# @FileName: __init__.py.py +# @Software: PyCharm +# @Github : diff --git a/test/clientTest.py b/test/clientTest.py new file mode 100644 index 0000000..148e541 --- /dev/null +++ b/test/clientTest.py @@ -0,0 +1,33 @@ +import unittest +import asyncio +import websockets +import requests +from time import sleep + +def send_post_request(): + url = "http://localhost:8000/example" + data = {"content": "Hello, WebSocket!"} + headers = {"Content-Type": "application/json"} + + response = requests.post(url, json=data, headers=headers) + print(f"Status Code: {response.status_code}") + print(f"Response: {response.json()}") +class MyTestCase(unittest.TestCase): + def test_something(self): + async def test_client(): + uri = "ws://localhost:8000/event" + async with websockets.connect(uri) as websocket: + while True: + try: + message = await websocket.recv() + self.assertGreater(len(message), 0) + except websockets.exceptions.ConnectionClosed: + raise Exception("Connection closed") + + asyncio.run(test_client()) + sleep(1) + send_post_request() + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test.py b/test/test.py new file mode 100644 index 0000000..d9dadc5 --- /dev/null +++ b/test/test.py @@ -0,0 +1,23 @@ +import asyncio +import websockets + +async def test_client(): + uri = "ws://localhost:8000/event" + async with websockets.connect(uri) as websocket: + print("Connected to server. Waiting for messages...") + try: + while True: + message = await websocket.recv() + print(f"Received message: {message}") + except websockets.exceptions.ConnectionClosed: + print("Connection closed by the server.") + except KeyboardInterrupt: + print("Keyboard interrupt received, closing connection...") + await websocket.close() + print("Connection closed.") + +if __name__ == "__main__": + try: + asyncio.run(test_client()) + except KeyboardInterrupt: + print("Program terminated by user.") diff --git a/test/test2.py b/test/test2.py new file mode 100644 index 0000000..91d512a --- /dev/null +++ b/test/test2.py @@ -0,0 +1,13 @@ +import requests + +def send_post_request(): + url = "http://localhost:8000/example" + data = {"content": "Hello, WebSocket!"} + headers = {"Content-Type": "application/json"} + + response = requests.post(url, json=data, headers=headers) + print(f"Status Code: {response.status_code}") + print(f"Response: {response.json()}") + +if __name__ == "__main__": + send_post_request() diff --git a/test_main.http b/test_main.http new file mode 100644 index 0000000..a2d81a9 --- /dev/null +++ b/test_main.http @@ -0,0 +1,11 @@ +# Test your FastAPI endpoints + +GET http://127.0.0.1:8000/ +Accept: application/json + +### + +GET http://127.0.0.1:8000/hello/User +Accept: application/json + +###