deepanything 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- deepanything/Server/Server.py +96 -59
- deepanything/__main__.py +3 -1
- deepanything/metadatas.py +1 -0
- {deepanything-0.1.4.dist-info → deepanything-0.1.6.dist-info}/METADATA +56 -3
- {deepanything-0.1.4.dist-info → deepanything-0.1.6.dist-info}/RECORD +9 -8
- {deepanything-0.1.4.dist-info → deepanything-0.1.6.dist-info}/LICENSE +0 -0
- {deepanything-0.1.4.dist-info → deepanything-0.1.6.dist-info}/WHEEL +0 -0
- {deepanything-0.1.4.dist-info → deepanything-0.1.6.dist-info}/entry_points.txt +0 -0
- {deepanything-0.1.4.dist-info → deepanything-0.1.6.dist-info}/top_level.txt +0 -0
deepanything/Server/Server.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from chunk import Chunk
|
1
2
|
from dataclasses import dataclass
|
2
3
|
import time
|
3
4
|
import uvicorn
|
@@ -5,9 +6,10 @@ from typing import Dict, List, Optional, Any
|
|
5
6
|
import json
|
6
7
|
|
7
8
|
from openai.types.model import Model as OpenaiModel
|
8
|
-
from fastapi import FastAPI,Depends, HTTPException, status,Header
|
9
|
-
from fastapi.responses import StreamingResponse
|
9
|
+
from fastapi import FastAPI,Depends, HTTPException, status,Header,Request
|
10
|
+
from fastapi.responses import StreamingResponse,Response
|
10
11
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
12
|
+
from uvicorn.config import LOGGING_CONFIG
|
11
13
|
|
12
14
|
from deepanything.DeepAnythingClient import chat_completion_stream_async, chat_completion_async
|
13
15
|
from deepanything.ResponseClient import AsyncOpenaiResponseClient,AsyncResponseClient
|
@@ -35,6 +37,7 @@ class DeepAnythingServer:
|
|
35
37
|
model_owner : str = "deepanything"
|
36
38
|
api_keys : List[str] = []
|
37
39
|
security = HTTPBearer()
|
40
|
+
log_config : Dict[str,Any] = LOGGING_CONFIG
|
38
41
|
|
39
42
|
def __init__(self, host:str = None, port:int = None, config : Any or str = None):
|
40
43
|
if config is not None:
|
@@ -52,7 +55,7 @@ class DeepAnythingServer:
|
|
52
55
|
self.app.add_api_route("/v1/chat/completions",self.chat_completions,methods=["POST"])
|
53
56
|
|
54
57
|
def run(self):
|
55
|
-
uvicorn.run(self.app,host=self.host,port=self.port,
|
58
|
+
uvicorn.run(self.app,host=self.host,port=self.port,log_config=self.log_config)
|
56
59
|
|
57
60
|
@staticmethod
|
58
61
|
def _extract_args(query : Types.ChatCompletionQuery) -> dict:
|
@@ -66,36 +69,18 @@ class DeepAnythingServer:
|
|
66
69
|
self.port = config_object.get("port",8000)
|
67
70
|
self.model_owner = config_object.get("model_owner","deepanything")
|
68
71
|
|
69
|
-
|
72
|
+
self._load_reason_clients(config_object)
|
73
|
+
self._load_response_clients(config_object)
|
74
|
+
self._load_models(config_object)
|
70
75
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
extract_args = client.get("extract_args",{})
|
76
|
-
|
77
|
-
if client["type"] == 'deepseek':
|
78
|
-
self.reason_clients[name] = AsyncDeepseekReasonClient(base_url, api_key, **extract_args)
|
79
|
-
elif client["type"] == 'openai':
|
80
|
-
self.reason_clients[name] = AsyncOpenaiReasonClient(base_url, api_key, **extract_args)
|
81
|
-
else:
|
82
|
-
raise Exception("unknown reason client type")
|
83
|
-
|
84
|
-
response_clients : List[Dict] = config_object.get("response_clients",[])
|
85
|
-
|
86
|
-
for client in response_clients:
|
87
|
-
name = client["name"]
|
88
|
-
base_url = client["base_url"]
|
89
|
-
api_key = client.get("api_key","")
|
90
|
-
extract_args = client.get("extract_args",{})
|
91
|
-
|
92
|
-
if client["type"] == 'openai':
|
93
|
-
self.response_clients[name] = AsyncOpenaiResponseClient(base_url,api_key,**extract_args)
|
94
|
-
else:
|
95
|
-
raise Exception("unknown response client type")
|
76
|
+
self.api_keys = config_object.get("api_keys",[])
|
77
|
+
self.log_config = config_object.get("log",LOGGING_CONFIG)
|
78
|
+
if self.log_config == {}:
|
79
|
+
self.log_config = LOGGING_CONFIG
|
96
80
|
|
97
|
-
models : List[Dict] = config_object.get("models",[])
|
98
81
|
|
82
|
+
def _load_models(self, config_object):
|
83
|
+
models: List[Dict] = config_object.get("models", [])
|
99
84
|
for _model in models:
|
100
85
|
name = _model["name"]
|
101
86
|
reason_client = _model["reason_client"]
|
@@ -103,20 +88,51 @@ class DeepAnythingServer:
|
|
103
88
|
response_client = _model["response_client"]
|
104
89
|
response_model = _model["response_model"]
|
105
90
|
created = _model.get("created", int(time.time()))
|
106
|
-
reason_prompt = _model.get("reason_prompt","<Think>{}</Think>")
|
91
|
+
reason_prompt = _model.get("reason_prompt", "<Think>{}</Think>")
|
92
|
+
|
93
|
+
if reason_client not in self.reason_clients:
|
94
|
+
raise ValueError(f"Reason client '{reason_model}' for '{name}' not found")
|
95
|
+
|
96
|
+
if response_client not in self.response_clients:
|
97
|
+
raise ValueError(f"Response client '{response_model}' for '{name}' not found")
|
107
98
|
|
108
99
|
self.models[name] = ModelInfo(
|
109
|
-
name
|
110
|
-
reason_client
|
111
|
-
reason_model
|
112
|
-
response_client
|
113
|
-
response_model
|
114
|
-
created
|
115
|
-
reason_prompt
|
100
|
+
name=name,
|
101
|
+
reason_client=reason_client,
|
102
|
+
reason_model=reason_model,
|
103
|
+
response_client=response_client,
|
104
|
+
response_model=response_model,
|
105
|
+
created=created,
|
106
|
+
reason_prompt=reason_prompt
|
116
107
|
)
|
117
108
|
|
118
|
-
|
109
|
+
def _load_response_clients(self, config_object):
|
110
|
+
response_clients: List[Dict] = config_object.get("response_clients", [])
|
111
|
+
for client in response_clients:
|
112
|
+
name = client["name"]
|
113
|
+
base_url = client["base_url"]
|
114
|
+
api_key = client.get("api_key", "")
|
115
|
+
extract_args = client.get("extract_args", {})
|
116
|
+
|
117
|
+
if client["type"] == 'openai':
|
118
|
+
self.response_clients[name] = AsyncOpenaiResponseClient(base_url, api_key, **extract_args)
|
119
|
+
else:
|
120
|
+
raise ValueError(f"Unsupported response client type '{client['type']}'")
|
119
121
|
|
122
|
+
def _load_reason_clients(self, config_object):
|
123
|
+
reason_clients: List[Dict] = config_object.get("reason_clients", [])
|
124
|
+
for client in reason_clients:
|
125
|
+
name = client["name"]
|
126
|
+
base_url = client["base_url"]
|
127
|
+
api_key = client.get("api_key", "")
|
128
|
+
extract_args = client.get("extract_args", {})
|
129
|
+
|
130
|
+
if client["type"] == 'deepseek':
|
131
|
+
self.reason_clients[name] = AsyncDeepseekReasonClient(base_url, api_key, **extract_args)
|
132
|
+
elif client["type"] == 'openai':
|
133
|
+
self.reason_clients[name] = AsyncOpenaiReasonClient(base_url, api_key, **extract_args)
|
134
|
+
else:
|
135
|
+
raise Exception("unknown reason client type")
|
120
136
|
|
121
137
|
def add_reason_client(self,name:str,client:AsyncReasonClient):
|
122
138
|
self.reason_clients[name] = client
|
@@ -126,7 +142,8 @@ class DeepAnythingServer:
|
|
126
142
|
|
127
143
|
def add_model(self,name:str,model:ModelInfo):
|
128
144
|
self.models[name] = model
|
129
|
-
|
145
|
+
|
146
|
+
def _verify_authorization(self, authorization:Optional[str]):
|
130
147
|
if not self.api_keys:
|
131
148
|
return
|
132
149
|
|
@@ -152,13 +169,29 @@ class DeepAnythingServer:
|
|
152
169
|
headers={"WWW-Authenticate": "Bearer"},
|
153
170
|
)
|
154
171
|
|
155
|
-
async def chat_completions(
|
156
|
-
|
172
|
+
async def chat_completions(
|
173
|
+
self,
|
174
|
+
request: Request, # 新增加Request参数
|
175
|
+
query: Types.ChatCompletionQuery,
|
176
|
+
authorization: Optional[str] = Header(None)
|
177
|
+
):
|
178
|
+
self._verify_authorization(authorization)
|
179
|
+
|
180
|
+
if query.model not in self.models:
|
181
|
+
raise HTTPException(
|
182
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
183
|
+
detail="Model not found",
|
184
|
+
)
|
185
|
+
|
157
186
|
model = self.models[query.model]
|
158
|
-
|
187
|
+
|
188
|
+
async def _sse_warp(it: AsyncStream, req: Request):
|
159
189
|
async for chunk in it:
|
160
|
-
|
161
|
-
|
190
|
+
if await req.is_disconnected():
|
191
|
+
await it.close()
|
192
|
+
break
|
193
|
+
yield f"data: {chunk.model_dump_json(indent=None)}\n\n".encode("utf-8")
|
194
|
+
yield "data: [DONE]".encode('utf-8')
|
162
195
|
|
163
196
|
args = DeepAnythingServer._extract_args(query)
|
164
197
|
|
@@ -168,7 +201,7 @@ class DeepAnythingServer:
|
|
168
201
|
args.pop("max_tokens")
|
169
202
|
|
170
203
|
if query.stream:
|
171
|
-
res =
|
204
|
+
res = _sse_warp(
|
172
205
|
await chat_completion_stream_async(
|
173
206
|
messages=query.messages,
|
174
207
|
reason_client=self.reason_clients[model.reason_client],
|
@@ -180,26 +213,30 @@ class DeepAnythingServer:
|
|
180
213
|
response_args=args,
|
181
214
|
reason_args=args,
|
182
215
|
max_tokens=max_tokens
|
183
|
-
)
|
216
|
+
),
|
217
|
+
request
|
184
218
|
)
|
185
219
|
return StreamingResponse(
|
186
220
|
res,
|
187
|
-
media_type="text/event-stream"
|
221
|
+
media_type="text/event-stream",
|
188
222
|
)
|
189
223
|
else:
|
190
224
|
res = await chat_completion_async(
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
225
|
+
messages=query.messages,
|
226
|
+
reason_client=self.reason_clients[model.reason_client],
|
227
|
+
reason_model=model.reason_model,
|
228
|
+
response_client=self.response_clients[model.response_client],
|
229
|
+
response_model=model.response_model,
|
230
|
+
show_model=model.name,
|
231
|
+
reason_prompt=model.reason_prompt,
|
232
|
+
response_args=args,
|
233
|
+
reason_args=args,
|
234
|
+
max_tokens=max_tokens
|
235
|
+
)
|
236
|
+
return Response(
|
237
|
+
content=res.model_dump_json(indent=None),
|
238
|
+
media_type="application/json"
|
201
239
|
)
|
202
|
-
return res.model_dump_json()
|
203
240
|
|
204
241
|
def get_models(self) -> Types.ModelsListResponse:
|
205
242
|
return Types.ModelsListResponse(
|
deepanything/__main__.py
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
from deepanything.Server.Server import DeepAnythingServer
|
2
2
|
import argparse
|
3
3
|
import json
|
4
|
+
from .metadatas import VERSION
|
4
5
|
def main():
|
5
|
-
parser = argparse.ArgumentParser(prog="deepanything",description="Run a DeepAnything Server.")
|
6
|
+
parser = argparse.ArgumentParser(prog=f"deepanything {VERSION}",description="Run a DeepAnything Server.")
|
6
7
|
parser.add_argument('--host', type=str, required=False, help='Specific the host to listen.If specified,the host will be overwritten by this.')
|
7
8
|
parser.add_argument('--port', type=int, required=False, help='Specific the port to listen.If specified,the port will be overwritten by this.')
|
8
9
|
parser.add_argument('--config', type=str, required=True, help='Specific the confi path.')
|
10
|
+
parser.add_argument('--version', action='version', version=f'%(prog)s {VERSION}')
|
9
11
|
|
10
12
|
args = parser.parse_args()
|
11
13
|
|
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = "v0.1.6"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: deepanything
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.6
|
4
4
|
Summary: DeepAnything is a project that provides DeepSeek R1's deep thinking capabilities for various large language models (LLMs).
|
5
5
|
Author: Junity
|
6
6
|
Author-email: 1727636624@qq.com
|
@@ -159,6 +159,7 @@ More example can be find in [examples](examples).
|
|
159
159
|
Below is an example of a configuration file:
|
160
160
|
|
161
161
|
```json
|
162
|
+
// Using R1 with Qwen-Max-Latest
|
162
163
|
{
|
163
164
|
"host" : "0.0.0.0",
|
164
165
|
"port" : 8080,
|
@@ -187,9 +188,41 @@ Below is an example of a configuration file:
|
|
187
188
|
"response_model" : "qwen-max-latest"
|
188
189
|
}
|
189
190
|
],
|
190
|
-
"api_keys": [
|
191
|
+
"api_keys" : [
|
191
192
|
"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
192
|
-
]
|
193
|
+
],
|
194
|
+
"log": {
|
195
|
+
"version": 1,
|
196
|
+
"disable_existing_loggers": false,
|
197
|
+
"formatters": {
|
198
|
+
"default": {
|
199
|
+
"()": "uvicorn.logging.DefaultFormatter",
|
200
|
+
"fmt": "%(levelprefix)s %(message)s",
|
201
|
+
"use_colors": null
|
202
|
+
},
|
203
|
+
"access": {
|
204
|
+
"()": "uvicorn.logging.AccessFormatter",
|
205
|
+
"fmt": "%(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s"
|
206
|
+
}
|
207
|
+
},
|
208
|
+
"handlers": {
|
209
|
+
"default": {
|
210
|
+
"formatter": "default",
|
211
|
+
"class": "logging.StreamHandler",
|
212
|
+
"stream": "ext://sys.stderr"
|
213
|
+
},
|
214
|
+
"access": {
|
215
|
+
"formatter": "access",
|
216
|
+
"class": "logging.StreamHandler",
|
217
|
+
"stream": "ext://sys.stdout"
|
218
|
+
}
|
219
|
+
},
|
220
|
+
"loggers": {
|
221
|
+
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": false},
|
222
|
+
"uvicorn.error": {"level": "INFO"},
|
223
|
+
"uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": false}
|
224
|
+
}
|
225
|
+
}
|
193
226
|
}
|
194
227
|
```
|
195
228
|
|
@@ -198,6 +231,26 @@ Below is an example of a configuration file:
|
|
198
231
|
- reason_clients: Configuration for thinking models, currently supports deepseek and openai types. When the type is openai, deepanything directly uses the model's output as the thinking content, and it is recommended to use qwq-32b in this case.
|
199
232
|
- response_clients: Configuration for response models, currently only supports the openai type.
|
200
233
|
- api_keys: API keys for user authentication. When left blank or an empty list, the server does not use API keys for authentication.
|
234
|
+
- log: Log configuration. If this item is not filled in, the default logging configuration of uvicorn will be used. For details, please refer to [uvicorn logging configuration](https://www.uvicorn.org/settings/#logging).
|
235
|
+
|
236
|
+
## Deploying with Docker
|
237
|
+
### 1. Pull the Image
|
238
|
+
```bash
|
239
|
+
docker pull junity233/deepanything:latest
|
240
|
+
```
|
241
|
+
|
242
|
+
### 2. Create config.json
|
243
|
+
First, create a folder in your desired directory, and then create a file named `config.json` inside it. This folder will be mounted into the container:
|
244
|
+
```bash
|
245
|
+
mkdir deepanything-data # You can replace this with another name
|
246
|
+
vim deepanything-data/config.json # Edit the configuration file, you can refer to examples/config.json
|
247
|
+
```
|
248
|
+
|
249
|
+
### 3. Run the Container
|
250
|
+
```bash
|
251
|
+
# Remember to modify the port mapping
|
252
|
+
docker run -v ./deepanything-data:/data -p 8080:8080 junity233/deepanything:latest
|
253
|
+
```
|
201
254
|
|
202
255
|
## License
|
203
256
|
|
@@ -4,13 +4,14 @@ deepanything/ResponseClient.py,sha256=NbXjlU_0qTKBNjZy8B9J9emuABQYvx3NZsWuja9OnM
|
|
4
4
|
deepanything/Stream.py,sha256=8ESR8ttjyPZ-uXPDENsVWUzaL34_GT2OZBJ0PWu7vsA,1578
|
5
5
|
deepanything/Utility.py,sha256=TFH-4NS-gQpzzEb1Aba7WpDEqBqNRF1STWFzfRqQLcg,6645
|
6
6
|
deepanything/__init__.py,sha256=_2RolcKcpxmW0dmtiQpXlvgxe5dvqx90Yg_Q_oVLVZQ,175
|
7
|
-
deepanything/__main__.py,sha256=
|
8
|
-
deepanything/
|
7
|
+
deepanything/__main__.py,sha256=N40zRebnTUmVd9a0wcK_I0au7Lvl4axxKX6zJGDdXq0,1066
|
8
|
+
deepanything/metadatas.py,sha256=WspkzXRul9GiZA9N8kBo-wnZEexn6N3Y_ykPEaT8dL8,18
|
9
|
+
deepanything/Server/Server.py,sha256=HIM-MHuRG98jv8MTeGK9So-xd8OiTA9R74uvKbWrXyk,9847
|
9
10
|
deepanything/Server/Types.py,sha256=b7aMaRBgODEKdyYe0FeraUfrygJuye3b5lfQTOWASXA,650
|
10
11
|
deepanything/Server/__init__.py,sha256=eIpn6NbNvEg4ST8CuuIuzPT3m_fTlmPC3sikPoPFsYo,92
|
11
|
-
deepanything-0.1.
|
12
|
-
deepanything-0.1.
|
13
|
-
deepanything-0.1.
|
14
|
-
deepanything-0.1.
|
15
|
-
deepanything-0.1.
|
16
|
-
deepanything-0.1.
|
12
|
+
deepanything-0.1.6.dist-info/LICENSE,sha256=JWYd2E-mcNcSYjT5nk4ayM5kkkDq6ZlOxVcYsyqCIwU,1059
|
13
|
+
deepanything-0.1.6.dist-info/METADATA,sha256=-h3eS_CkiwY27ju-QxH2_40IJMBszckjbjmhBTqW0Ig,7851
|
14
|
+
deepanything-0.1.6.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
15
|
+
deepanything-0.1.6.dist-info/entry_points.txt,sha256=UT4gNGx6dJsKBjZIl3VkMekh385O5WMbMidAAla6UB4,60
|
16
|
+
deepanything-0.1.6.dist-info/top_level.txt,sha256=wGeRb__4jEJTclCUl0cxhgubD_Bq-QT38VIH6C4KpzY,13
|
17
|
+
deepanything-0.1.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|