sapienta 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.
- sapienta/__init__.py +1 -0
- sapienta/client.py +187 -0
- sapienta-0.1.0.dist-info/METADATA +44 -0
- sapienta-0.1.0.dist-info/RECORD +6 -0
- sapienta-0.1.0.dist-info/WHEEL +5 -0
- sapienta-0.1.0.dist-info/top_level.txt +1 -0
sapienta/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .client import Sapienta, SapientaError
|
sapienta/client.py
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SapientaError(Exception):
|
|
5
|
+
"""Base exception for the Sapienta SDK."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class _ChatResponse:
|
|
9
|
+
"""Response returned by the Sapienta chat API."""
|
|
10
|
+
|
|
11
|
+
__slots__ = (
|
|
12
|
+
"__content",
|
|
13
|
+
"__completion_tokens",
|
|
14
|
+
"__prompt_tokens",
|
|
15
|
+
"__total_tokens",
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
content: str,
|
|
21
|
+
completion_tokens: int,
|
|
22
|
+
prompt_tokens: int,
|
|
23
|
+
total_tokens: int,
|
|
24
|
+
):
|
|
25
|
+
object.__setattr__(self, "_ChatResponse__content", content)
|
|
26
|
+
object.__setattr__(
|
|
27
|
+
self, "_ChatResponse__completion_tokens", completion_tokens
|
|
28
|
+
)
|
|
29
|
+
object.__setattr__(
|
|
30
|
+
self, "_ChatResponse__prompt_tokens", prompt_tokens
|
|
31
|
+
)
|
|
32
|
+
object.__setattr__(
|
|
33
|
+
self, "_ChatResponse__total_tokens", total_tokens
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def content(self) -> str:
|
|
38
|
+
"""The assistant's generated response."""
|
|
39
|
+
return self.__content
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def completion_tokens(self) -> int:
|
|
43
|
+
"""Number of tokens generated by the model."""
|
|
44
|
+
return self.__completion_tokens
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def prompt_tokens(self) -> int:
|
|
48
|
+
"""Number of tokens in the input prompt."""
|
|
49
|
+
return self.__prompt_tokens
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def total_tokens(self) -> int:
|
|
53
|
+
"""Total number of tokens used by the request."""
|
|
54
|
+
return self.__total_tokens
|
|
55
|
+
|
|
56
|
+
def __setattr__(self, name, value):
|
|
57
|
+
raise AttributeError("ChatResponse is read-only.")
|
|
58
|
+
|
|
59
|
+
def __dir__(self):
|
|
60
|
+
return [
|
|
61
|
+
"content",
|
|
62
|
+
"completion_tokens",
|
|
63
|
+
"prompt_tokens",
|
|
64
|
+
"total_tokens",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Sapienta:
|
|
69
|
+
_BASE_URL = "https://jett-lateenrigged-jessie.ngrok-free.dev"
|
|
70
|
+
_MODEL = "qwen3-vl:8b"
|
|
71
|
+
|
|
72
|
+
def __init__(self, api_key: str):
|
|
73
|
+
if not isinstance(api_key, str) or not api_key.strip():
|
|
74
|
+
raise SapientaError("API key is required.")
|
|
75
|
+
|
|
76
|
+
self._client = httpx.Client(
|
|
77
|
+
base_url=self._BASE_URL,
|
|
78
|
+
headers={
|
|
79
|
+
"Authorization": f"Bearer {api_key}",
|
|
80
|
+
"Content-Type": "application/json",
|
|
81
|
+
},
|
|
82
|
+
timeout=60.0,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def chat(self, message: str) -> _ChatResponse:
|
|
86
|
+
"""
|
|
87
|
+
Send a message to Sapienta AI.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
message: The message to send to the model.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
The generated response and token usage.
|
|
94
|
+
|
|
95
|
+
Raises:
|
|
96
|
+
SapientaError: If the request fails or the response is invalid.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
if not isinstance(message, str) or not message.strip():
|
|
100
|
+
raise SapientaError("Message is required.")
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
response = self._client.post(
|
|
104
|
+
"/v1/chat/completions",
|
|
105
|
+
json={
|
|
106
|
+
"model": self._MODEL,
|
|
107
|
+
"messages": [
|
|
108
|
+
{
|
|
109
|
+
"role": "user",
|
|
110
|
+
"content": message,
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"stream": False,
|
|
114
|
+
},
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
response.raise_for_status()
|
|
118
|
+
data = response.json()
|
|
119
|
+
|
|
120
|
+
except httpx.TimeoutException as e:
|
|
121
|
+
raise SapientaError(
|
|
122
|
+
"Sapienta request timed out. Please try again later."
|
|
123
|
+
) from e
|
|
124
|
+
|
|
125
|
+
except httpx.HTTPStatusError as e:
|
|
126
|
+
status = e.response.status_code
|
|
127
|
+
|
|
128
|
+
if status == 401:
|
|
129
|
+
raise SapientaError("Invalid API key.") from e
|
|
130
|
+
|
|
131
|
+
if status == 403:
|
|
132
|
+
raise SapientaError(
|
|
133
|
+
"You are not authorized to use Sapienta."
|
|
134
|
+
) from e
|
|
135
|
+
|
|
136
|
+
if status >= 500:
|
|
137
|
+
raise SapientaError(
|
|
138
|
+
"Sapienta is temporarily unavailable. "
|
|
139
|
+
"Please try again later."
|
|
140
|
+
) from e
|
|
141
|
+
|
|
142
|
+
raise SapientaError(
|
|
143
|
+
"Sapienta could not process your request. "
|
|
144
|
+
"Please try again later."
|
|
145
|
+
) from e
|
|
146
|
+
|
|
147
|
+
except httpx.RequestError as e:
|
|
148
|
+
raise SapientaError(
|
|
149
|
+
"Unable to connect to Sapienta. Please try again later."
|
|
150
|
+
) from e
|
|
151
|
+
|
|
152
|
+
except ValueError as e:
|
|
153
|
+
raise SapientaError(
|
|
154
|
+
"Sapienta returned an invalid response."
|
|
155
|
+
) from e
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
usage = data["usage"]
|
|
159
|
+
message_data = data["choices"][0]["message"]
|
|
160
|
+
|
|
161
|
+
content = message_data["content"]
|
|
162
|
+
completion_tokens = usage["completion_tokens"]
|
|
163
|
+
prompt_tokens = usage["prompt_tokens"]
|
|
164
|
+
total_tokens = usage["total_tokens"]
|
|
165
|
+
|
|
166
|
+
if (
|
|
167
|
+
not isinstance(content, str)
|
|
168
|
+
or not isinstance(completion_tokens, int)
|
|
169
|
+
or isinstance(completion_tokens, bool)
|
|
170
|
+
or not isinstance(prompt_tokens, int)
|
|
171
|
+
or isinstance(prompt_tokens, bool)
|
|
172
|
+
or not isinstance(total_tokens, int)
|
|
173
|
+
or isinstance(total_tokens, bool)
|
|
174
|
+
):
|
|
175
|
+
raise TypeError("Unexpected response field types.")
|
|
176
|
+
|
|
177
|
+
return _ChatResponse(
|
|
178
|
+
content=content,
|
|
179
|
+
completion_tokens=completion_tokens,
|
|
180
|
+
prompt_tokens=prompt_tokens,
|
|
181
|
+
total_tokens=total_tokens,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
except (KeyError, IndexError, TypeError) as e:
|
|
185
|
+
raise SapientaError(
|
|
186
|
+
"Sapienta returned an unexpected response."
|
|
187
|
+
) from e
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sapienta
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for Sapienta AI
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: httpx>=0.27.0
|
|
8
|
+
|
|
9
|
+
# Sapienta Python SDK
|
|
10
|
+
|
|
11
|
+
Official Python SDK for integrating Sapienta AI into your applications.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install sapienta
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from sapienta import Sapienta
|
|
23
|
+
|
|
24
|
+
client = Sapienta("YOUR_API_KEY")
|
|
25
|
+
|
|
26
|
+
response = client.chat("Hello!")
|
|
27
|
+
|
|
28
|
+
print(response.content)
|
|
29
|
+
print(response.completion_tokens)
|
|
30
|
+
print(response.prompt_tokens)
|
|
31
|
+
print(response.total_tokens)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Key
|
|
35
|
+
|
|
36
|
+
Contact the Sapienta team to obtain your API key.
|
|
37
|
+
|
|
38
|
+
## Requirements
|
|
39
|
+
|
|
40
|
+
Python 3.9 or later.
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
Proprietary. All rights reserved.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
sapienta/__init__.py,sha256=0cOI0mF9hlVV2Yk0DqggNE8RwXjCrFk-a5pmH1LpBDU,43
|
|
2
|
+
sapienta/client.py,sha256=Dq4Q0nAtXeGu53bXna9qSOxyooU1X35npn7U6HqExqo,5496
|
|
3
|
+
sapienta-0.1.0.dist-info/METADATA,sha256=8Qs0B94guA2RpelGk8duMiv9dG4Vpdce1odBvInYweA,718
|
|
4
|
+
sapienta-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
sapienta-0.1.0.dist-info/top_level.txt,sha256=y0jm4xL71NAmabUZ3eF5fBAdvA232UHo7i6BT-_AVxo,9
|
|
6
|
+
sapienta-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sapienta
|