deepwrap 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepwrap/__init__.py +3 -0
- deepwrap/__main__.py +437 -0
- deepwrap/api/__init__.py +7 -0
- deepwrap/api/base.py +31 -0
- deepwrap/api/chat_session.py +303 -0
- deepwrap/api/chats.py +101 -0
- deepwrap/api/pow.py +92 -0
- deepwrap/client.py +136 -0
- deepwrap/config.py +74 -0
- deepwrap/core/__init__.py +4 -0
- deepwrap/core/auth.py +123 -0
- deepwrap/core/session_manager.py +55 -0
- deepwrap/interfaces/__init__.py +1 -0
- deepwrap/interfaces/api.py +373 -0
- deepwrap/interfaces/cli.py +966 -0
- deepwrap/modules/__init__.py +3 -0
- deepwrap/modules/pow_asm.py +305 -0
- deepwrap/py.typed +0 -0
- deepwrap/utils/bearer_token_extractor.py +56 -0
- deepwrap/utils/browser_finder.py +172 -0
- deepwrap/utils/browser_process.py +72 -0
- deepwrap/utils/cdp_client.py +82 -0
- deepwrap/utils/config_store.py +101 -0
- deepwrap/utils/dev_tools_http.py +90 -0
- deepwrap/utils/port_finder.py +17 -0
- deepwrap-0.1.0.dist-info/METADATA +860 -0
- deepwrap-0.1.0.dist-info/RECORD +31 -0
- deepwrap-0.1.0.dist-info/WHEEL +5 -0
- deepwrap-0.1.0.dist-info/entry_points.txt +2 -0
- deepwrap-0.1.0.dist-info/licenses/LICENSE +21 -0
- deepwrap-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepwrap
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK, CLI, and local FastAPI wrapper for DeepSeek Chat.
|
|
5
|
+
Author-email: Nika Kudukhashvili <nikakuduxashvili0@gmail.com>
|
|
6
|
+
Maintainer-email: Nika Kudukhashvili <nikakuduxashvili0@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/Kuduxaaa/deepwrap
|
|
9
|
+
Project-URL: Repository, https://github.com/Kuduxaaa/deepwrap
|
|
10
|
+
Project-URL: Issues, https://github.com/Kuduxaaa/deepwrap/issues
|
|
11
|
+
Project-URL: Documentation, https://github.com/Kuduxaaa/deepwrap#readme
|
|
12
|
+
Keywords: deepseek,chat,ai,sdk,cli,fastapi,wrapper,streaming,llm
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Framework :: FastAPI
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
26
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Classifier: Typing :: Typed
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: requests>=2.31.0
|
|
33
|
+
Requires-Dist: websocket-client>=1.7.0
|
|
34
|
+
Requires-Dist: wasmtime>=20.0.0
|
|
35
|
+
Requires-Dist: click>=8.1.0
|
|
36
|
+
Requires-Dist: rich>=13.0.0
|
|
37
|
+
Requires-Dist: prompt_toolkit>=3.0.0
|
|
38
|
+
Requires-Dist: fastapi>=0.110.0
|
|
39
|
+
Requires-Dist: uvicorn[standard]>=0.27.0
|
|
40
|
+
Requires-Dist: pydantic>=2.0.0
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
46
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
47
|
+
Requires-Dist: mypy>=1.8.0; extra == "dev"
|
|
48
|
+
Provides-Extra: test
|
|
49
|
+
Requires-Dist: pytest>=8.0.0; extra == "test"
|
|
50
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "test"
|
|
51
|
+
Provides-Extra: lint
|
|
52
|
+
Requires-Dist: ruff>=0.5.0; extra == "lint"
|
|
53
|
+
Requires-Dist: mypy>=1.8.0; extra == "lint"
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
|
|
56
|
+
# DeepWrap
|
|
57
|
+
|
|
58
|
+
**DeepWrap** is a lightweight Python SDK, CLI, and local HTTP API wrapper for interacting with DeepSeek Chat through a clean developer-friendly interface.
|
|
59
|
+
|
|
60
|
+
It provides:
|
|
61
|
+
|
|
62
|
+
- A simple Python client
|
|
63
|
+
- Streaming and non-streaming chat responses
|
|
64
|
+
- Structured streaming with separated thinking and response chunks
|
|
65
|
+
- Browser-based authentication
|
|
66
|
+
- Local token storage
|
|
67
|
+
- Interactive terminal UI
|
|
68
|
+
- FastAPI server mode
|
|
69
|
+
- Session-based chat support
|
|
70
|
+
- Proof-of-work handling internally
|
|
71
|
+
|
|
72
|
+
> Repository: [https://github.com/Kuduxaaa/deepwrap](https://github.com/Kuduxaaa/deepwrap)
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install deepwrap
|
|
80
|
+
````
|
|
81
|
+
|
|
82
|
+
Or install directly from GitHub:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install git+https://github.com/Kuduxaaa/deepwrap.git
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For local development:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git clone https://github.com/Kuduxaaa/deepwrap.git
|
|
92
|
+
cd deepwrap
|
|
93
|
+
pip install -e .
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
deepwrap
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
or
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from deepwrap import Client
|
|
108
|
+
|
|
109
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
110
|
+
chat = client.chats.create_session(model="expert")
|
|
111
|
+
|
|
112
|
+
response = chat.respond(
|
|
113
|
+
"Hello, introduce yourself in one sentence.",
|
|
114
|
+
stream=False,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
print(response)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Authentication
|
|
123
|
+
|
|
124
|
+
DeepWrap uses a Bearer token.
|
|
125
|
+
|
|
126
|
+
You can provide the token directly:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from deepwrap import Client
|
|
130
|
+
|
|
131
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Or use environment variables:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
export DEEPWRAP_API_KEY="YOUR_BEARER_TOKEN"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
DeepWrap also supports:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
export DEEPSEEK_API_KEY="YOUR_BEARER_TOKEN"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Then:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from deepwrap import Client
|
|
150
|
+
|
|
151
|
+
client = Client()
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## CLI Authentication
|
|
157
|
+
|
|
158
|
+
Authenticate using browser login:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
deepwrap auth
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Manually save a token:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
deepwrap auth --manual
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Save a token directly:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
deepwrap auth --token "YOUR_BEARER_TOKEN"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Show current config status:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
deepwrap config
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Remove saved token:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
deepwrap logout
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Python SDK Usage
|
|
191
|
+
|
|
192
|
+
### Basic Non-Streaming Chat
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from deepwrap import Client
|
|
196
|
+
|
|
197
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
198
|
+
chat = client.chats.create_session(model="expert")
|
|
199
|
+
|
|
200
|
+
response = chat.respond(
|
|
201
|
+
"Explain quantum computing in one short sentence.",
|
|
202
|
+
thinking=True,
|
|
203
|
+
search=True,
|
|
204
|
+
stream=False,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
print(response)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### Streaming Chat
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from deepwrap import Client
|
|
216
|
+
|
|
217
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
218
|
+
chat = client.chats.create_session(model="expert")
|
|
219
|
+
|
|
220
|
+
for chunk in chat.respond(
|
|
221
|
+
"Write a short explanation of black holes.",
|
|
222
|
+
thinking=True,
|
|
223
|
+
search=True,
|
|
224
|
+
stream=True,
|
|
225
|
+
):
|
|
226
|
+
print(chunk, end="", flush=True)
|
|
227
|
+
|
|
228
|
+
print()
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Multi-Turn Chat
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
from deepwrap import Client
|
|
237
|
+
|
|
238
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
239
|
+
chat = client.chats.create_session(model="expert")
|
|
240
|
+
|
|
241
|
+
print(chat.respond("My name is Nika.", stream=False))
|
|
242
|
+
print(chat.respond("What is my name?", stream=False))
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The `ChatSession` keeps track of the latest message ID internally, so follow-up messages stay inside the same conversation.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### Structured Streaming
|
|
250
|
+
|
|
251
|
+
If you want to separate thinking chunks from final response chunks:
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from deepwrap import Client
|
|
255
|
+
|
|
256
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
257
|
+
chat = client.chats.create_session(model="expert")
|
|
258
|
+
|
|
259
|
+
for kind, chunk in chat.respond_structured(
|
|
260
|
+
"Explain how neural networks learn.",
|
|
261
|
+
thinking=True,
|
|
262
|
+
search=True,
|
|
263
|
+
):
|
|
264
|
+
if kind == "think":
|
|
265
|
+
print(f"[THINK] {chunk}", end="", flush=True)
|
|
266
|
+
|
|
267
|
+
elif kind == "response":
|
|
268
|
+
print(f"[RESPONSE] {chunk}", end="", flush=True)
|
|
269
|
+
|
|
270
|
+
print()
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Possible chunk kinds:
|
|
274
|
+
|
|
275
|
+
```text
|
|
276
|
+
think
|
|
277
|
+
response
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Supported Models
|
|
283
|
+
|
|
284
|
+
DeepWrap currently supports:
|
|
285
|
+
|
|
286
|
+
```text
|
|
287
|
+
expert
|
|
288
|
+
default
|
|
289
|
+
vision
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Example:
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
chat = client.chats.create_session(model="default")
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## CLI Usage
|
|
301
|
+
|
|
302
|
+
Run the interactive terminal interface:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
deepwrap
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Send a single message from the terminal:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
deepwrap chat "Explain recursion in one sentence."
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Use a specific model:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
deepwrap chat "Hello" --model expert
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Disable thinking output:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
deepwrap chat "Give me three facts about Tbilisi." --no-thinking
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Disable search:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
deepwrap chat "Explain Python decorators." --no-search
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Stream output:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
deepwrap chat "Write a short story about AI." --stream
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Use a direct token:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
deepwrap chat "Hello" --token "YOUR_BEARER_TOKEN"
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Interactive CLI Commands
|
|
347
|
+
|
|
348
|
+
Inside the interactive terminal UI:
|
|
349
|
+
|
|
350
|
+
```text
|
|
351
|
+
/help Show help
|
|
352
|
+
/exit Exit the CLI
|
|
353
|
+
/quit Exit the CLI
|
|
354
|
+
/clear Clear the terminal
|
|
355
|
+
/new Start a fresh chat session
|
|
356
|
+
/model <name> Switch model: expert, default, vision
|
|
357
|
+
/token Set token interactively
|
|
358
|
+
/token "<token>" Set token inline
|
|
359
|
+
/thinking on|off Show or hide thinking blocks
|
|
360
|
+
/search on|off Enable or disable search
|
|
361
|
+
/save Save current settings
|
|
362
|
+
/status Show current session status
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Example:
|
|
366
|
+
|
|
367
|
+
```text
|
|
368
|
+
/model expert
|
|
369
|
+
/thinking off
|
|
370
|
+
/search on
|
|
371
|
+
/new
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Local FastAPI Server
|
|
377
|
+
|
|
378
|
+
DeepWrap can run as a local HTTP API.
|
|
379
|
+
|
|
380
|
+
Start the server:
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
deepwrap api
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Specify host and port:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
deepwrap api --host 127.0.0.1 --port 7070
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Enable reload for development:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
deepwrap api --reload
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Use more workers:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
deepwrap api --workers 2
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Set log level:
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
deepwrap api --log-level debug
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## HTTP API
|
|
413
|
+
|
|
414
|
+
### Health Check
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
curl http://127.0.0.1:7070/health
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Example response:
|
|
421
|
+
|
|
422
|
+
```json
|
|
423
|
+
{
|
|
424
|
+
"ok": true,
|
|
425
|
+
"app": "deepwrap",
|
|
426
|
+
"version": "0.1.0",
|
|
427
|
+
"token_configured": true,
|
|
428
|
+
"cached_clients": 1,
|
|
429
|
+
"active_sessions": 0
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### One-Shot Chat Request
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
curl -X POST http://127.0.0.1:7070/chat \
|
|
439
|
+
-H "Content-Type: application/json" \
|
|
440
|
+
-d '{
|
|
441
|
+
"message": "Explain recursion in one sentence.",
|
|
442
|
+
"model": "expert",
|
|
443
|
+
"thinking": true,
|
|
444
|
+
"search": true,
|
|
445
|
+
"stream": false
|
|
446
|
+
}'
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Example response:
|
|
450
|
+
|
|
451
|
+
```json
|
|
452
|
+
{
|
|
453
|
+
"model": "expert",
|
|
454
|
+
"response": "Recursion is a technique where a function solves a problem by calling itself on smaller versions of the same problem.",
|
|
455
|
+
"session_id": null
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
### Create Persistent Session
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
curl -X POST http://127.0.0.1:7070/sessions \
|
|
465
|
+
-H "Content-Type: application/json" \
|
|
466
|
+
-d '{
|
|
467
|
+
"model": "expert"
|
|
468
|
+
}'
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Example response:
|
|
472
|
+
|
|
473
|
+
```json
|
|
474
|
+
{
|
|
475
|
+
"session_id": "chat_abc123",
|
|
476
|
+
"model": "expert",
|
|
477
|
+
"god_mode": false
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
### Use Persistent Session
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
curl -X POST http://127.0.0.1:7070/chat \
|
|
487
|
+
-H "Content-Type: application/json" \
|
|
488
|
+
-d '{
|
|
489
|
+
"session_id": "chat_abc123",
|
|
490
|
+
"message": "My name is Nika.",
|
|
491
|
+
"model": "expert"
|
|
492
|
+
}'
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Then:
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
curl -X POST http://127.0.0.1:7070/chat \
|
|
499
|
+
-H "Content-Type: application/json" \
|
|
500
|
+
-d '{
|
|
501
|
+
"session_id": "chat_abc123",
|
|
502
|
+
"message": "What is my name?",
|
|
503
|
+
"model": "expert"
|
|
504
|
+
}'
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
### Delete Session
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
curl -X DELETE http://127.0.0.1:7070/sessions/chat_abc123
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Streaming Over HTTP
|
|
518
|
+
|
|
519
|
+
### Plain Text Streaming
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
curl -N -X POST http://127.0.0.1:7070/chat \
|
|
523
|
+
-H "Content-Type: application/json" \
|
|
524
|
+
-d '{
|
|
525
|
+
"message": "Explain black holes simply.",
|
|
526
|
+
"model": "expert",
|
|
527
|
+
"stream": true,
|
|
528
|
+
"stream_format": "text"
|
|
529
|
+
}'
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
### Server-Sent Events Streaming
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
curl -N -X POST http://127.0.0.1:7070/chat \
|
|
538
|
+
-H "Content-Type: application/json" \
|
|
539
|
+
-d '{
|
|
540
|
+
"message": "Explain black holes simply.",
|
|
541
|
+
"model": "expert",
|
|
542
|
+
"stream": true,
|
|
543
|
+
"stream_format": "sse"
|
|
544
|
+
}'
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
SSE output format:
|
|
548
|
+
|
|
549
|
+
```text
|
|
550
|
+
data: chunk text
|
|
551
|
+
|
|
552
|
+
data: more chunk text
|
|
553
|
+
|
|
554
|
+
event: done
|
|
555
|
+
data: [DONE]
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## Environment Variables
|
|
561
|
+
|
|
562
|
+
DeepWrap checks the following environment variables:
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
DEEPWRAP_API_KEY
|
|
566
|
+
DEEPSEEK_API_KEY
|
|
567
|
+
DEEPSEEK_BASE_URL
|
|
568
|
+
DEEPSEEK_BASE_DOMAIN
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
Example:
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
export DEEPWRAP_API_KEY="YOUR_BEARER_TOKEN"
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
Optional custom base URL:
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
export DEEPSEEK_BASE_URL="https://chat.deepseek.com"
|
|
581
|
+
export DEEPSEEK_BASE_DOMAIN="chat.deepseek.com"
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
---
|
|
585
|
+
|
|
586
|
+
## Project Structure
|
|
587
|
+
|
|
588
|
+
```text
|
|
589
|
+
deepwrap/
|
|
590
|
+
__init__.py
|
|
591
|
+
__main__.py
|
|
592
|
+
client.py
|
|
593
|
+
config.py
|
|
594
|
+
|
|
595
|
+
api/
|
|
596
|
+
__init__.py
|
|
597
|
+
base.py
|
|
598
|
+
chats.py
|
|
599
|
+
chat_session.py
|
|
600
|
+
pow.py
|
|
601
|
+
|
|
602
|
+
core/
|
|
603
|
+
__init__.py
|
|
604
|
+
auth.py
|
|
605
|
+
session_manager.py
|
|
606
|
+
|
|
607
|
+
interfaces/
|
|
608
|
+
cli.py
|
|
609
|
+
api.py
|
|
610
|
+
|
|
611
|
+
modules/
|
|
612
|
+
...
|
|
613
|
+
|
|
614
|
+
utils/
|
|
615
|
+
...
|
|
616
|
+
|
|
617
|
+
examples/
|
|
618
|
+
01_basic_stream.py
|
|
619
|
+
02_basic_non_stream.py
|
|
620
|
+
03_multi_turn_chat.py
|
|
621
|
+
04_god_mode.py
|
|
622
|
+
05_no_thinking.py
|
|
623
|
+
06_structured_chunks.py
|
|
624
|
+
07_separate_thinking_and_answer.py
|
|
625
|
+
08_switch_model.py
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
---
|
|
629
|
+
|
|
630
|
+
## API Design
|
|
631
|
+
|
|
632
|
+
DeepWrap exposes a small SDK surface:
|
|
633
|
+
|
|
634
|
+
```python
|
|
635
|
+
from deepwrap import Client
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Create a client:
|
|
639
|
+
|
|
640
|
+
```python
|
|
641
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
Create a chat session:
|
|
645
|
+
|
|
646
|
+
```python
|
|
647
|
+
chat = client.chats.create_session(model="expert")
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
Send a message:
|
|
651
|
+
|
|
652
|
+
```python
|
|
653
|
+
response = chat.respond("Hello", stream=False)
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
Stream a message:
|
|
657
|
+
|
|
658
|
+
```python
|
|
659
|
+
for chunk in chat.respond("Hello", stream=True):
|
|
660
|
+
print(chunk, end="")
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
Use structured chunks:
|
|
664
|
+
|
|
665
|
+
```python
|
|
666
|
+
for kind, chunk in chat.respond_structured("Hello"):
|
|
667
|
+
print(kind, chunk)
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## Development Setup
|
|
673
|
+
|
|
674
|
+
Clone the repository:
|
|
675
|
+
|
|
676
|
+
```bash
|
|
677
|
+
git clone https://github.com/Kuduxaaa/deepwrap.git
|
|
678
|
+
cd deepwrap
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
Create a virtual environment:
|
|
682
|
+
|
|
683
|
+
```bash
|
|
684
|
+
python -m venv .venv
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
Activate it:
|
|
688
|
+
|
|
689
|
+
Windows:
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
.venv\Scripts\activate
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Linux/macOS:
|
|
696
|
+
|
|
697
|
+
```bash
|
|
698
|
+
source .venv/bin/activate
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
Install in editable mode:
|
|
702
|
+
|
|
703
|
+
```bash
|
|
704
|
+
pip install -e .
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Install development dependencies:
|
|
708
|
+
|
|
709
|
+
```bash
|
|
710
|
+
pip install -e ".[dev]"
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
---
|
|
716
|
+
|
|
717
|
+
## Examples
|
|
718
|
+
|
|
719
|
+
### Switch Models
|
|
720
|
+
|
|
721
|
+
```python
|
|
722
|
+
from deepwrap import Client
|
|
723
|
+
|
|
724
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
725
|
+
|
|
726
|
+
expert_chat = client.chats.create_session(model="expert")
|
|
727
|
+
default_chat = client.chats.create_session(model="default")
|
|
728
|
+
|
|
729
|
+
print(expert_chat.respond("Explain recursion in one sentence.", stream=False))
|
|
730
|
+
print(default_chat.respond("Explain recursion in one sentence.", stream=False))
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
---
|
|
734
|
+
|
|
735
|
+
### Hide Thinking Output
|
|
736
|
+
|
|
737
|
+
```python
|
|
738
|
+
from deepwrap import Client
|
|
739
|
+
|
|
740
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
741
|
+
chat = client.chats.create_session(model="expert")
|
|
742
|
+
|
|
743
|
+
response = chat.respond(
|
|
744
|
+
"Give me three facts about Tbilisi.",
|
|
745
|
+
thinking=False,
|
|
746
|
+
search=True,
|
|
747
|
+
stream=False,
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
print(response)
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
### Disable Search
|
|
756
|
+
|
|
757
|
+
```python
|
|
758
|
+
from deepwrap import Client
|
|
759
|
+
|
|
760
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
761
|
+
chat = client.chats.create_session(model="expert")
|
|
762
|
+
|
|
763
|
+
response = chat.respond(
|
|
764
|
+
"Explain Python generators.",
|
|
765
|
+
thinking=True,
|
|
766
|
+
search=False,
|
|
767
|
+
stream=False,
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
print(response)
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
## Error Handling
|
|
776
|
+
|
|
777
|
+
Example:
|
|
778
|
+
|
|
779
|
+
```python
|
|
780
|
+
from deepwrap import Client
|
|
781
|
+
|
|
782
|
+
try:
|
|
783
|
+
client = Client(api_key="YOUR_BEARER_TOKEN")
|
|
784
|
+
chat = client.chats.create_session(model="expert")
|
|
785
|
+
response = chat.respond("Hello", stream=False)
|
|
786
|
+
print(response)
|
|
787
|
+
|
|
788
|
+
except ValueError as exc:
|
|
789
|
+
print(f"Configuration error: {exc}")
|
|
790
|
+
|
|
791
|
+
except RuntimeError as exc:
|
|
792
|
+
print(f"API error: {exc}")
|
|
793
|
+
|
|
794
|
+
except Exception as exc:
|
|
795
|
+
print(f"Unexpected error: {exc}")
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
---
|
|
799
|
+
|
|
800
|
+
## Notes
|
|
801
|
+
|
|
802
|
+
DeepWrap is designed as a developer-focused wrapper.
|
|
803
|
+
|
|
804
|
+
It handles:
|
|
805
|
+
|
|
806
|
+
* HTTP session headers
|
|
807
|
+
* Authorization
|
|
808
|
+
* Chat session creation
|
|
809
|
+
* Streaming response parsing
|
|
810
|
+
* Proof-of-work challenge solving
|
|
811
|
+
* CLI interaction
|
|
812
|
+
* Local API serving
|
|
813
|
+
|
|
814
|
+
The goal is to provide a clean interface while keeping the internal implementation modular and extensible.
|
|
815
|
+
|
|
816
|
+
---
|
|
817
|
+
|
|
818
|
+
## Security Notice
|
|
819
|
+
|
|
820
|
+
Do not commit your Bearer token.
|
|
821
|
+
|
|
822
|
+
Avoid hardcoding tokens in public repositories.
|
|
823
|
+
|
|
824
|
+
Recommended:
|
|
825
|
+
|
|
826
|
+
```bash
|
|
827
|
+
export DEEPWRAP_API_KEY="YOUR_BEARER_TOKEN"
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
Or use:
|
|
831
|
+
|
|
832
|
+
```bash
|
|
833
|
+
deepwrap auth
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
Tokens saved by DeepWrap are stored locally in the user config directory.
|
|
837
|
+
|
|
838
|
+
---
|
|
839
|
+
|
|
840
|
+
## Disclaimer
|
|
841
|
+
|
|
842
|
+
This project is an unofficial wrapper.
|
|
843
|
+
|
|
844
|
+
It is not affiliated with, endorsed by, or officially supported by DeepSeek.
|
|
845
|
+
|
|
846
|
+
Use responsibly and respect the terms of service of any service you interact with.
|
|
847
|
+
|
|
848
|
+
---
|
|
849
|
+
|
|
850
|
+
## License
|
|
851
|
+
|
|
852
|
+
MIT License
|
|
853
|
+
|
|
854
|
+
Copyright (c) 2026 Nika Kudukhashvili
|
|
855
|
+
|
|
856
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
857
|
+
of this software and associated documentation files, to deal in the Software
|
|
858
|
+
without restriction, including without limitation the rights to use, copy,
|
|
859
|
+
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
860
|
+
Software, subject to the conditions of the MIT License.
|