dan92 commited on
Commit
28fcd47
·
verified ·
1 Parent(s): 7149ff5

Delete app

Browse files
app/api/auth.py DELETED
@@ -1,5 +0,0 @@
1
- import os
2
- from fastapi.security import HTTPBearer
3
-
4
- security = HTTPBearer()
5
- APP_SECRET = os.getenv("APP_SECRET", "sk-zhoudan20241029")
 
 
 
 
 
 
app/api/config.py DELETED
@@ -1,73 +0,0 @@
1
- import os
2
- from pydantic_settings import BaseSettings
3
- from dotenv import load_dotenv
4
- from typing import Dict, List
5
-
6
- load_dotenv()
7
-
8
- class Settings(BaseSettings):
9
- # Server settings
10
- HOST: str = os.getenv("HOST", "0.0.0.0")
11
- PORT: int = int(os.getenv("PORT", "8001"))
12
- DEBUG: bool = os.getenv("DEBUG", "False").lower() == "true"
13
- WORKERS: int = int(os.getenv("WORKERS", "1"))
14
- LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
15
-
16
- # API settings
17
- BASE_URL: str = "http://216.24.57.252"
18
- APP_SECRET: str = os.getenv("APP_SECRET", "")
19
- REQUEST_TIMEOUT: int = int(os.getenv("REQUEST_TIMEOUT", "30"))
20
-
21
- # Headers
22
- HEADERS: Dict[str, str] = {
23
- 'accept': '*/*',
24
- 'accept-language': 'zh-CN,zh;q=0.9',
25
- 'content-type': 'application/json',
26
- 'origin': 'http://216.24.57.252',
27
- 'referer': 'http://216.24.57.252/',
28
- 'host': '216.24.57.252',
29
- 'connection': 'keep-alive',
30
- 'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
31
- 'sec-ch-ua-mobile': '?0',
32
- 'sec-ch-ua-platform': '"Windows"',
33
- 'sec-fetch-dest': 'empty',
34
- 'sec-fetch-mode': 'cors',
35
- 'sec-fetch-site': 'same-origin',
36
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
37
- }
38
-
39
- ALLOWED_MODELS: List[Dict[str, str]] = [
40
- {"id": "gpt-4o", "name": "gpt-4o"},
41
- {"id": "gemini-1.5-pro", "name": "gemini-pro"},
42
- {"id": "claude-3-5-sonnet", "name": "claude-sonnet-3.5"},
43
- {"id": "blackboxai", "name": "blackboxai"},
44
- {"id": "blackboxai-pro", "name": "blackboxai-pro"},
45
- {"id": "blackboxai-search", "name": "blackboxai-search"},
46
- {"id": "meta-llama/Llama-3.3-70B-Instruct-Turbo", "name": "meta-llama/Llama-3.3-70B-Instruct-Turbo"},
47
- {"id": "meta-llama/Meta-Llama-3.1-405B-Instruct-Lite-Pro", "name": "meta-llama/Meta-Llama-3.1-405B-Instruct-Lite-Pro"},
48
- {"id": "Qwen/QwQ-32B-Preview", "name": "Qwen/QwQ-32B-Preview"},
49
- ]
50
-
51
- MODEL_MAPPING: Dict[str, str] = {
52
- "gpt-4o": "gpt-4o",
53
- "gemini-1.5-pro": "gemini-pro",
54
- "claude-3-5-sonnet": "claude-sonnet-3.5",
55
- "blackboxai": "blackboxai",
56
- "blackboxai-pro": "blackboxai-pro",
57
- "blackboxai-search": "blackboxai-search",
58
- "meta-llama/Llama-3.3-70B-Instruct-Turbo": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
59
- "meta-llama/Meta-Llama-3.1-405B-Instruct-Lite-Pro": "meta-llama/Meta-Llama-3.1-405B-Instruct-Lite-Pro",
60
- "Qwen/QwQ-32B-Preview": "Qwen/QwQ-32B-Preview",
61
- }
62
-
63
- class Config:
64
- env_file = ".env"
65
- case_sensitive = True
66
-
67
- _settings = None
68
-
69
- def get_settings() -> Settings:
70
- global _settings
71
- if _settings is None:
72
- _settings = Settings()
73
- return _settings
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/logger.py DELETED
@@ -1,24 +0,0 @@
1
- import logging
2
- from logging.handlers import RotatingFileHandler
3
- import os
4
-
5
- def setup_logger(name):
6
- logger = logging.getLogger(name)
7
-
8
- if not logger.handlers:
9
- logger.setLevel(logging.INFO)
10
-
11
- # 创建控制台处理器
12
- console_handler = logging.StreamHandler()
13
- console_handler.setLevel(logging.INFO)
14
-
15
- # 设置日志格式
16
- formatter = logging.Formatter(
17
- '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
18
- )
19
- console_handler.setFormatter(formatter)
20
-
21
- # 添加处理器到logger
22
- logger.addHandler(console_handler)
23
-
24
- return logger
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/models.py DELETED
@@ -1,14 +0,0 @@
1
- from typing import List, Optional, Union
2
- from pydantic import BaseModel, Field
3
-
4
- class Message(BaseModel):
5
- role: str
6
- content: Union[str, List]
7
-
8
- class ChatRequest(BaseModel):
9
- model: str
10
- messages: List[Message]
11
- stream: bool = False
12
- temperature: float = Field(default=0.7, ge=0, le=2)
13
- top_p: float = Field(default=0.95, ge=0, le=1)
14
- max_tokens: int = Field(default=8192, ge=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/routes.py DELETED
@@ -1,24 +0,0 @@
1
- from fastapi import APIRouter, Depends
2
- from fastapi.responses import StreamingResponse
3
- from api.models import ChatRequest
4
- from api.utils import process_streaming_response, process_non_streaming_response
5
- from api.logger import setup_logger
6
-
7
- logger = setup_logger(__name__)
8
- router = APIRouter()
9
-
10
- @router.post("/chat/completions")
11
- async def chat_completions(request: ChatRequest):
12
- """
13
- 处理聊天完成请求
14
- """
15
- logger.info("Entering chat_completions route")
16
- logger.info(f"Received request: {request}")
17
-
18
- if request.stream:
19
- return StreamingResponse(
20
- process_streaming_response(request),
21
- media_type="text/event-stream"
22
- )
23
- else:
24
- return await process_non_streaming_response(request)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/utils.py DELETED
@@ -1,187 +0,0 @@
1
- from datetime import datetime
2
- from http.client import HTTPException
3
- import json
4
- from typing import Any, Dict, Optional
5
- import uuid
6
-
7
- import httpx
8
- from api import validate
9
- from api.auth import APP_SECRET
10
- from api.config import get_settings
11
- from fastapi import Depends, security
12
- from fastapi.security import HTTPAuthorizationCredentials
13
-
14
- from api.models import ChatRequest
15
-
16
- from api.logger import setup_logger
17
-
18
- logger = setup_logger(__name__)
19
-
20
- settings = get_settings()
21
- BASE_URL = settings.BASE_URL
22
- MODEL_MAPPING = settings.MODEL_MAPPING
23
-
24
- def create_chat_completion_data(
25
- content: str, model: str, timestamp: int, finish_reason: Optional[str] = None
26
- ) -> Dict[str, Any]:
27
- return {
28
- "id": f"chatcmpl-{uuid.uuid4()}",
29
- "object": "chat.completion.chunk",
30
- "created": timestamp,
31
- "model": model,
32
- "choices": [
33
- {
34
- "index": 0,
35
- "delta": {"content": content, "role": "assistant"},
36
- "finish_reason": finish_reason,
37
- }
38
- ],
39
- "usage": None,
40
- }
41
-
42
- def verify_app_secret(credentials: HTTPAuthorizationCredentials = Depends(security)):
43
- if credentials.credentials != APP_SECRET:
44
- raise HTTPException(status_code=403, detail="Invalid APP_SECRET")
45
- return credentials.credentials
46
-
47
- def message_to_dict(message):
48
- if isinstance(message.content, str):
49
- return {"role": message.role, "content": message.content}
50
- elif isinstance(message.content, list) and len(message.content) == 2:
51
- return {
52
- "role": message.role,
53
- "content": message.content[0]["text"],
54
- "data": {
55
- "imageBase64": message.content[1]["image_url"]["url"],
56
- "fileText": "",
57
- "title": "snapshoot",
58
- },
59
- }
60
- else:
61
- return {"role": message.role, "content": message.content}
62
-
63
- async def process_streaming_response(request: ChatRequest):
64
- json_data = {
65
- "messages": [message_to_dict(msg) for msg in request.messages],
66
- "previewToken": None,
67
- "userId": None,
68
- "codeModelMode": True,
69
- "agentMode": {},
70
- "trendingAgentMode": {},
71
- "isMicMode": False,
72
- "userSystemPrompt": None,
73
- "maxTokens": request.max_tokens,
74
- "playgroundTopP": request.top_p,
75
- "playgroundTemperature": request.temperature,
76
- "isChromeExt": False,
77
- "githubToken": None,
78
- "clickedAnswer2": False,
79
- "clickedAnswer3": False,
80
- "clickedForceWebSearch": False,
81
- "visitFromDelta": False,
82
- "mobileClient": False,
83
- "userSelectedModel": settings.MODEL_MAPPING.get(request.model),
84
- "validated": validate.getVid(),
85
- "webSearchModePrompt": True if request.model.endswith("-search") else False
86
- }
87
-
88
- try:
89
- async with httpx.AsyncClient(verify=False) as client:
90
- async with client.stream(
91
- method="POST",
92
- url=f"{settings.BASE_URL}/api/chat",
93
- headers=settings.HEADERS,
94
- json=json_data
95
- ) as response:
96
- response.raise_for_status()
97
- timestamp = int(datetime.now().timestamp())
98
- search_results = None
99
-
100
- async for line in response.aiter_lines():
101
- if not line:
102
- continue
103
-
104
- if line.startswith("$~~~$"): # 处理搜索结果
105
- try:
106
- json_str = line[5:-5] # 提取中间的JSON字符串
107
- results = json.loads(json_str)
108
- search_results = results # 保存搜索结果
109
- continue
110
- except json.JSONDecodeError:
111
- logger.error("Failed to parse search results")
112
- continue
113
-
114
- if line == "**":
115
- continue
116
- content = line + "\n"
117
- print(content)
118
- if "http://216.24.57.252" in content:
119
- validate.getVid(True)
120
- content = "vid已刷新,重新对话即可\n"
121
- yield f"data: {json.dumps(create_chat_completion_data(content, request.model, timestamp))}\n\n"
122
- break
123
- if content.startswith("$@$v=undefined-rv1$@$"):
124
- yield f"data: {json.dumps(create_chat_completion_data(content[21:], request.model, timestamp))}\n\n"
125
- else:
126
- yield f"data: {json.dumps(create_chat_completion_data(content, request.model, timestamp))}\n\n"
127
-
128
- if search_results: # 在结束前输出引用来源
129
- sources = "\n\n**引用来源**\n" + "\n".join([f"- [{r['title']}]({r['link']})" for r in search_results])
130
- yield f"data: {json.dumps(create_chat_completion_data(sources, request.model, timestamp))}\n\n"
131
- except httpx.HTTPStatusError as e:
132
- logger.error(f"HTTP error occurred: {str(e)}")
133
- raise HTTPException(status_code=e.response.status_code, detail=str(e))
134
- except Exception as e:
135
- logger.error(f"Error occurred: {str(e)}")
136
- raise HTTPException(status_code=500, detail=str(e))
137
-
138
- async def process_non_streaming_response(request: ChatRequest):
139
- json_data = {
140
- "messages": [message_to_dict(msg) for msg in request.messages],
141
- "previewToken": None,
142
- "userId": None,
143
- "codeModelMode": True,
144
- "agentMode": {},
145
- "trendingAgentMode": {},
146
- "isMicMode": False,
147
- "userSystemPrompt": None,
148
- "maxTokens": request.max_tokens,
149
- "playgroundTopP": request.top_p,
150
- "playgroundTemperature": request.temperature,
151
- "isChromeExt": False,
152
- "githubToken": None,
153
- "clickedAnswer2": False,
154
- "clickedAnswer3": False,
155
- "clickedForceWebSearch": False,
156
- "visitFromDelta": False,
157
- "mobileClient": False,
158
- "userSelectedModel": MODEL_MAPPING.get(request.model),
159
- "validated": validate.getVid(),
160
- "webSearchModePrompt": True if request.model.endswith("-search") else False
161
- }
162
- full_response = ""
163
- async with httpx.AsyncClient(verify=False) as client:
164
- async with client.stream(
165
- method="POST", url=f"{BASE_URL}/api/chat", headers=settings.HEADERS, json=json_data
166
- ) as response:
167
- async for chunk in response.aiter_text():
168
- full_response += chunk
169
- if "http://216.24.57.252" in full_response:
170
- validate.getVid(True)
171
- full_response = "vid已刷新,重新对话即可"
172
- if full_response.startswith("$@$v=undefined-rv1$@$"):
173
- full_response = full_response[21:]
174
- return {
175
- "id": f"chatcmpl-{uuid.uuid4()}",
176
- "object": "chat.completion",
177
- "created": int(datetime.now().timestamp()),
178
- "model": request.model,
179
- "choices": [
180
- {
181
- "index": 0,
182
- "message": {"role": "assistant", "content": full_response},
183
- "finish_reason": "stop",
184
- }
185
- ],
186
- "usage": None,
187
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/api/validate.py DELETED
@@ -1,26 +0,0 @@
1
- import time
2
- import random
3
- import string
4
-
5
- _vid = None
6
- _last_update = 0
7
-
8
- def generate_vid():
9
- """生成随机vid"""
10
- length = 32
11
- characters = string.ascii_letters + string.digits
12
- return ''.join(random.choice(characters) for _ in range(length))
13
-
14
- def getVid(force_refresh=False):
15
- """获取或刷新vid"""
16
- global _vid, _last_update
17
- current_time = time.time()
18
-
19
- # 如果强制刷新或者vid不存在或者已过期(1小时)
20
- if force_refresh or _vid is None or (current_time - _last_update) > 3600:
21
- _vid = generate_vid()
22
- _last_update = current_time
23
-
24
- return _vid
25
-
26
- base_url = "http://216.24.57.252"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/main.py DELETED
@@ -1,17 +0,0 @@
1
- from fastapi import FastAPI
2
- from fastapi.middleware.cors import CORSMiddleware
3
- from api.routes import router
4
-
5
- app = FastAPI()
6
-
7
- # 配置CORS
8
- app.add_middleware(
9
- CORSMiddleware,
10
- allow_origins=["*"],
11
- allow_credentials=True,
12
- allow_methods=["*"],
13
- allow_headers=["*"],
14
- )
15
-
16
- # 添加路由
17
- app.include_router(router, prefix="/api/v1")