djeli 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.
- djeli/__init__.py +2 -0
- djeli/client.py +70 -0
- djeli-0.1.0.dist-info/METADATA +48 -0
- djeli-0.1.0.dist-info/RECORD +6 -0
- djeli-0.1.0.dist-info/WHEEL +5 -0
- djeli-0.1.0.dist-info/top_level.txt +1 -0
djeli/__init__.py
ADDED
djeli/client.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Iterator
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
DEFAULT_BASE = "http://127.0.0.1:11435"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DjeliError(Exception):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Djeli:
|
|
14
|
+
def __init__(self, base_url: str = DEFAULT_BASE, timeout: float = 300.0):
|
|
15
|
+
self.base_url = base_url.rstrip("/")
|
|
16
|
+
self.timeout = timeout
|
|
17
|
+
|
|
18
|
+
def models(self) -> list[dict]:
|
|
19
|
+
r = httpx.get(f"{self.base_url}/v1/models", timeout=10.0)
|
|
20
|
+
r.raise_for_status()
|
|
21
|
+
return r.json().get("data", [])
|
|
22
|
+
|
|
23
|
+
def chat(
|
|
24
|
+
self,
|
|
25
|
+
model: str,
|
|
26
|
+
messages: list[dict],
|
|
27
|
+
temperature: float = 0.7,
|
|
28
|
+
max_tokens: int = 1024,
|
|
29
|
+
stream: bool = False,
|
|
30
|
+
):
|
|
31
|
+
payload = {
|
|
32
|
+
"model": model,
|
|
33
|
+
"messages": messages,
|
|
34
|
+
"temperature": temperature,
|
|
35
|
+
"max_tokens": max_tokens,
|
|
36
|
+
"stream": stream,
|
|
37
|
+
}
|
|
38
|
+
if not stream:
|
|
39
|
+
r = httpx.post(
|
|
40
|
+
f"{self.base_url}/v1/chat/completions",
|
|
41
|
+
json=payload,
|
|
42
|
+
timeout=self.timeout,
|
|
43
|
+
)
|
|
44
|
+
if r.status_code >= 400:
|
|
45
|
+
raise DjeliError(r.text)
|
|
46
|
+
return r.json()["choices"][0]["message"]["content"]
|
|
47
|
+
return self._stream(payload)
|
|
48
|
+
|
|
49
|
+
def _stream(self, payload: dict) -> Iterator[str]:
|
|
50
|
+
with httpx.stream(
|
|
51
|
+
"POST",
|
|
52
|
+
f"{self.base_url}/v1/chat/completions",
|
|
53
|
+
json=payload,
|
|
54
|
+
timeout=self.timeout,
|
|
55
|
+
) as r:
|
|
56
|
+
if r.status_code >= 400:
|
|
57
|
+
raise DjeliError(r.read().decode())
|
|
58
|
+
for line in r.iter_lines():
|
|
59
|
+
if not line.startswith("data:"):
|
|
60
|
+
continue
|
|
61
|
+
data = line[5:].strip()
|
|
62
|
+
if data == "[DONE]" or not data:
|
|
63
|
+
continue
|
|
64
|
+
try:
|
|
65
|
+
chunk = json.loads(data)
|
|
66
|
+
content = chunk["choices"][0].get("delta", {}).get("content", "")
|
|
67
|
+
if content:
|
|
68
|
+
yield content
|
|
69
|
+
except (json.JSONDecodeError, KeyError, IndexError):
|
|
70
|
+
continue
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: djeli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the djeli local LLM server
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: httpx>=0.27
|
|
9
|
+
|
|
10
|
+
# djeli
|
|
11
|
+
|
|
12
|
+
Python client for the djeli local LLM server.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install djeli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from djeli import Djeli
|
|
24
|
+
|
|
25
|
+
client = Djeli()
|
|
26
|
+
answer = client.chat(
|
|
27
|
+
model="qwen2.5-1.5b-instruct-q4_k_m",
|
|
28
|
+
messages=[{"role": "user", "content": "What is the capital of Kenya?"}],
|
|
29
|
+
)
|
|
30
|
+
print(answer)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Requires a djeli serve process running on 127.0.0.1:11435.
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
. Djeli(base_url="http://127.0.0.1:11435", timeout=300.0)
|
|
38
|
+
|
|
39
|
+
. client.models() -> list[dict]
|
|
40
|
+
|
|
41
|
+
. client.chat(model, messages, temperature=0.7, max_tokens=1024, stream=False)
|
|
42
|
+
|
|
43
|
+
. DjeliError
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
### MIT
|
|
48
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
djeli/__init__.py,sha256=piHAViyOIBBXM6O0CCc0zc5diIA-GOSKKoyGBrvomi8,71
|
|
2
|
+
djeli/client.py,sha256=o-sn9fiyp7ZV55TFkj_RCVUA0pFd14Ymhwht50X0owk,2101
|
|
3
|
+
djeli-0.1.0.dist-info/METADATA,sha256=kDw96V3L3UzCX7mEvaZFY_X0NHyK8XBAi0u8yuWGHRw,810
|
|
4
|
+
djeli-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
5
|
+
djeli-0.1.0.dist-info/top_level.txt,sha256=peDWrzPbS0Mbci30qVtICpHzKxEjh1tPpXhB7n_nguI,6
|
|
6
|
+
djeli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
djeli
|