embed-client 0.0.1__py3-none-any.whl → 1.0.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.
- embed_client/async_client.py +50 -15
- embed_client/example_async_usage.py +28 -53
- {embed_client-0.0.1.dist-info → embed_client-1.0.0.dist-info}/METADATA +1 -1
- embed_client-1.0.0.dist-info/RECORD +8 -0
- {embed_client-0.0.1.dist-info → embed_client-1.0.0.dist-info}/WHEEL +1 -1
- embed_client-0.0.1.dist-info/RECORD +0 -8
- {embed_client-0.0.1.dist-info → embed_client-1.0.0.dist-info}/top_level.txt +0 -0
embed_client/async_client.py
CHANGED
@@ -8,6 +8,7 @@ Async client for Embedding Service API (OpenAPI 3.0.2)
|
|
8
8
|
|
9
9
|
from typing import Any, Dict, List, Optional, Union
|
10
10
|
import aiohttp
|
11
|
+
import os
|
11
12
|
|
12
13
|
class EmbeddingServiceError(Exception):
|
13
14
|
"""Base exception for EmbeddingServiceAsyncClient."""
|
@@ -37,13 +38,13 @@ class EmbeddingServiceAsyncClient:
|
|
37
38
|
Raises:
|
38
39
|
ValueError: If base_url or port is not provided.
|
39
40
|
"""
|
40
|
-
def __init__(self, base_url: str, port: int):
|
41
|
-
|
41
|
+
def __init__(self, base_url: Optional[str] = None, port: Optional[int] = None):
|
42
|
+
self.base_url = base_url or os.getenv("EMBEDDING_SERVICE_BASE_URL", "http://localhost")
|
43
|
+
if not self.base_url:
|
42
44
|
raise ValueError("base_url must be provided.")
|
43
|
-
|
45
|
+
self.port = port or int(os.getenv("EMBEDDING_SERVICE_PORT", "8001"))
|
46
|
+
if self.port is None:
|
44
47
|
raise ValueError("port must be provided.")
|
45
|
-
self.base_url = base_url.rstrip("/")
|
46
|
-
self.port = port
|
47
48
|
self._session: Optional[aiohttp.ClientSession] = None
|
48
49
|
|
49
50
|
def _make_url(self, path: str, base_url: Optional[str] = None, port: Optional[int] = None) -> str:
|
@@ -51,6 +52,23 @@ class EmbeddingServiceAsyncClient:
|
|
51
52
|
port_val = port if port is not None else self.port
|
52
53
|
return f"{url}:{port_val}{path}"
|
53
54
|
|
55
|
+
def _format_error_response(self, error: str, lang: Optional[str] = None, text: Optional[str] = None) -> Dict[str, Any]:
|
56
|
+
"""
|
57
|
+
Format error response in a standard way.
|
58
|
+
Args:
|
59
|
+
error (str): Error message
|
60
|
+
lang (str, optional): Language of the text that caused the error
|
61
|
+
text (str, optional): Text that caused the error
|
62
|
+
Returns:
|
63
|
+
dict: Formatted error response
|
64
|
+
"""
|
65
|
+
response = {"error": f"Embedding service error: {error}"}
|
66
|
+
if lang is not None:
|
67
|
+
response["lang"] = lang
|
68
|
+
if text is not None:
|
69
|
+
response["text"] = text
|
70
|
+
return response
|
71
|
+
|
54
72
|
async def __aenter__(self):
|
55
73
|
self._session = aiohttp.ClientSession()
|
56
74
|
return self
|
@@ -144,8 +162,25 @@ class EmbeddingServiceAsyncClient:
|
|
144
162
|
base_url (str, optional): Override base URL.
|
145
163
|
port (int, optional): Override port.
|
146
164
|
Returns:
|
147
|
-
dict: Command execution result
|
165
|
+
dict: Command execution result or error response in format:
|
166
|
+
{
|
167
|
+
"error": {
|
168
|
+
"code": <код ошибки>,
|
169
|
+
"message": <сообщение об ошибке>
|
170
|
+
}
|
171
|
+
}
|
172
|
+
или
|
173
|
+
{
|
174
|
+
"result": {
|
175
|
+
"success": true,
|
176
|
+
"data": {
|
177
|
+
"embeddings": [[...], ...]
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
148
181
|
"""
|
182
|
+
if not command:
|
183
|
+
raise EmbeddingServiceAPIError("Command is required")
|
149
184
|
url = self._make_url("/cmd", base_url, port)
|
150
185
|
payload = {"command": command}
|
151
186
|
if params is not None:
|
@@ -154,22 +189,22 @@ class EmbeddingServiceAsyncClient:
|
|
154
189
|
async with self._session.post(url, json=payload) as resp:
|
155
190
|
await self._raise_for_status(resp)
|
156
191
|
data = await resp.json()
|
157
|
-
# Обработка ошибок, возвращаемых сервером в теле ответа
|
158
192
|
if "error" in data:
|
159
193
|
raise EmbeddingServiceAPIError(data["error"])
|
194
|
+
if "result" in data:
|
195
|
+
res = data["result"]
|
196
|
+
if isinstance(res, dict) and "success" in res and res["success"] is False:
|
197
|
+
if "error" in res:
|
198
|
+
raise EmbeddingServiceAPIError(res["error"])
|
160
199
|
return data
|
161
|
-
except EmbeddingServiceAPIError:
|
162
|
-
raise
|
163
|
-
except EmbeddingServiceHTTPError:
|
164
|
-
raise
|
165
|
-
except EmbeddingServiceConnectionError:
|
166
|
-
raise
|
167
200
|
except aiohttp.ClientConnectionError as e:
|
168
|
-
raise
|
201
|
+
raise EmbeddingServiceAPIError(f"Connection error: {e}") from e
|
169
202
|
except aiohttp.ClientResponseError as e:
|
170
203
|
raise EmbeddingServiceHTTPError(e.status, e.message) from e
|
204
|
+
except EmbeddingServiceHTTPError:
|
205
|
+
raise
|
171
206
|
except Exception as e:
|
172
|
-
raise
|
207
|
+
raise EmbeddingServiceAPIError(f"Unexpected error: {e}") from e
|
173
208
|
|
174
209
|
async def _raise_for_status(self, resp: aiohttp.ClientResponse):
|
175
210
|
try:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Example usage of EmbeddingServiceAsyncClient.
|
3
3
|
|
4
4
|
This example demonstrates how to use the async client to check the health of the embedding service,
|
5
|
-
request embeddings, and handle all possible
|
5
|
+
request embeddings, and handle all possible errors.
|
6
6
|
|
7
7
|
Run this script with:
|
8
8
|
python -m asyncio embed_client/example_async_usage.py --base-url http://localhost --port 8001
|
@@ -13,13 +13,7 @@ You can also set EMBED_CLIENT_BASE_URL and EMBED_CLIENT_PORT environment variabl
|
|
13
13
|
import asyncio
|
14
14
|
import sys
|
15
15
|
import os
|
16
|
-
from embed_client.async_client import
|
17
|
-
EmbeddingServiceAsyncClient,
|
18
|
-
EmbeddingServiceConnectionError,
|
19
|
-
EmbeddingServiceHTTPError,
|
20
|
-
EmbeddingServiceAPIError,
|
21
|
-
EmbeddingServiceError,
|
22
|
-
)
|
16
|
+
from embed_client.async_client import EmbeddingServiceAsyncClient
|
23
17
|
|
24
18
|
def get_params():
|
25
19
|
base_url = None
|
@@ -41,54 +35,35 @@ def get_params():
|
|
41
35
|
|
42
36
|
async def main():
|
43
37
|
base_url, port = get_params()
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
try:
|
49
|
-
health = await client.health()
|
50
|
-
print("Service health:", health)
|
51
|
-
except EmbeddingServiceConnectionError as e:
|
52
|
-
print("[Connection error]", e)
|
53
|
-
return
|
54
|
-
except EmbeddingServiceHTTPError as e:
|
55
|
-
print(f"[HTTP error] {e.status}: {e.message}")
|
56
|
-
return
|
57
|
-
except EmbeddingServiceError as e:
|
58
|
-
print("[Other error]", e)
|
59
|
-
return
|
38
|
+
async with EmbeddingServiceAsyncClient(base_url=base_url, port=port) as client:
|
39
|
+
# Check health
|
40
|
+
health = await client.health()
|
41
|
+
print("Service health:", health)
|
60
42
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
print("[
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
print("[Other error]", e)
|
43
|
+
# Request embeddings for a list of texts
|
44
|
+
texts = ["hello world", "test embedding"]
|
45
|
+
result = await client.cmd("embed", params={"texts": texts})
|
46
|
+
|
47
|
+
if "error" in result:
|
48
|
+
print(f"Error occurred: {result['error']}")
|
49
|
+
if "lang" in result:
|
50
|
+
print(f"Language: {result['lang']}")
|
51
|
+
if "text" in result:
|
52
|
+
print(f"Text: {result['text']}")
|
53
|
+
else:
|
54
|
+
vectors = result["result"]
|
55
|
+
print(f"Embeddings for {len(texts)} texts:")
|
56
|
+
for i, vec in enumerate(vectors):
|
57
|
+
print(f" Text: {texts[i]!r}\n Vector: {vec[:5]}... (total {len(vec)} dims)")
|
77
58
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
except EmbeddingServiceAPIError as e:
|
82
|
-
print("[API error for invalid command]", e.error)
|
59
|
+
# Example: error handling for invalid command
|
60
|
+
result = await client.cmd("health")
|
61
|
+
print("Health check result:", result)
|
83
62
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
print("[API error for empty texts]", e.error)
|
89
|
-
|
90
|
-
except Exception as e:
|
91
|
-
print("[Unexpected error]", e)
|
63
|
+
# Example: error handling for empty command
|
64
|
+
# result = await client.cmd("")
|
65
|
+
# if "error" in result:
|
66
|
+
# print(f"Error for empty command: {result['error']}")
|
92
67
|
|
93
68
|
if __name__ == "__main__":
|
94
69
|
asyncio.run(main())
|
@@ -0,0 +1,8 @@
|
|
1
|
+
embed_client/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
2
|
+
embed_client/async_client.py,sha256=twSw-YhWdo1yeQLkfbi6ldCrq647TrEhEbPigpsAX6U,8802
|
3
|
+
embed_client/example_async_usage.py,sha256=df0RRwq2FtqVSL2MHVclfVIJj1wyQUuKZXB-lyVb3Kg,2538
|
4
|
+
embed_client/example_async_usage_ru.py,sha256=kZXQcbEFkx9tWXoCq-AoyvvUY4aCuW1XqPVb1ADWeAM,3558
|
5
|
+
embed_client-1.0.0.dist-info/METADATA,sha256=vsgnbBHhgvu1Mkj-NV-iUFs0w03aqSSe1Ju6kDECHk0,252
|
6
|
+
embed_client-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
7
|
+
embed_client-1.0.0.dist-info/top_level.txt,sha256=uG00A4d9o9DFrhiN7goObpeig72Pniby0E7UpDRgyXY,13
|
8
|
+
embed_client-1.0.0.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
embed_client/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
2
|
-
embed_client/async_client.py,sha256=HzvJ85Qh8fT-YHuam4YFW5Kbxx2hrbsOV8EzjbQ34Eg,7329
|
3
|
-
embed_client/example_async_usage.py,sha256=7j9Hro7-TjsKVC2vHUX2J1_-Rh3V9FxsOmsCdCV8KYM,3555
|
4
|
-
embed_client/example_async_usage_ru.py,sha256=kZXQcbEFkx9tWXoCq-AoyvvUY4aCuW1XqPVb1ADWeAM,3558
|
5
|
-
embed_client-0.0.1.dist-info/METADATA,sha256=GUuiN2owdcnNa7XqqZeEJo_G9oV8Z7ZoqcNUtn-Cuyo,252
|
6
|
-
embed_client-0.0.1.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
7
|
-
embed_client-0.0.1.dist-info/top_level.txt,sha256=uG00A4d9o9DFrhiN7goObpeig72Pniby0E7UpDRgyXY,13
|
8
|
-
embed_client-0.0.1.dist-info/RECORD,,
|
File without changes
|