embed-client 2.0.0.0__py3-none-any.whl → 3.1.0.1__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 +376 -16
- embed_client/auth.py +491 -0
- embed_client/auth_examples.py +248 -0
- embed_client/client_factory.py +396 -0
- embed_client/client_factory_examples.py +353 -0
- embed_client/config.py +592 -0
- embed_client/config_examples.py +197 -0
- embed_client/example_async_usage.py +578 -90
- embed_client/example_async_usage_ru.py +536 -102
- embed_client/ssl_examples.py +329 -0
- embed_client/ssl_manager.py +475 -0
- embed_client-3.1.0.1.dist-info/METADATA +256 -0
- embed_client-3.1.0.1.dist-info/RECORD +17 -0
- embed_client-3.1.0.1.dist-info/licenses/LICENSE +21 -0
- embed_client-2.0.0.0.dist-info/METADATA +0 -9
- embed_client-2.0.0.0.dist-info/RECORD +0 -8
- {embed_client-2.0.0.0.dist-info → embed_client-3.1.0.1.dist-info}/WHEEL +0 -0
- {embed_client-2.0.0.0.dist-info → embed_client-3.1.0.1.dist-info}/top_level.txt +0 -0
@@ -1,128 +1,562 @@
|
|
1
1
|
"""
|
2
|
-
Пример использования EmbeddingServiceAsyncClient
|
2
|
+
Пример использования EmbeddingServiceAsyncClient со всеми режимами безопасности и ClientFactory.
|
3
3
|
|
4
|
-
|
5
|
-
|
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
|
8
6
|
|
9
|
-
|
7
|
+
ИСПОЛЬЗОВАНИЕ:
|
8
|
+
# Базовое использование без аутентификации
|
9
|
+
python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
|
10
|
+
|
11
|
+
# С аутентификацией по API ключу
|
12
|
+
python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method api_key --api-key your_key
|
13
|
+
|
14
|
+
# С JWT аутентификацией
|
15
|
+
python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method jwt --jwt-secret secret --jwt-username user
|
16
|
+
|
17
|
+
# С базовой аутентификацией
|
18
|
+
python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method basic --username user --password pass
|
19
|
+
|
20
|
+
# С файлом конфигурации
|
21
|
+
python embed_client/example_async_usage_ru.py --config configs/http_token.json
|
22
|
+
|
23
|
+
# С переменными окружения
|
10
24
|
export EMBED_CLIENT_BASE_URL=http://localhost
|
11
25
|
export EMBED_CLIENT_PORT=8001
|
26
|
+
export EMBED_CLIENT_AUTH_METHOD=api_key
|
27
|
+
export EMBED_CLIENT_API_KEY=your_key
|
12
28
|
python embed_client/example_async_usage_ru.py
|
13
29
|
|
14
|
-
|
15
|
-
#
|
16
|
-
# а не через = (НЕ --base_url=...)
|
17
|
-
# base_url должен содержать http:// или https://
|
18
|
-
|
19
|
-
EXAMPLES:
|
30
|
+
ПРИМЕРЫ РЕЖИМОВ БЕЗОПАСНОСТИ:
|
31
|
+
# 1. HTTP - обычный HTTP без аутентификации
|
20
32
|
python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001
|
21
|
-
|
22
|
-
|
23
|
-
|
33
|
+
|
34
|
+
# 2. HTTP + Token - HTTP с аутентификацией по API ключу
|
35
|
+
python embed_client/example_async_usage_ru.py --base-url http://localhost --port 8001 --auth-method api_key --api-key admin_key_123
|
36
|
+
|
37
|
+
# 3. HTTPS - HTTPS с проверкой сертификатов сервера
|
38
|
+
python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443
|
39
|
+
|
40
|
+
# 4. HTTPS + Token - HTTPS с сертификатами сервера + аутентификация
|
41
|
+
python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --auth-method jwt --jwt-secret secret --jwt-username admin
|
42
|
+
|
43
|
+
# 5. mTLS - взаимная TLS с сертификатами клиента и сервера
|
44
|
+
python embed_client/example_async_usage_ru.py --base-url https://localhost --port 8443 --cert-file mtls_certificates/client/embedding-service.crt --key-file mtls_certificates/client/embedding-service.key
|
45
|
+
|
46
|
+
# 6. mTLS + Roles - mTLS с контролем доступа на основе ролей
|
47
|
+
python embed_client/example_async_usage_ru.py --base-url https://localhost --port 8443 --cert-file mtls_certificates/client/embedding-service.crt --key-file mtls_certificates/client/embedding-service.key --roles admin,user
|
48
|
+
|
49
|
+
ПРИМЕРЫ ФАБРИКИ КЛИЕНТОВ:
|
50
|
+
# Автоматическое определение режима безопасности
|
51
|
+
python embed_client/example_async_usage_ru.py --factory-mode auto --base-url https://localhost --port 9443 --auth-method api_key --api-key key
|
52
|
+
|
53
|
+
# Создание конкретного режима безопасности
|
54
|
+
python embed_client/example_async_usage_ru.py --factory-mode https_token --base-url https://localhost --port 9443 --auth-method basic --username user --password pass
|
55
|
+
|
56
|
+
# mTLS с фабрикой
|
57
|
+
python embed_client/example_async_usage_ru.py --factory-mode mtls --base-url https://localhost --port 8443 --cert-file mtls_certificates/client/embedding-service.crt --key-file mtls_certificates/client/embedding-service.key
|
58
|
+
|
59
|
+
ПРИМЕРЫ SSL/TLS:
|
60
|
+
# HTTPS с отключенной проверкой SSL
|
61
|
+
python embed_client/example_async_usage_ru.py --base-url https://localhost --port 9443 --ssl-verify-mode CERT_NONE
|
62
|
+
|
63
|
+
# mTLS с пользовательским CA сертификатом
|
64
|
+
python embed_client/example_async_usage_ru.py --base-url https://localhost --port 8443 --cert-file mtls_certificates/client/embedding-service.crt --key-file mtls_certificates/client/embedding-service.key --ca-cert-file mtls_certificates/ca/ca.crt
|
65
|
+
|
66
|
+
# HTTPS с пользовательскими настройками SSL
|
67
|
+
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
|
68
|
+
|
69
|
+
ПРИМЕРЫ КОНФИГУРАЦИИ:
|
70
|
+
# Использование файла конфигурации
|
71
|
+
python embed_client/example_async_usage_ru.py --config configs/https_token.json
|
72
|
+
|
73
|
+
# Использование переменных окружения
|
74
|
+
export EMBED_CLIENT_BASE_URL=https://secure.example.com
|
75
|
+
export EMBED_CLIENT_PORT=9443
|
76
|
+
export EMBED_CLIENT_AUTH_METHOD=api_key
|
77
|
+
export EMBED_CLIENT_API_KEY=production_key
|
24
78
|
python embed_client/example_async_usage_ru.py
|
79
|
+
|
80
|
+
Пример явного закрытия сессии:
|
81
|
+
import asyncio
|
82
|
+
from embed_client.async_client import EmbeddingServiceAsyncClient
|
83
|
+
from embed_client.config import ClientConfig
|
84
|
+
from embed_client.client_factory import ClientFactory, create_client
|
85
|
+
|
86
|
+
async def main():
|
87
|
+
# Метод 1: Прямое создание клиента
|
88
|
+
client = EmbeddingServiceAsyncClient('http://localhost', 8001)
|
89
|
+
await client.close()
|
90
|
+
|
91
|
+
# Метод 2: Использование конфигурации
|
92
|
+
config = ClientConfig()
|
93
|
+
config.configure_server('http://localhost', 8001)
|
94
|
+
client = EmbeddingServiceAsyncClient.from_config(config)
|
95
|
+
await client.close()
|
96
|
+
|
97
|
+
# Метод 3: Использование фабрики с автоматическим определением
|
98
|
+
client = create_client('https://localhost', 9443, auth_method='api_key', api_key='key')
|
99
|
+
await client.close()
|
100
|
+
|
101
|
+
# Метод 4: Использование конкретного метода фабрики
|
102
|
+
client = ClientFactory.create_https_token_client(
|
103
|
+
'https://localhost', 9443, 'api_key', api_key='key'
|
104
|
+
)
|
105
|
+
await client.close()
|
106
|
+
|
107
|
+
asyncio.run(main())
|
25
108
|
"""
|
26
109
|
|
110
|
+
import argparse
|
27
111
|
import asyncio
|
28
|
-
import
|
112
|
+
import json
|
29
113
|
import os
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
114
|
+
import sys
|
115
|
+
from typing import Dict, Any, Optional, Union
|
116
|
+
|
117
|
+
from embed_client.async_client import EmbeddingServiceAsyncClient, EmbeddingServiceError, EmbeddingServiceConfigError
|
118
|
+
from embed_client.config import ClientConfig
|
119
|
+
from embed_client.client_factory import (
|
120
|
+
ClientFactory, SecurityMode, create_client, create_client_from_config,
|
121
|
+
create_client_from_env, detect_security_mode
|
36
122
|
)
|
37
123
|
|
124
|
+
|
38
125
|
def get_params():
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
126
|
+
"""Парсинг аргументов командной строки и переменных окружения для конфигурации клиента."""
|
127
|
+
parser = argparse.ArgumentParser(description="Пример Embedding Service Async Client - Все режимы безопасности")
|
128
|
+
|
129
|
+
# Базовые параметры подключения
|
130
|
+
parser.add_argument("--base-url", "-b", help="Базовый URL сервиса эмбеддингов")
|
131
|
+
parser.add_argument("--port", "-p", type=int, help="Порт сервиса эмбеддингов")
|
132
|
+
parser.add_argument("--config", "-c", help="Путь к файлу конфигурации")
|
133
|
+
|
134
|
+
# Режим фабрики клиентов
|
135
|
+
parser.add_argument("--factory-mode", choices=["auto", "http", "http_token", "https", "https_token", "mtls", "mtls_roles"],
|
136
|
+
default="auto", help="Режим фабрики клиентов (auto для автоматического определения)")
|
137
|
+
|
138
|
+
# Параметры аутентификации
|
139
|
+
parser.add_argument("--auth-method", choices=["none", "api_key", "jwt", "basic", "certificate"],
|
140
|
+
default="none", help="Метод аутентификации")
|
141
|
+
parser.add_argument("--api-key", help="API ключ для аутентификации api_key")
|
142
|
+
parser.add_argument("--jwt-secret", help="JWT секрет для аутентификации jwt")
|
143
|
+
parser.add_argument("--jwt-username", help="JWT имя пользователя для аутентификации jwt")
|
144
|
+
parser.add_argument("--jwt-password", help="JWT пароль для аутентификации jwt")
|
145
|
+
parser.add_argument("--username", help="Имя пользователя для базовой аутентификации")
|
146
|
+
parser.add_argument("--password", help="Пароль для базовой аутентификации")
|
147
|
+
parser.add_argument("--cert-file", help="Файл сертификата для аутентификации certificate")
|
148
|
+
parser.add_argument("--key-file", help="Файл ключа для аутентификации certificate")
|
149
|
+
|
150
|
+
# Параметры SSL/TLS
|
151
|
+
parser.add_argument("--ssl-verify-mode", choices=["CERT_NONE", "CERT_OPTIONAL", "CERT_REQUIRED"],
|
152
|
+
default="CERT_REQUIRED", help="Режим проверки SSL сертификатов")
|
153
|
+
parser.add_argument("--ssl-check-hostname", action="store_true", default=True,
|
154
|
+
help="Включить проверку имени хоста SSL")
|
155
|
+
parser.add_argument("--ssl-check-expiry", action="store_true", default=True,
|
156
|
+
help="Включить проверку срока действия SSL сертификатов")
|
157
|
+
parser.add_argument("--ca-cert-file", help="Файл CA сертификата для проверки SSL")
|
158
|
+
|
159
|
+
# Контроль доступа на основе ролей (для mTLS + Roles)
|
160
|
+
parser.add_argument("--roles", help="Список ролей через запятую для режима mTLS + Roles")
|
161
|
+
parser.add_argument("--role-attributes", help="JSON строка атрибутов ролей для режима mTLS + Roles")
|
162
|
+
|
163
|
+
# Дополнительные параметры
|
164
|
+
parser.add_argument("--timeout", type=float, default=30.0, help="Таймаут запроса в секундах")
|
165
|
+
parser.add_argument("--demo-mode", action="store_true", help="Запуск в демо режиме (показать все режимы безопасности)")
|
166
|
+
|
167
|
+
args = parser.parse_args()
|
168
|
+
|
169
|
+
# Если предоставлен файл конфигурации, загружаем его
|
170
|
+
if args.config:
|
171
|
+
try:
|
172
|
+
config = ClientConfig()
|
173
|
+
config.load_config_file(args.config)
|
174
|
+
return config
|
175
|
+
except Exception as e:
|
176
|
+
print(f"Ошибка загрузки файла конфигурации {args.config}: {e}")
|
177
|
+
sys.exit(1)
|
178
|
+
|
179
|
+
# Иначе строим конфигурацию из аргументов и переменных окружения
|
180
|
+
base_url = args.base_url or os.environ.get("EMBED_CLIENT_BASE_URL", "http://localhost")
|
181
|
+
port = args.port or int(os.environ.get("EMBED_CLIENT_PORT", "8001"))
|
182
|
+
|
50
183
|
if not base_url or not port:
|
51
|
-
print("
|
184
|
+
print("Ошибка: base_url и port должны быть предоставлены через аргументы --base-url/--port или переменные окружения EMBED_CLIENT_BASE_URL/EMBED_CLIENT_PORT.")
|
52
185
|
sys.exit(1)
|
53
|
-
|
54
|
-
|
186
|
+
|
187
|
+
# Строим словарь конфигурации
|
188
|
+
config_dict = {
|
189
|
+
"server": {
|
190
|
+
"host": base_url,
|
191
|
+
"port": port
|
192
|
+
},
|
193
|
+
"client": {
|
194
|
+
"timeout": args.timeout
|
195
|
+
},
|
196
|
+
"auth": {
|
197
|
+
"method": args.auth_method
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
# Добавляем конфигурацию аутентификации
|
202
|
+
if args.auth_method == "api_key":
|
203
|
+
api_key = args.api_key or os.environ.get("EMBED_CLIENT_API_KEY")
|
204
|
+
if api_key:
|
205
|
+
config_dict["auth"]["api_keys"] = {"user": api_key}
|
206
|
+
else:
|
207
|
+
print("Предупреждение: API ключ не предоставлен для аутентификации api_key")
|
208
|
+
|
209
|
+
elif args.auth_method == "jwt":
|
210
|
+
jwt_secret = args.jwt_secret or os.environ.get("EMBED_CLIENT_JWT_SECRET")
|
211
|
+
jwt_username = args.jwt_username or os.environ.get("EMBED_CLIENT_JWT_USERNAME")
|
212
|
+
jwt_password = args.jwt_password or os.environ.get("EMBED_CLIENT_JWT_PASSWORD")
|
213
|
+
|
214
|
+
if jwt_secret and jwt_username and jwt_password:
|
215
|
+
config_dict["auth"]["jwt"] = {
|
216
|
+
"secret": jwt_secret,
|
217
|
+
"username": jwt_username,
|
218
|
+
"password": jwt_password
|
219
|
+
}
|
220
|
+
else:
|
221
|
+
print("Предупреждение: JWT учетные данные не полностью предоставлены")
|
222
|
+
|
223
|
+
elif args.auth_method == "basic":
|
224
|
+
username = args.username or os.environ.get("EMBED_CLIENT_USERNAME")
|
225
|
+
password = args.password or os.environ.get("EMBED_CLIENT_PASSWORD")
|
226
|
+
|
227
|
+
if username and password:
|
228
|
+
config_dict["auth"]["basic"] = {
|
229
|
+
"username": username,
|
230
|
+
"password": password
|
231
|
+
}
|
232
|
+
else:
|
233
|
+
print("Предупреждение: Учетные данные базовой аутентификации не полностью предоставлены")
|
234
|
+
|
235
|
+
elif args.auth_method == "certificate":
|
236
|
+
cert_file = args.cert_file or os.environ.get("EMBED_CLIENT_CERT_FILE")
|
237
|
+
key_file = args.key_file or os.environ.get("EMBED_CLIENT_KEY_FILE")
|
238
|
+
|
239
|
+
if cert_file and key_file:
|
240
|
+
config_dict["auth"]["certificate"] = {
|
241
|
+
"cert_file": cert_file,
|
242
|
+
"key_file": key_file
|
243
|
+
}
|
244
|
+
else:
|
245
|
+
print("Предупреждение: Файлы сертификатов не полностью предоставлены")
|
246
|
+
|
247
|
+
# Добавляем конфигурацию SSL если используется HTTPS или предоставлены SSL параметры
|
248
|
+
if base_url.startswith("https://") or args.ssl_verify_mode != "CERT_REQUIRED" or args.ca_cert_file:
|
249
|
+
config_dict["ssl"] = {
|
250
|
+
"enabled": True,
|
251
|
+
"verify_mode": args.ssl_verify_mode,
|
252
|
+
"check_hostname": args.ssl_check_hostname,
|
253
|
+
"check_expiry": args.ssl_check_expiry
|
254
|
+
}
|
255
|
+
|
256
|
+
if args.ca_cert_file:
|
257
|
+
config_dict["ssl"]["ca_cert_file"] = args.ca_cert_file
|
258
|
+
|
259
|
+
# Добавляем клиентские сертификаты для mTLS
|
260
|
+
if args.cert_file:
|
261
|
+
config_dict["ssl"]["cert_file"] = args.cert_file
|
262
|
+
if args.key_file:
|
263
|
+
config_dict["ssl"]["key_file"] = args.key_file
|
264
|
+
|
265
|
+
# Добавляем контроль доступа на основе ролей для mTLS + Roles
|
266
|
+
if args.roles:
|
267
|
+
roles = [role.strip() for role in args.roles.split(",")]
|
268
|
+
config_dict["roles"] = roles
|
269
|
+
|
270
|
+
if args.role_attributes:
|
271
|
+
try:
|
272
|
+
role_attributes = json.loads(args.role_attributes)
|
273
|
+
config_dict["role_attributes"] = role_attributes
|
274
|
+
except json.JSONDecodeError:
|
275
|
+
print("Предупреждение: Неверный JSON в role_attributes")
|
276
|
+
|
277
|
+
return config_dict
|
278
|
+
|
279
|
+
|
280
|
+
def extract_embeddings(result):
|
281
|
+
"""Извлечение эмбеддингов из ответа API, поддерживая старый и новый форматы."""
|
282
|
+
# Обработка прямого поля embeddings (совместимость со старым форматом)
|
283
|
+
if "embeddings" in result:
|
284
|
+
return result["embeddings"]
|
285
|
+
|
286
|
+
# Обработка обертки result
|
287
|
+
if "result" in result:
|
288
|
+
res = result["result"]
|
289
|
+
|
290
|
+
# Обработка прямого списка в result (старый формат)
|
291
|
+
if isinstance(res, list):
|
292
|
+
return res
|
293
|
+
|
294
|
+
if isinstance(res, dict):
|
295
|
+
# Обработка старого формата: result.embeddings
|
296
|
+
if "embeddings" in res:
|
297
|
+
return res["embeddings"]
|
298
|
+
|
299
|
+
# Обработка старого формата: result.data.embeddings
|
300
|
+
if "data" in res and isinstance(res["data"], dict) and "embeddings" in res["data"]:
|
301
|
+
return res["data"]["embeddings"]
|
302
|
+
|
303
|
+
# Обработка нового формата: result.data[].embedding
|
304
|
+
if "data" in res and isinstance(res["data"], list):
|
305
|
+
embeddings = []
|
306
|
+
for item in res["data"]:
|
307
|
+
if isinstance(item, dict) and "embedding" in item:
|
308
|
+
embeddings.append(item["embedding"])
|
309
|
+
else:
|
310
|
+
raise ValueError(f"Неверный формат элемента в новом ответе API: {item}")
|
311
|
+
return embeddings
|
312
|
+
|
313
|
+
raise ValueError(f"Не удается извлечь эмбеддинги из ответа: {result}")
|
314
|
+
|
315
|
+
|
316
|
+
async def run_client_examples(client):
|
317
|
+
"""Запуск примеров операций с клиентом."""
|
318
|
+
# Проверка здоровья
|
319
|
+
try:
|
320
|
+
health = await client.health()
|
321
|
+
print("Состояние сервиса:", health)
|
322
|
+
except EmbeddingServiceError as e:
|
323
|
+
print(f"Ошибка при проверке здоровья: {e}")
|
324
|
+
return
|
325
|
+
|
326
|
+
# Получение схемы OpenAPI
|
327
|
+
try:
|
328
|
+
schema = await client.get_openapi_schema()
|
329
|
+
print(f"Версия схемы OpenAPI: {schema.get('info', {}).get('version', 'неизвестно')}")
|
330
|
+
except EmbeddingServiceError as e:
|
331
|
+
print(f"Ошибка получения схемы OpenAPI: {e}")
|
332
|
+
|
333
|
+
# Получение доступных команд
|
334
|
+
try:
|
335
|
+
commands = await client.get_commands()
|
336
|
+
print(f"Доступные команды: {commands}")
|
337
|
+
except EmbeddingServiceError as e:
|
338
|
+
print(f"Ошибка получения команд: {e}")
|
339
|
+
|
340
|
+
# Тест генерации эмбеддингов
|
341
|
+
try:
|
342
|
+
texts = ["Привет, мир!", "Это тестовое предложение.", "Сервис эмбеддингов работает!"]
|
343
|
+
result = await client.cmd("embed", {"texts": texts})
|
344
|
+
|
345
|
+
if result.get("success"):
|
346
|
+
embeddings = extract_embeddings(result)
|
347
|
+
print(f"Сгенерировано {len(embeddings)} эмбеддингов")
|
348
|
+
print(f"Размерность первого эмбеддинга: {len(embeddings[0]) if embeddings else 0}")
|
349
|
+
else:
|
350
|
+
print(f"Генерация эмбеддингов не удалась: {result.get('error', 'Неизвестная ошибка')}")
|
351
|
+
except EmbeddingServiceError as e:
|
352
|
+
print(f"Ошибка при генерации эмбеддингов: {e}")
|
353
|
+
|
354
|
+
|
355
|
+
async def demonstrate_security_modes():
|
356
|
+
"""Демонстрация всех режимов безопасности с использованием ClientFactory."""
|
357
|
+
print("=== Демонстрация режимов безопасности ===")
|
358
|
+
|
359
|
+
# 1. HTTP режим
|
360
|
+
print("\n1. HTTP режим (без аутентификации, без SSL):")
|
361
|
+
try:
|
362
|
+
client = ClientFactory.create_http_client("http://localhost", 8001)
|
363
|
+
print(f" Создан HTTP клиент: {client.base_url}:{client.port}")
|
364
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
365
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
366
|
+
await client.close()
|
367
|
+
except Exception as e:
|
368
|
+
print(f" Ошибка: {e}")
|
369
|
+
|
370
|
+
# 2. HTTP + Token режим
|
371
|
+
print("\n2. HTTP + Token режим (HTTP с API ключом):")
|
372
|
+
try:
|
373
|
+
client = ClientFactory.create_http_token_client(
|
374
|
+
"http://localhost", 8001, "api_key", api_key="demo_key"
|
375
|
+
)
|
376
|
+
print(f" Создан HTTP + Token клиент: {client.base_url}:{client.port}")
|
377
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
378
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
379
|
+
print(f" Метод аутентификации: {client.get_auth_method()}")
|
380
|
+
await client.close()
|
381
|
+
except Exception as e:
|
382
|
+
print(f" Ошибка: {e}")
|
383
|
+
|
384
|
+
# 3. HTTPS режим
|
385
|
+
print("\n3. HTTPS режим (HTTPS с сертификатами сервера):")
|
386
|
+
try:
|
387
|
+
client = ClientFactory.create_https_client("https://localhost", 9443)
|
388
|
+
print(f" Создан HTTPS клиент: {client.base_url}:{client.port}")
|
389
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
390
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
391
|
+
if client.is_ssl_enabled():
|
392
|
+
ssl_config = client.get_ssl_config()
|
393
|
+
print(f" SSL конфигурация: {ssl_config}")
|
394
|
+
await client.close()
|
395
|
+
except Exception as e:
|
396
|
+
print(f" Ошибка: {e}")
|
397
|
+
|
398
|
+
# 4. HTTPS + Token режим
|
399
|
+
print("\n4. HTTPS + Token режим (HTTPS с сертификатами сервера + аутентификация):")
|
400
|
+
try:
|
401
|
+
client = ClientFactory.create_https_token_client(
|
402
|
+
"https://localhost", 9443, "basic", username="admin", password="secret"
|
403
|
+
)
|
404
|
+
print(f" Создан HTTPS + Token клиент: {client.base_url}:{client.port}")
|
405
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
406
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
407
|
+
print(f" Метод аутентификации: {client.get_auth_method()}")
|
408
|
+
await client.close()
|
409
|
+
except Exception as e:
|
410
|
+
print(f" Ошибка: {e}")
|
411
|
+
|
412
|
+
# 5. mTLS режим
|
413
|
+
print("\n5. mTLS режим (взаимная TLS с сертификатами клиента и сервера):")
|
414
|
+
try:
|
415
|
+
client = ClientFactory.create_mtls_client(
|
416
|
+
"https://localhost", "mtls_certificates/client/embedding-service.crt", "mtls_certificates/client/embedding-service.key", 8443
|
417
|
+
)
|
418
|
+
print(f" Создан mTLS клиент: {client.base_url}:{client.port}")
|
419
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
420
|
+
print(f" mTLS включен: {client.is_mtls_enabled()}")
|
421
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
422
|
+
await client.close()
|
423
|
+
except Exception as e:
|
424
|
+
print(f" Ошибка: {e}")
|
425
|
+
|
426
|
+
# 6. mTLS + Roles режим
|
427
|
+
print("\n6. mTLS + Roles режим (mTLS с контролем доступа на основе ролей):")
|
428
|
+
try:
|
429
|
+
client = ClientFactory.create_mtls_roles_client(
|
430
|
+
"https://localhost", "client_cert.pem", "client_key.pem", 9443,
|
431
|
+
roles=["admin", "user"], role_attributes={"department": "IT"}
|
432
|
+
)
|
433
|
+
print(f" Создан mTLS + Roles клиент: {client.base_url}:{client.port}")
|
434
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
435
|
+
print(f" mTLS включен: {client.is_mtls_enabled()}")
|
436
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
437
|
+
await client.close()
|
438
|
+
except Exception as e:
|
439
|
+
print(f" Ошибка: {e}")
|
440
|
+
|
441
|
+
|
442
|
+
async def demonstrate_automatic_detection():
|
443
|
+
"""Демонстрация автоматического определения режима безопасности."""
|
444
|
+
print("\n=== Автоматическое определение режима безопасности ===")
|
445
|
+
|
446
|
+
test_cases = [
|
447
|
+
("http://localhost", None, None, None, None, "HTTP"),
|
448
|
+
("http://localhost", "api_key", None, None, None, "HTTP + Token"),
|
449
|
+
("https://localhost", None, None, None, None, "HTTPS"),
|
450
|
+
("https://localhost", "api_key", None, None, None, "HTTPS + Token"),
|
451
|
+
("https://localhost", None, None, "cert.pem", "key.pem", "mTLS"),
|
452
|
+
("https://localhost", None, None, "cert.pem", "key.pem", "mTLS + Roles", {"roles": ["admin"]}),
|
453
|
+
]
|
454
|
+
|
455
|
+
for case in test_cases:
|
456
|
+
if len(case) == 6:
|
457
|
+
base_url, auth_method, ssl_enabled, cert_file, key_file, expected = case
|
458
|
+
kwargs = {}
|
459
|
+
else:
|
460
|
+
base_url, auth_method, ssl_enabled, cert_file, key_file, expected, kwargs = case
|
461
|
+
|
462
|
+
try:
|
463
|
+
mode = detect_security_mode(base_url, auth_method, ssl_enabled, cert_file, key_file, **kwargs)
|
464
|
+
print(f" {base_url} + {auth_method or 'none'} + {cert_file or 'no cert'} -> {mode} ({expected})")
|
465
|
+
except Exception as e:
|
466
|
+
print(f" Ошибка определения режима для {base_url}: {e}")
|
467
|
+
|
55
468
|
|
56
469
|
async def main():
|
57
|
-
base_url, port = get_params()
|
58
|
-
# Always use try/except to handle all possible errors
|
59
470
|
try:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
471
|
+
config = get_params()
|
472
|
+
|
473
|
+
# Проверяем, запрошен ли демо режим
|
474
|
+
if hasattr(config, 'demo_mode') and config.demo_mode:
|
475
|
+
await demonstrate_security_modes()
|
476
|
+
await demonstrate_automatic_detection()
|
477
|
+
return
|
478
|
+
|
479
|
+
# Создаем клиент на основе режима фабрики
|
480
|
+
if isinstance(config, ClientConfig):
|
481
|
+
# Использование объекта конфигурации
|
482
|
+
client = EmbeddingServiceAsyncClient.from_config(config)
|
483
|
+
else:
|
484
|
+
# Использование словаря конфигурации
|
485
|
+
factory_mode = getattr(config, 'factory_mode', 'auto')
|
486
|
+
|
487
|
+
if factory_mode == "auto":
|
488
|
+
# Автоматическое определение
|
489
|
+
client = create_client(
|
490
|
+
config["server"]["host"],
|
491
|
+
config["server"]["port"],
|
492
|
+
auth_method=config["auth"]["method"],
|
493
|
+
**{k: v for k, v in config.items() if k not in ["server", "auth", "ssl", "client"]}
|
494
|
+
)
|
495
|
+
else:
|
496
|
+
# Конкретный метод фабрики
|
497
|
+
base_url = config["server"]["host"]
|
498
|
+
port = config["server"]["port"]
|
499
|
+
auth_method = config["auth"]["method"]
|
84
500
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
501
|
+
if factory_mode == "http":
|
502
|
+
client = ClientFactory.create_http_client(base_url, port)
|
503
|
+
elif factory_mode == "http_token":
|
504
|
+
client = ClientFactory.create_http_token_client(base_url, port, auth_method, **config.get("auth", {}))
|
505
|
+
elif factory_mode == "https":
|
506
|
+
client = ClientFactory.create_https_client(base_url, port)
|
507
|
+
elif factory_mode == "https_token":
|
508
|
+
client = ClientFactory.create_https_token_client(base_url, port, auth_method, **config.get("auth", {}))
|
509
|
+
elif factory_mode == "mtls":
|
510
|
+
cert_file = config.get("ssl", {}).get("cert_file", "client_cert.pem")
|
511
|
+
key_file = config.get("ssl", {}).get("key_file", "client_key.pem")
|
512
|
+
client = ClientFactory.create_mtls_client(base_url, cert_file, key_file, port)
|
513
|
+
elif factory_mode == "mtls_roles":
|
514
|
+
cert_file = config.get("ssl", {}).get("cert_file", "client_cert.pem")
|
515
|
+
key_file = config.get("ssl", {}).get("key_file", "client_key.pem")
|
516
|
+
roles = config.get("roles", ["admin"])
|
517
|
+
role_attributes = config.get("role_attributes", {})
|
518
|
+
client = ClientFactory.create_mtls_roles_client(
|
519
|
+
base_url, cert_file, key_file, port, roles, role_attributes
|
520
|
+
)
|
521
|
+
else:
|
522
|
+
client = EmbeddingServiceAsyncClient(config_dict=config)
|
523
|
+
|
524
|
+
print(f"Конфигурация клиента:")
|
525
|
+
print(f" Базовый URL: {client.base_url}")
|
526
|
+
print(f" Порт: {client.port}")
|
527
|
+
print(f" Аутентификация: {client.get_auth_method()}")
|
528
|
+
print(f" Аутентифицирован: {client.is_authenticated()}")
|
529
|
+
if client.is_authenticated():
|
530
|
+
headers = client.get_auth_headers()
|
531
|
+
print(f" Заголовки аутентификации: {headers}")
|
532
|
+
print(f" SSL включен: {client.is_ssl_enabled()}")
|
533
|
+
print(f" mTLS включен: {client.is_mtls_enabled()}")
|
534
|
+
if client.is_ssl_enabled():
|
535
|
+
ssl_config = client.get_ssl_config()
|
536
|
+
print(f" SSL конфигурация: {ssl_config}")
|
537
|
+
protocols = client.get_supported_ssl_protocols()
|
538
|
+
print(f" Поддерживаемые SSL протоколы: {protocols}")
|
539
|
+
print()
|
540
|
+
|
541
|
+
# Пример явного открытия/закрытия
|
542
|
+
print("Пример явного открытия/закрытия сессии:")
|
543
|
+
await client.close()
|
544
|
+
print("Сессия закрыта явно (пример ручного закрытия).\n")
|
545
|
+
|
546
|
+
# Использование контекстного менеджера
|
547
|
+
if isinstance(config, ClientConfig):
|
548
|
+
async with EmbeddingServiceAsyncClient.from_config(config) as client:
|
549
|
+
await run_client_examples(client)
|
550
|
+
else:
|
551
|
+
async with EmbeddingServiceAsyncClient(config_dict=config) as client:
|
552
|
+
await run_client_examples(client)
|
123
553
|
|
554
|
+
except EmbeddingServiceConfigError as e:
|
555
|
+
print(f"Ошибка конфигурации: {e}")
|
556
|
+
sys.exit(1)
|
124
557
|
except Exception as e:
|
125
|
-
print("
|
558
|
+
print(f"Неожиданная ошибка: {e}")
|
559
|
+
sys.exit(1)
|
126
560
|
|
127
561
|
if __name__ == "__main__":
|
128
|
-
asyncio.run(main())
|
562
|
+
asyncio.run(main())
|