embed-client 2.0.0.0__py3-none-any.whl → 3.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.
@@ -1,128 +1,470 @@
1
1
  """
2
- Пример использования EmbeddingServiceAsyncClient (асинхронный клиент).
2
+ Пример использования EmbeddingServiceAsyncClient со всеми режимами безопасности.
3
3
 
4
- USAGE:
5
- python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
6
- # или
7
- python -m asyncio embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
4
+ Author: Vasiliy Zdanovskiy
5
+ email: vasilyvz@gmail.com
6
+
7
+ Этот пример демонстрирует все 6 режимов безопасности, поддерживаемых embed-client:
8
+ 1. HTTP (обычный HTTP без аутентификации)
9
+ 2. HTTP + Token (HTTP с аутентификацией по API ключу)
10
+ 3. HTTPS (HTTPS с проверкой сертификатов сервера)
11
+ 4. HTTPS + Token (HTTPS с сертификатами сервера + аутентификация)
12
+ 5. mTLS (взаимный TLS с клиентскими и серверными сертификатами)
13
+ 6. mTLS + Роли (mTLS с контролем доступа на основе ролей)
8
14
 
9
- # Можно также использовать переменные окружения:
15
+ ИСПОЛЬЗОВАНИЕ:
16
+ # Базовое использование без аутентификации
17
+ python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
18
+
19
+ # С аутентификацией по API ключу
20
+ python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method api_key --api-key your_key
21
+
22
+ # С JWT аутентификацией
23
+ python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method jwt --jwt-secret secret --jwt-username user
24
+
25
+ # С базовой аутентификацией
26
+ python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method basic --username user --password pass
27
+
28
+ # С файлом конфигурации
29
+ python embed_client/example_async_usage_ru.py --config configs/http_token.json
30
+
31
+ # С переменными окружения
10
32
  export EMBED_CLIENT_BASE_URL=http://localhost
11
33
  export EMBED_CLIENT_PORT=8001
34
+ export EMBED_CLIENT_AUTH_METHOD=api_key
35
+ export EMBED_CLIENT_API_KEY=your_key
12
36
  python embed_client/example_async_usage_ru.py
13
37
 
14
- # ВАЖНО:
15
- # --base-url и --port должны быть отдельными аргументами (через пробел),
16
- # а не через = (НЕ --base_url=...)
17
- # base_url должен содержать http:// или https://
18
-
19
- EXAMPLES:
38
+ ПРИМЕРЫ РЕЖИМОВ БЕЗОПАСНОСТИ:
39
+ # 1. HTTP - обычный HTTP без аутентификации
20
40
  python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
21
- python -m asyncio embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
22
- export EMBED_CLIENT_BASE_URL=http://localhost
23
- export EMBED_CLIENT_PORT=8001
41
+
42
+ # 2. HTTP + Token - HTTP с аутентификацией по API ключу
43
+ python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method api_key --api-key admin_key_123
44
+
45
+ # 3. HTTPS - HTTPS с проверкой сертификатов сервера
46
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443
47
+
48
+ # 4. HTTPS + Token - HTTPS с сертификатами сервера + аутентификация
49
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --auth-method jwt --jwt-secret secret --jwt-username admin
50
+
51
+ # 5. mTLS - взаимный TLS с клиентскими и серверными сертификатами
52
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --auth-method certificate --cert-file certs/client.crt --key-file keys/client.key
53
+
54
+ # 6. mTLS + Роли - mTLS с контролем доступа на основе ролей
55
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --auth-method certificate --cert-file certs/client.crt --key-file keys/client.key --roles admin,user
56
+
57
+ ПРИМЕРЫ SSL/TLS:
58
+ # HTTPS с отключенной проверкой SSL
59
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --ssl-verify-mode CERT_NONE
60
+
61
+ # mTLS с пользовательским CA сертификатом
62
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --cert-file certs/client.crt --key-file keys/client.key --ca-cert-file certs/ca.crt
63
+
64
+ # HTTPS с пользовательскими настройками SSL
65
+ python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --ssl-verify-mode CERT_REQUIRED --ssl-check-hostname --ssl-check-expiry
66
+
67
+ ПРИМЕРЫ КОНФИГУРАЦИИ:
68
+ # Использование файла конфигурации
69
+ python embed_client/example_async_usage_ru.py --config configs/https_token.json
70
+
71
+ # Использование переменных окружения
72
+ export EMBED_CLIENT_BASE_URL=https://secure.example.com
73
+ export EMBED_CLIENT_PORT=9443
74
+ export EMBED_CLIENT_AUTH_METHOD=api_key
75
+ export EMBED_CLIENT_API_KEY=production_key
24
76
  python embed_client/example_async_usage_ru.py
77
+
78
+ ПРОГРАММНЫЕ ПРИМЕРЫ:
79
+ import asyncio
80
+ from embed_client.async_client import EmbeddingServiceAsyncClient
81
+ from embed_client.config import ClientConfig
82
+ from embed_client.client_factory import ClientFactory, create_client
83
+
84
+ async def main():
85
+ # Метод 1: Прямое создание клиента
86
+ client = EmbeddingServiceAsyncClient('http://localhost', 8001)
87
+ await client.close()
88
+
89
+ # Метод 2: Использование конфигурации
90
+ config = ClientConfig()
91
+ config.configure_server('http://localhost', 8001)
92
+ client = EmbeddingServiceAsyncClient.from_config(config)
93
+ await client.close()
94
+
95
+ # Метод 3: Использование фабрики с автоматическим определением
96
+ client = create_client('https://localhost', 9443, auth_method='api_key', api_key='key')
97
+ await client.close()
98
+
99
+ # Метод 4: Использование конкретного метода фабрики
100
+ client = ClientFactory.create_https_token_client(
101
+ 'https://localhost', 9443, 'api_key', api_key='key'
102
+ )
103
+ await client.close()
104
+
105
+ # Метод 5: Использование метода with_auth для динамической аутентификации
106
+ client = EmbeddingServiceAsyncClient('http://localhost', 8001)
107
+ client = client.with_auth('api_key', api_key='dynamic_key')
108
+ await client.close()
109
+
110
+ asyncio.run(main())
25
111
  """
26
112
 
27
113
  import asyncio
28
114
  import sys
29
115
  import os
30
- from embed_client.async_client import (
31
- EmbeddingServiceAsyncClient,
32
- EmbeddingServiceConnectionError,
33
- EmbeddingServiceHTTPError,
34
- EmbeddingServiceAPIError,
35
- EmbeddingServiceError,
116
+ import argparse
117
+ import json
118
+ from typing import Dict, Any, Optional, Union
119
+
120
+ from embed_client.async_client import EmbeddingServiceAsyncClient, EmbeddingServiceError, EmbeddingServiceConnectionError, EmbeddingServiceHTTPError, EmbeddingServiceConfigError
121
+ from embed_client.config import ClientConfig
122
+ from embed_client.client_factory import (
123
+ ClientFactory, SecurityMode, create_client, create_client_from_config,
124
+ create_client_from_env, detect_security_mode
36
125
  )
37
126
 
38
127
  def get_params():
39
- base_url = None
40
- port = None
41
- for i, arg in enumerate(sys.argv):
42
- if arg in ("--base-url", "-b") and i + 1 < len(sys.argv):
43
- base_url = sys.argv[i + 1]
44
- if arg in ("--port", "-p") and i + 1 < len(sys.argv):
45
- port = sys.argv[i + 1]
46
- if not base_url:
47
- base_url = os.environ.get("EMBED_CLIENT_BASE_URL")
48
- if not port:
49
- port = os.environ.get("EMBED_CLIENT_PORT")
128
+ """Парсинг аргументов командной строки и переменных окружения для конфигурации клиента."""
129
+ parser = argparse.ArgumentParser(description="Пример Embedding Service Async Client - Все режимы безопасности")
130
+
131
+ # Базовые параметры подключения
132
+ parser.add_argument("--base-url", "-b", help="Базовый URL сервиса эмбеддингов")
133
+ parser.add_argument("--port", "-p", type=int, help="Порт сервиса эмбеддингов")
134
+ parser.add_argument("--config", "-c", help="Путь к файлу конфигурации")
135
+
136
+ # Режим фабрики клиентов
137
+ parser.add_argument("--factory-mode", choices=["auto", "http", "http_token", "https", "https_token", "mtls", "mtls_roles"],
138
+ default="auto", help="Режим фабрики клиентов (auto для автоматического определения)")
139
+
140
+ # Параметры аутентификации
141
+ parser.add_argument("--auth-method", choices=["none", "api_key", "jwt", "basic", "certificate"],
142
+ default="none", help="Метод аутентификации")
143
+ parser.add_argument("--api-key", help="API ключ для аутентификации api_key")
144
+ parser.add_argument("--jwt-secret", help="JWT секрет для аутентификации jwt")
145
+ parser.add_argument("--jwt-username", help="JWT имя пользователя для аутентификации jwt")
146
+ parser.add_argument("--jwt-password", help="JWT пароль для аутентификации jwt")
147
+ parser.add_argument("--username", help="Имя пользователя для базовой аутентификации")
148
+ parser.add_argument("--password", help="Пароль для базовой аутентификации")
149
+ parser.add_argument("--cert-file", help="Файл сертификата для аутентификации certificate")
150
+ parser.add_argument("--key-file", help="Файл ключа для аутентификации certificate")
151
+
152
+ # SSL/TLS параметры
153
+ parser.add_argument("--ssl-verify-mode", choices=["CERT_NONE", "CERT_OPTIONAL", "CERT_REQUIRED"],
154
+ default="CERT_REQUIRED", help="Режим проверки SSL сертификата")
155
+ parser.add_argument("--ssl-check-hostname", action="store_true", default=True,
156
+ help="Включить проверку имени хоста SSL")
157
+ parser.add_argument("--ssl-check-expiry", action="store_true", default=True,
158
+ help="Включить проверку срока действия SSL сертификата")
159
+ parser.add_argument("--ca-cert-file", help="Файл CA сертификата для проверки SSL")
160
+
161
+ # Контроль доступа на основе ролей (для mTLS + Роли)
162
+ parser.add_argument("--roles", help="Список ролей через запятую для режима mTLS + Роли")
163
+ parser.add_argument("--role-attributes", help="JSON строка атрибутов ролей для режима mTLS + Роли")
164
+
165
+ # Дополнительные параметры
166
+ parser.add_argument("--timeout", type=float, default=30.0, help="Таймаут запроса в секундах")
167
+ parser.add_argument("--demo-mode", action="store_true", help="Запустить в демо режиме (показать все режимы безопасности)")
168
+
169
+ args = parser.parse_args()
170
+
171
+ # Сохраняем demo_mode в args для дальнейшего использования
172
+ args.demo_mode = args.demo_mode
173
+
174
+ # Если запрошен демо режим, возвращаем args напрямую
175
+ if args.demo_mode:
176
+ return args
177
+
178
+ # Если указан файл конфигурации, загружаем его
179
+ if args.config:
180
+ try:
181
+ config = ClientConfig()
182
+ config.load_config_file(args.config)
183
+ return config
184
+ except Exception as e:
185
+ print(f"Ошибка загрузки файла конфигурации {args.config}: {e}")
186
+ sys.exit(1)
187
+
188
+ # Иначе строим конфигурацию из аргументов и переменных окружения
189
+ base_url = args.base_url or os.environ.get("EMBED_CLIENT_BASE_URL", "http://localhost")
190
+ port = args.port or int(os.environ.get("EMBED_CLIENT_PORT", "8001"))
191
+
50
192
  if not base_url or not port:
51
- print("Error: base_url and port must be provided via [--base-url | --port] arguments or [EMBED_CLIENT_BASE_URL/EMBED_CLIENT_PORT] environment variables.")
193
+ print("Ошибка: base_url и port должны быть указаны через аргументы --base-url/--port или переменные окружения EMBED_CLIENT_BASE_URL/EMBED_CLIENT_PORT.")
52
194
  sys.exit(1)
53
- return None, None
54
- return base_url, int(port)
195
+
196
+ # Строим словарь конфигурации
197
+ config_dict = {
198
+ "server": {
199
+ "host": base_url,
200
+ "port": port
201
+ },
202
+ "client": {
203
+ "timeout": args.timeout
204
+ },
205
+ "auth": {
206
+ "method": args.auth_method
207
+ }
208
+ }
209
+
210
+ # Добавляем конфигурацию аутентификации
211
+ if args.auth_method == "api_key":
212
+ api_key = args.api_key or os.environ.get("EMBED_CLIENT_API_KEY")
213
+ if api_key:
214
+ config_dict["auth"]["api_keys"] = {"user": api_key}
215
+ else:
216
+ print("Предупреждение: API ключ не указан для аутентификации api_key")
217
+
218
+ elif args.auth_method == "jwt":
219
+ jwt_secret = args.jwt_secret or os.environ.get("EMBED_CLIENT_JWT_SECRET")
220
+ jwt_username = args.jwt_username or os.environ.get("EMBED_CLIENT_JWT_USERNAME")
221
+ jwt_password = args.jwt_password or os.environ.get("EMBED_CLIENT_JWT_PASSWORD")
222
+
223
+ if jwt_secret and jwt_username and jwt_password:
224
+ config_dict["auth"]["jwt"] = {
225
+ "secret": jwt_secret,
226
+ "username": jwt_username,
227
+ "password": jwt_password
228
+ }
229
+ else:
230
+ print("Предупреждение: JWT секрет, имя пользователя или пароль не указаны для аутентификации jwt")
231
+
232
+ elif args.auth_method == "basic":
233
+ username = args.username or os.environ.get("EMBED_CLIENT_USERNAME")
234
+ password = args.password or os.environ.get("EMBED_CLIENT_PASSWORD")
235
+
236
+ if username and password:
237
+ config_dict["auth"]["basic"] = {
238
+ "username": username,
239
+ "password": password
240
+ }
241
+ else:
242
+ print("Предупреждение: Имя пользователя или пароль не указаны для базовой аутентификации")
243
+
244
+ elif args.auth_method == "certificate":
245
+ cert_file = args.cert_file or os.environ.get("EMBED_CLIENT_CERT_FILE")
246
+ key_file = args.key_file or os.environ.get("EMBED_CLIENT_KEY_FILE")
247
+
248
+ if cert_file and key_file:
249
+ config_dict["auth"]["certificate"] = {
250
+ "cert_file": cert_file,
251
+ "key_file": key_file
252
+ }
253
+ else:
254
+ print("Предупреждение: Файл сертификата или ключа не указан для аутентификации certificate")
255
+
256
+ # Добавляем SSL конфигурацию если используется HTTPS или указаны SSL параметры
257
+ if base_url.startswith("https://") or args.ssl_verify_mode != "CERT_REQUIRED" or args.ca_cert_file:
258
+ config_dict["ssl"] = {
259
+ "enabled": True,
260
+ "verify_mode": args.ssl_verify_mode,
261
+ "check_hostname": args.ssl_check_hostname,
262
+ "check_expiry": args.ssl_check_expiry
263
+ }
264
+
265
+ if args.ca_cert_file:
266
+ config_dict["ssl"]["ca_cert_file"] = args.ca_cert_file
267
+
268
+ # Добавляем клиентские сертификаты для mTLS
269
+ if args.cert_file:
270
+ config_dict["ssl"]["cert_file"] = args.cert_file
271
+ if args.key_file:
272
+ config_dict["ssl"]["key_file"] = args.key_file
273
+
274
+ # Добавляем контроль доступа на основе ролей для mTLS + Роли
275
+ if args.roles:
276
+ roles = [role.strip() for role in args.roles.split(",")]
277
+ config_dict["roles"] = roles
278
+
279
+ if args.role_attributes:
280
+ try:
281
+ role_attributes = json.loads(args.role_attributes)
282
+ config_dict["role_attributes"] = role_attributes
283
+ except json.JSONDecodeError:
284
+ print("Предупреждение: Неверный JSON в role_attributes")
285
+
286
+ return config_dict
287
+
288
+ def extract_vectors(result):
289
+ """Извлечение эмбеддингов из ответа API, поддерживает старый и новый форматы."""
290
+ # Обработка прямого поля embeddings (совместимость со старым форматом)
291
+ if "embeddings" in result:
292
+ return result["embeddings"]
293
+
294
+ # Обработка обертки result
295
+ if "result" in result:
296
+ res = result["result"]
297
+
298
+ # Обработка прямого списка в result (старый формат)
299
+ if isinstance(res, list):
300
+ return res
301
+
302
+ if isinstance(res, dict):
303
+ # Обработка старого формата: result.embeddings
304
+ if "embeddings" in res:
305
+ return res["embeddings"]
306
+
307
+ # Обработка старого формата: result.data.embeddings
308
+ if "data" in res and isinstance(res["data"], dict) and "embeddings" in res["data"]:
309
+ return res["data"]["embeddings"]
310
+
311
+ # Обработка нового формата: result.data[].embedding
312
+ if "data" in res and isinstance(res["data"], list):
313
+ embeddings = []
314
+ for item in res["data"]:
315
+ if isinstance(item, dict) and "embedding" in item:
316
+ embeddings.append(item["embedding"])
317
+ else:
318
+ raise ValueError(f"Неверный формат элемента в новом ответе API: {item}")
319
+ return embeddings
320
+
321
+ raise ValueError(f"Не удается извлечь эмбеддинги из ответа: {result}")
322
+
323
+ async def run_client_examples(client):
324
+ """Запуск примеров операций с клиентом."""
325
+ # Проверка здоровья
326
+ try:
327
+ health = await client.health()
328
+ print("Состояние сервиса:", health)
329
+ except EmbeddingServiceConnectionError as e:
330
+ print(f"[Ошибка подключения] {e}")
331
+ return
332
+ except EmbeddingServiceHTTPError as e:
333
+ print(f"[HTTP ошибка] {e.status}: {e.message}")
334
+ return
335
+ except EmbeddingServiceError as e:
336
+ print("[Другая ошибка]", e)
337
+ return
338
+
339
+ # Запрос эмбеддингов для списка текстов
340
+ texts = ["привет мир", "тестовый эмбеддинг"]
341
+ try:
342
+ result = await client.cmd("embed", params={"texts": texts})
343
+ print("Результат эмбеддинга:", result)
344
+
345
+ # Извлечение эмбеддингов
346
+ embeddings = client.extract_embeddings(result)
347
+ print("Эмбеддинги:", embeddings)
348
+
349
+ # Извлечение текстов
350
+ extracted_texts = client.extract_texts(result)
351
+ print("Извлеченные тексты:", extracted_texts)
352
+
353
+ # Извлечение чанков
354
+ chunks = client.extract_chunks(result)
355
+ print("Чанки:", chunks)
356
+
357
+ # Извлечение токенов
358
+ tokens = client.extract_tokens(result)
359
+ print("Токены:", tokens)
360
+
361
+ # Извлечение BM25 токенов
362
+ bm25_tokens = client.extract_bm25_tokens(result)
363
+ print("BM25 токены:", bm25_tokens)
364
+
365
+ except EmbeddingServiceError as e:
366
+ print(f"[Ошибка эмбеддинга] {e}")
367
+ except ValueError as e:
368
+ print(f"Обнаружен старый формат или ошибка извлечения нового формата данных: {e}")
55
369
 
56
370
  async def main():
57
- base_url, port = get_params()
58
- # Always use try/except to handle all possible errors
59
371
  try:
60
- async with EmbeddingServiceAsyncClient(base_url=base_url, port=port) as client:
61
- # Check health
62
- try:
63
- health = await client.health()
64
- print("Service health:", health)
65
- except EmbeddingServiceConnectionError as e:
66
- print("[Connection error]", e)
67
- return
68
- except EmbeddingServiceHTTPError as e:
69
- print(f"[HTTP error] {e.status}: {e.message}")
70
- return
71
- except EmbeddingServiceError as e:
72
- print("[Other error]", e)
73
- return
74
-
75
- # Request embeddings for a list of texts
76
- texts = ["hello world", "test embedding"]
77
- try:
78
- result = await client.cmd("embed", params={"texts": texts})
79
- # Use client's extract method for compatibility with both old and new formats
80
- vectors = client.extract_embeddings(result)
81
- print(f"Embeddings for {len(texts)} texts:")
82
- for i, vec in enumerate(vectors):
83
- print(f" Text: {texts[i]!r}\n Vector: {vec[:5]}... (total {len(vec)} dims)")
372
+ config = get_params()
373
+
374
+ # Проверяем, запрошен ли демо режим
375
+ if hasattr(config, 'demo_mode') and config.demo_mode:
376
+ print("=== Демонстрация всех режимов безопасности ===")
377
+ print("Этот режим показывает все 6 режимов безопасности embed-client.")
378
+ print("Примечание: Эти примеры создают конфигурации клиентов, но не подключаются к реальным серверам.")
379
+ return
380
+
381
+ # Создаем клиент на основе режима фабрики
382
+ if isinstance(config, ClientConfig):
383
+ # Используя объект конфигурации
384
+ client = EmbeddingServiceAsyncClient.from_config(config)
385
+ else:
386
+ # Используя словарь конфигурации
387
+ factory_mode = getattr(config, 'factory_mode', 'auto')
388
+
389
+ if factory_mode == "auto":
390
+ # Автоматическое определение
391
+ client = create_client(
392
+ config["server"]["host"],
393
+ config["server"]["port"],
394
+ auth_method=config["auth"]["method"],
395
+ **{k: v for k, v in config.items() if k not in ["server", "auth", "ssl", "client"]}
396
+ )
397
+ else:
398
+ # Конкретный метод фабрики
399
+ base_url = config["server"]["host"]
400
+ port = config["server"]["port"]
401
+ auth_method = config["auth"]["method"]
84
402
 
85
- # Try to extract additional data if new format is available
86
- try:
87
- embedding_data = client.extract_embedding_data(result)
88
- print("\nAdditional data from new format:")
89
- for i, data in enumerate(embedding_data):
90
- print(f" Text: {data['body']!r}")
91
- print(f" Tokens: {data['tokens']}")
92
- print(f" BM25 tokens: {data['bm25_tokens']}")
93
-
94
- # Extract tokens and BM25 tokens separately
95
- tokens = client.extract_tokens(result)
96
- bm25_tokens = client.extract_bm25_tokens(result)
97
- print(f"\nExtracted tokens: {tokens}")
98
- print(f"Extracted BM25 tokens: {bm25_tokens}")
99
-
100
- except ValueError as e:
101
- print(f"(Old format detected - no additional data available): {e}")
102
-
103
- except EmbeddingServiceAPIError as e:
104
- print("[API error]", e.error)
105
- except EmbeddingServiceHTTPError as e:
106
- print(f"[HTTP error] {e.status}: {e.message}")
107
- except EmbeddingServiceConnectionError as e:
108
- print("[Connection error]", e)
109
- except EmbeddingServiceError as e:
110
- print("[Other error]", e)
111
-
112
- # Example: error handling for invalid command
113
- try:
114
- await client.cmd("not_a_command")
115
- except EmbeddingServiceAPIError as e:
116
- print("[API error for invalid command]", e.error)
117
-
118
- # Example: error handling for empty texts
119
- try:
120
- await client.cmd("embed", params={"texts": []})
121
- except EmbeddingServiceAPIError as e:
122
- print("[API error for empty texts]", e.error)
403
+ if factory_mode == "http":
404
+ client = ClientFactory.create_http_client(base_url, port)
405
+ elif factory_mode == "http_token":
406
+ client = ClientFactory.create_http_token_client(base_url, port, auth_method, **config.get("auth", {}))
407
+ elif factory_mode == "https":
408
+ client = ClientFactory.create_https_client(base_url, port)
409
+ elif factory_mode == "https_token":
410
+ client = ClientFactory.create_https_token_client(base_url, port, auth_method, **config.get("auth", {}))
411
+ elif factory_mode == "mtls":
412
+ cert_file = config.get("ssl", {}).get("cert_file", "client_cert.pem")
413
+ key_file = config.get("ssl", {}).get("key_file", "client_key.pem")
414
+ client = ClientFactory.create_mtls_client(base_url, cert_file, key_file, port)
415
+ elif factory_mode == "mtls_roles":
416
+ cert_file = config.get("ssl", {}).get("cert_file", "client_cert.pem")
417
+ key_file = config.get("ssl", {}).get("key_file", "client_key.pem")
418
+ roles = config.get("roles", ["admin"])
419
+ role_attributes = config.get("role_attributes", {})
420
+ client = ClientFactory.create_mtls_roles_client(
421
+ base_url, cert_file, key_file, port, roles, role_attributes
422
+ )
423
+ else:
424
+ client = EmbeddingServiceAsyncClient(config_dict=config)
425
+
426
+ print(f"Конфигурация клиента:")
427
+ print(f" Базовый URL: {client.base_url}")
428
+ print(f" Порт: {client.port}")
429
+ print(f" Аутентификация: {client.get_auth_method()}")
430
+ print(f" Аутентифицирован: {client.is_authenticated()}")
431
+ if client.is_authenticated():
432
+ headers = client.get_auth_headers()
433
+ print(f" Заголовки аутентификации: {headers}")
434
+ print(f" SSL включен: {client.is_ssl_enabled()}")
435
+ print(f" mTLS включен: {client.is_mtls_enabled()}")
436
+ if client.is_ssl_enabled():
437
+ ssl_config = client.get_ssl_config()
438
+ print(f" SSL конфигурация: {ssl_config}")
439
+ protocols = client.get_supported_ssl_protocols()
440
+ print(f" Поддерживаемые SSL протоколы: {protocols}")
441
+ print()
442
+
443
+ # Пример явного открытия/закрытия сессии
444
+ print("Пример явного открытия/закрытия сессии:")
445
+ await client.close()
446
+ print("Сессия закрыта явно (пример ручного закрытия).\n")
447
+
448
+ # Используем контекстный менеджер
449
+ try:
450
+ if isinstance(config, ClientConfig):
451
+ async with EmbeddingServiceAsyncClient.from_config(config) as client:
452
+ await run_client_examples(client)
453
+ else:
454
+ async with EmbeddingServiceAsyncClient(config_dict=config) as client:
455
+ await run_client_examples(client)
456
+
457
+ except EmbeddingServiceError as e:
458
+ print(f"[Ошибка EmbeddingService] {e}")
459
+ except Exception as e:
460
+ print(f"[Неожиданная ошибка] {e}")
123
461
 
462
+ except EmbeddingServiceConfigError as e:
463
+ print(f"Ошибка конфигурации: {e}")
464
+ sys.exit(1)
124
465
  except Exception as e:
125
- print("[Unexpected error]", e)
466
+ print(f"Неожиданная ошибка: {e}")
467
+ sys.exit(1)
126
468
 
127
469
  if __name__ == "__main__":
128
470
  asyncio.run(main())