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 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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ sapienta