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.
- embed_client/async_client.py +376 -16
- embed_client/auth.py +487 -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 +442 -100
- embed_client/ssl_examples.py +329 -0
- embed_client/ssl_manager.py +466 -0
- embed_client-3.1.0.0.dist-info/METADATA +229 -0
- embed_client-3.1.0.0.dist-info/RECORD +16 -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.0.dist-info}/WHEEL +0 -0
- {embed_client-2.0.0.0.dist-info → embed_client-3.1.0.0.dist-info}/top_level.txt +0 -0
embed_client/config.py
ADDED
@@ -0,0 +1,592 @@
|
|
1
|
+
"""
|
2
|
+
Client configuration management module.
|
3
|
+
|
4
|
+
This module provides configuration management for the embed-client,
|
5
|
+
supporting all security modes and authentication methods.
|
6
|
+
|
7
|
+
Author: Vasiliy Zdanovskiy
|
8
|
+
email: vasilyvz@gmail.com
|
9
|
+
"""
|
10
|
+
|
11
|
+
import json
|
12
|
+
import os
|
13
|
+
from typing import Any, Dict, Optional, List, Union
|
14
|
+
from pathlib import Path
|
15
|
+
|
16
|
+
|
17
|
+
class ClientConfig:
|
18
|
+
"""
|
19
|
+
Configuration management class for the embed-client.
|
20
|
+
Allows loading settings from configuration file and environment variables.
|
21
|
+
Supports all security modes and authentication methods.
|
22
|
+
"""
|
23
|
+
|
24
|
+
def __init__(self, config_path: Optional[str] = None):
|
25
|
+
"""
|
26
|
+
Initialize client configuration.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
config_path: Path to configuration file. If not specified,
|
30
|
+
"./config.json" is used.
|
31
|
+
"""
|
32
|
+
self.config_path = config_path or "./config.json"
|
33
|
+
self.config_data: Dict[str, Any] = {}
|
34
|
+
self.load_config()
|
35
|
+
|
36
|
+
def load_config(self) -> None:
|
37
|
+
"""
|
38
|
+
Load configuration from file and environment variables.
|
39
|
+
"""
|
40
|
+
# Set default config values
|
41
|
+
self.config_data = {
|
42
|
+
"server": {
|
43
|
+
"host": "localhost",
|
44
|
+
"port": 8001,
|
45
|
+
"base_url": "http://localhost:8001"
|
46
|
+
},
|
47
|
+
"timeout": 30,
|
48
|
+
"retry_attempts": 3,
|
49
|
+
"retry_delay": 1,
|
50
|
+
"auth": {
|
51
|
+
"method": "none", # none, api_key, jwt, certificate, basic
|
52
|
+
"api_key": {
|
53
|
+
"key": None,
|
54
|
+
"header": "X-API-Key"
|
55
|
+
},
|
56
|
+
"jwt": {
|
57
|
+
"username": None,
|
58
|
+
"password": None,
|
59
|
+
"secret": None,
|
60
|
+
"expiry_hours": 24
|
61
|
+
},
|
62
|
+
"certificate": {
|
63
|
+
"enabled": False,
|
64
|
+
"cert_file": None,
|
65
|
+
"key_file": None,
|
66
|
+
"ca_cert_file": None
|
67
|
+
},
|
68
|
+
"basic": {
|
69
|
+
"username": None,
|
70
|
+
"password": None
|
71
|
+
}
|
72
|
+
},
|
73
|
+
"ssl": {
|
74
|
+
"enabled": False,
|
75
|
+
"verify": True,
|
76
|
+
"check_hostname": True,
|
77
|
+
"cert_file": None,
|
78
|
+
"key_file": None,
|
79
|
+
"ca_cert_file": None,
|
80
|
+
"client_cert_required": False
|
81
|
+
},
|
82
|
+
"security": {
|
83
|
+
"enabled": False,
|
84
|
+
"roles_enabled": False,
|
85
|
+
"roles_file": None
|
86
|
+
},
|
87
|
+
"logging": {
|
88
|
+
"enabled": False,
|
89
|
+
"level": "INFO",
|
90
|
+
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
# Try to load configuration from file
|
95
|
+
if os.path.exists(self.config_path):
|
96
|
+
try:
|
97
|
+
with open(self.config_path, 'r', encoding='utf-8') as f:
|
98
|
+
file_config = json.load(f)
|
99
|
+
self._update_nested_dict(self.config_data, file_config)
|
100
|
+
except Exception as e:
|
101
|
+
print(f"Error loading config from {self.config_path}: {e}")
|
102
|
+
|
103
|
+
# Load configuration from environment variables
|
104
|
+
self._load_env_variables()
|
105
|
+
|
106
|
+
def load_from_file(self, config_path: str) -> None:
|
107
|
+
"""
|
108
|
+
Load configuration from the specified file.
|
109
|
+
|
110
|
+
Args:
|
111
|
+
config_path: Path to configuration file.
|
112
|
+
"""
|
113
|
+
self.config_path = config_path
|
114
|
+
self.load_config()
|
115
|
+
|
116
|
+
def _load_env_variables(self) -> None:
|
117
|
+
"""
|
118
|
+
Load configuration from environment variables.
|
119
|
+
Environment variables should be in format EMBED_CLIENT_SECTION_KEY=value.
|
120
|
+
For example, EMBED_CLIENT_SERVER_PORT=8080.
|
121
|
+
"""
|
122
|
+
prefix = "EMBED_CLIENT_"
|
123
|
+
for key, value in os.environ.items():
|
124
|
+
if key.startswith(prefix):
|
125
|
+
parts = key[len(prefix):].lower().split("_", 1)
|
126
|
+
if len(parts) == 2:
|
127
|
+
section, param = parts
|
128
|
+
if section not in self.config_data:
|
129
|
+
self.config_data[section] = {}
|
130
|
+
self.config_data[section][param] = self._convert_env_value(value)
|
131
|
+
|
132
|
+
def _convert_env_value(self, value: str) -> Any:
|
133
|
+
"""
|
134
|
+
Convert environment variable value to appropriate type.
|
135
|
+
|
136
|
+
Args:
|
137
|
+
value: Value as string
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
Converted value
|
141
|
+
"""
|
142
|
+
# Try to convert to appropriate type
|
143
|
+
if value.lower() == "true":
|
144
|
+
return True
|
145
|
+
elif value.lower() == "false":
|
146
|
+
return False
|
147
|
+
elif value.isdigit():
|
148
|
+
return int(value)
|
149
|
+
else:
|
150
|
+
try:
|
151
|
+
return float(value)
|
152
|
+
except ValueError:
|
153
|
+
return value
|
154
|
+
|
155
|
+
def get(self, key: str, default: Any = None) -> Any:
|
156
|
+
"""
|
157
|
+
Get configuration value for key.
|
158
|
+
|
159
|
+
Args:
|
160
|
+
key: Configuration key in format "section.param"
|
161
|
+
default: Default value if key not found
|
162
|
+
|
163
|
+
Returns:
|
164
|
+
Configuration value
|
165
|
+
"""
|
166
|
+
parts = key.split(".")
|
167
|
+
|
168
|
+
# Get value from config
|
169
|
+
value = self.config_data
|
170
|
+
for part in parts:
|
171
|
+
if not isinstance(value, dict) or part not in value:
|
172
|
+
return default
|
173
|
+
value = value[part]
|
174
|
+
|
175
|
+
return value
|
176
|
+
|
177
|
+
def get_all(self) -> Dict[str, Any]:
|
178
|
+
"""
|
179
|
+
Get all configuration values.
|
180
|
+
|
181
|
+
Returns:
|
182
|
+
Dictionary with all configuration values
|
183
|
+
"""
|
184
|
+
return self.config_data.copy()
|
185
|
+
|
186
|
+
def set(self, key: str, value: Any) -> None:
|
187
|
+
"""
|
188
|
+
Set configuration value for key.
|
189
|
+
|
190
|
+
Args:
|
191
|
+
key: Configuration key in format "section.param"
|
192
|
+
value: Configuration value
|
193
|
+
"""
|
194
|
+
parts = key.split(".")
|
195
|
+
if len(parts) == 1:
|
196
|
+
self.config_data[key] = value
|
197
|
+
else:
|
198
|
+
section = parts[0]
|
199
|
+
param_key = ".".join(parts[1:])
|
200
|
+
|
201
|
+
if section not in self.config_data:
|
202
|
+
self.config_data[section] = {}
|
203
|
+
|
204
|
+
current = self.config_data[section]
|
205
|
+
for part in parts[1:-1]:
|
206
|
+
if part not in current:
|
207
|
+
current[part] = {}
|
208
|
+
current = current[part]
|
209
|
+
|
210
|
+
current[parts[-1]] = value
|
211
|
+
|
212
|
+
def save(self, path: Optional[str] = None) -> None:
|
213
|
+
"""
|
214
|
+
Save configuration to file.
|
215
|
+
|
216
|
+
Args:
|
217
|
+
path: Path to configuration file. If not specified,
|
218
|
+
self.config_path is used.
|
219
|
+
"""
|
220
|
+
save_path = path or self.config_path
|
221
|
+
with open(save_path, 'w', encoding='utf-8') as f:
|
222
|
+
json.dump(self.config_data, f, indent=2)
|
223
|
+
|
224
|
+
def _update_nested_dict(self, d: Dict, u: Dict) -> Dict:
|
225
|
+
"""
|
226
|
+
Update nested dictionary recursively.
|
227
|
+
|
228
|
+
Args:
|
229
|
+
d: Dictionary to update
|
230
|
+
u: Dictionary with new values
|
231
|
+
|
232
|
+
Returns:
|
233
|
+
Updated dictionary
|
234
|
+
"""
|
235
|
+
for k, v in u.items():
|
236
|
+
if isinstance(v, dict) and k in d and isinstance(d[k], dict):
|
237
|
+
self._update_nested_dict(d[k], v)
|
238
|
+
else:
|
239
|
+
d[k] = v
|
240
|
+
return d
|
241
|
+
|
242
|
+
def configure_auth_mode(self, mode: str, **kwargs) -> None:
|
243
|
+
"""
|
244
|
+
Configure authentication mode.
|
245
|
+
|
246
|
+
Args:
|
247
|
+
mode: Authentication mode (none, api_key, jwt, certificate, basic)
|
248
|
+
**kwargs: Additional configuration parameters
|
249
|
+
"""
|
250
|
+
self.set("auth.method", mode)
|
251
|
+
|
252
|
+
if mode == "api_key":
|
253
|
+
if "key" in kwargs:
|
254
|
+
self.set("auth.api_key.key", kwargs["key"])
|
255
|
+
if "header" in kwargs:
|
256
|
+
self.set("auth.api_key.header", kwargs["header"])
|
257
|
+
elif mode == "jwt":
|
258
|
+
if "username" in kwargs:
|
259
|
+
self.set("auth.jwt.username", kwargs["username"])
|
260
|
+
if "password" in kwargs:
|
261
|
+
self.set("auth.jwt.password", kwargs["password"])
|
262
|
+
if "secret" in kwargs:
|
263
|
+
self.set("auth.jwt.secret", kwargs["secret"])
|
264
|
+
if "expiry_hours" in kwargs:
|
265
|
+
self.set("auth.jwt.expiry_hours", kwargs["expiry_hours"])
|
266
|
+
elif mode == "certificate":
|
267
|
+
self.set("auth.certificate.enabled", True)
|
268
|
+
if "cert_file" in kwargs:
|
269
|
+
self.set("auth.certificate.cert_file", kwargs["cert_file"])
|
270
|
+
if "key_file" in kwargs:
|
271
|
+
self.set("auth.certificate.key_file", kwargs["key_file"])
|
272
|
+
if "ca_cert_file" in kwargs:
|
273
|
+
self.set("auth.certificate.ca_cert_file", kwargs["ca_cert_file"])
|
274
|
+
elif mode == "basic":
|
275
|
+
if "username" in kwargs:
|
276
|
+
self.set("auth.basic.username", kwargs["username"])
|
277
|
+
if "password" in kwargs:
|
278
|
+
self.set("auth.basic.password", kwargs["password"])
|
279
|
+
|
280
|
+
def configure_ssl(self, enabled: bool = True, **kwargs) -> None:
|
281
|
+
"""
|
282
|
+
Configure SSL/TLS settings.
|
283
|
+
|
284
|
+
Args:
|
285
|
+
enabled: Enable SSL/TLS
|
286
|
+
**kwargs: Additional SSL configuration parameters
|
287
|
+
"""
|
288
|
+
self.set("ssl.enabled", enabled)
|
289
|
+
|
290
|
+
if "verify" in kwargs:
|
291
|
+
self.set("ssl.verify", kwargs["verify"])
|
292
|
+
if "check_hostname" in kwargs:
|
293
|
+
self.set("ssl.check_hostname", kwargs["check_hostname"])
|
294
|
+
if "cert_file" in kwargs:
|
295
|
+
self.set("ssl.cert_file", kwargs["cert_file"])
|
296
|
+
if "key_file" in kwargs:
|
297
|
+
self.set("ssl.key_file", kwargs["key_file"])
|
298
|
+
if "ca_cert_file" in kwargs:
|
299
|
+
self.set("ssl.ca_cert_file", kwargs["ca_cert_file"])
|
300
|
+
if "client_cert_required" in kwargs:
|
301
|
+
self.set("ssl.client_cert_required", kwargs["client_cert_required"])
|
302
|
+
|
303
|
+
def configure_server(self, host: str, port: int, base_url: Optional[str] = None) -> None:
|
304
|
+
"""
|
305
|
+
Configure server connection settings.
|
306
|
+
|
307
|
+
Args:
|
308
|
+
host: Server host
|
309
|
+
port: Server port
|
310
|
+
base_url: Full server URL (optional, will be constructed if not provided)
|
311
|
+
"""
|
312
|
+
self.set("server.host", host)
|
313
|
+
self.set("server.port", port)
|
314
|
+
|
315
|
+
if base_url:
|
316
|
+
self.set("server.base_url", base_url)
|
317
|
+
else:
|
318
|
+
protocol = "https" if self.get("ssl.enabled", False) else "http"
|
319
|
+
self.set("server.base_url", f"{protocol}://{host}:{port}")
|
320
|
+
|
321
|
+
def get_server_url(self) -> str:
|
322
|
+
"""
|
323
|
+
Get the complete server URL.
|
324
|
+
|
325
|
+
Returns:
|
326
|
+
Server URL string
|
327
|
+
"""
|
328
|
+
return self.get("server.base_url", "http://localhost:8001")
|
329
|
+
|
330
|
+
def get_auth_method(self) -> str:
|
331
|
+
"""
|
332
|
+
Get the authentication method.
|
333
|
+
|
334
|
+
Returns:
|
335
|
+
Authentication method string
|
336
|
+
"""
|
337
|
+
return self.get("auth.method", "none")
|
338
|
+
|
339
|
+
def is_ssl_enabled(self) -> bool:
|
340
|
+
"""
|
341
|
+
Check if SSL/TLS is enabled.
|
342
|
+
|
343
|
+
Returns:
|
344
|
+
True if SSL is enabled, False otherwise
|
345
|
+
"""
|
346
|
+
return self.get("ssl.enabled", False)
|
347
|
+
|
348
|
+
def is_auth_enabled(self) -> bool:
|
349
|
+
"""
|
350
|
+
Check if authentication is enabled.
|
351
|
+
|
352
|
+
Returns:
|
353
|
+
True if authentication is enabled, False otherwise
|
354
|
+
"""
|
355
|
+
return self.get("auth.method", "none") != "none"
|
356
|
+
|
357
|
+
def is_security_enabled(self) -> bool:
|
358
|
+
"""
|
359
|
+
Check if security features are enabled.
|
360
|
+
|
361
|
+
Returns:
|
362
|
+
True if security is enabled, False otherwise
|
363
|
+
"""
|
364
|
+
return self.get("security.enabled", False)
|
365
|
+
|
366
|
+
def validate_config(self) -> List[str]:
|
367
|
+
"""
|
368
|
+
Validate configuration and return list of errors.
|
369
|
+
|
370
|
+
Returns:
|
371
|
+
List of validation error messages
|
372
|
+
"""
|
373
|
+
errors = []
|
374
|
+
|
375
|
+
# Validate server configuration
|
376
|
+
host = self.get("server.host")
|
377
|
+
port = self.get("server.port")
|
378
|
+
if not host:
|
379
|
+
errors.append("Server host is required")
|
380
|
+
if not port or not isinstance(port, int) or port <= 0:
|
381
|
+
errors.append("Server port must be a positive integer")
|
382
|
+
|
383
|
+
# Validate authentication configuration
|
384
|
+
auth_method = self.get("auth.method", "none")
|
385
|
+
if auth_method == "api_key":
|
386
|
+
if not self.get("auth.api_key.key"):
|
387
|
+
errors.append("API key is required for api_key authentication")
|
388
|
+
elif auth_method == "jwt":
|
389
|
+
if not all([self.get("auth.jwt.username"),
|
390
|
+
self.get("auth.jwt.password"),
|
391
|
+
self.get("auth.jwt.secret")]):
|
392
|
+
errors.append("Username, password, and secret are required for JWT authentication")
|
393
|
+
elif auth_method == "certificate":
|
394
|
+
if not all([self.get("auth.certificate.cert_file"),
|
395
|
+
self.get("auth.certificate.key_file")]):
|
396
|
+
errors.append("Certificate and key files are required for certificate authentication")
|
397
|
+
elif auth_method == "basic":
|
398
|
+
if not all([self.get("auth.basic.username"),
|
399
|
+
self.get("auth.basic.password")]):
|
400
|
+
errors.append("Username and password are required for basic authentication")
|
401
|
+
|
402
|
+
# Validate SSL configuration
|
403
|
+
if self.get("ssl.enabled", False):
|
404
|
+
if self.get("ssl.cert_file") and not os.path.exists(self.get("ssl.cert_file")):
|
405
|
+
errors.append(f"SSL certificate file not found: {self.get('ssl.cert_file')}")
|
406
|
+
if self.get("ssl.key_file") and not os.path.exists(self.get("ssl.key_file")):
|
407
|
+
errors.append(f"SSL key file not found: {self.get('ssl.key_file')}")
|
408
|
+
if self.get("ssl.ca_cert_file") and not os.path.exists(self.get("ssl.ca_cert_file")):
|
409
|
+
errors.append(f"SSL CA certificate file not found: {self.get('ssl.ca_cert_file')}")
|
410
|
+
|
411
|
+
return errors
|
412
|
+
|
413
|
+
def create_minimal_config(self) -> Dict[str, Any]:
|
414
|
+
"""
|
415
|
+
Create minimal configuration with only essential features.
|
416
|
+
|
417
|
+
Returns:
|
418
|
+
Minimal configuration dictionary
|
419
|
+
"""
|
420
|
+
minimal_config = self.config_data.copy()
|
421
|
+
|
422
|
+
# Disable all optional features
|
423
|
+
minimal_config["ssl"]["enabled"] = False
|
424
|
+
minimal_config["security"]["enabled"] = False
|
425
|
+
minimal_config["auth"]["method"] = "none"
|
426
|
+
minimal_config["logging"]["enabled"] = False
|
427
|
+
|
428
|
+
return minimal_config
|
429
|
+
|
430
|
+
def create_secure_config(self) -> Dict[str, Any]:
|
431
|
+
"""
|
432
|
+
Create secure configuration with all security features enabled.
|
433
|
+
|
434
|
+
Returns:
|
435
|
+
Secure configuration dictionary
|
436
|
+
"""
|
437
|
+
secure_config = self.config_data.copy()
|
438
|
+
|
439
|
+
# Enable all security features
|
440
|
+
secure_config["ssl"]["enabled"] = True
|
441
|
+
secure_config["security"]["enabled"] = True
|
442
|
+
secure_config["auth"]["method"] = "certificate"
|
443
|
+
secure_config["ssl"]["verify"] = True
|
444
|
+
secure_config["ssl"]["check_hostname"] = True
|
445
|
+
secure_config["ssl"]["client_cert_required"] = True
|
446
|
+
|
447
|
+
return secure_config
|
448
|
+
|
449
|
+
@classmethod
|
450
|
+
def from_dict(cls, config_dict: Dict[str, Any]) -> 'ClientConfig':
|
451
|
+
"""
|
452
|
+
Create ClientConfig instance from dictionary.
|
453
|
+
|
454
|
+
Args:
|
455
|
+
config_dict: Configuration dictionary
|
456
|
+
|
457
|
+
Returns:
|
458
|
+
ClientConfig instance
|
459
|
+
"""
|
460
|
+
config = cls()
|
461
|
+
config.config_data = config._update_nested_dict(config.config_data, config_dict)
|
462
|
+
return config
|
463
|
+
|
464
|
+
@classmethod
|
465
|
+
def from_file(cls, config_path: str) -> 'ClientConfig':
|
466
|
+
"""
|
467
|
+
Create ClientConfig instance from file.
|
468
|
+
|
469
|
+
Args:
|
470
|
+
config_path: Path to configuration file
|
471
|
+
|
472
|
+
Returns:
|
473
|
+
ClientConfig instance
|
474
|
+
"""
|
475
|
+
config = cls(config_path)
|
476
|
+
return config
|
477
|
+
|
478
|
+
@classmethod
|
479
|
+
def create_http_config(cls, host: str = "localhost", port: int = 8001) -> 'ClientConfig':
|
480
|
+
"""
|
481
|
+
Create configuration for HTTP connection without authentication.
|
482
|
+
|
483
|
+
Args:
|
484
|
+
host: Server host
|
485
|
+
port: Server port
|
486
|
+
|
487
|
+
Returns:
|
488
|
+
ClientConfig instance
|
489
|
+
"""
|
490
|
+
config = cls()
|
491
|
+
config.configure_server(host, port)
|
492
|
+
config.configure_auth_mode("none")
|
493
|
+
config.configure_ssl(False)
|
494
|
+
return config
|
495
|
+
|
496
|
+
@classmethod
|
497
|
+
def create_http_token_config(cls, host: str = "localhost", port: int = 8001,
|
498
|
+
api_key: str = None) -> 'ClientConfig':
|
499
|
+
"""
|
500
|
+
Create configuration for HTTP connection with API key authentication.
|
501
|
+
|
502
|
+
Args:
|
503
|
+
host: Server host
|
504
|
+
port: Server port
|
505
|
+
api_key: API key for authentication
|
506
|
+
|
507
|
+
Returns:
|
508
|
+
ClientConfig instance
|
509
|
+
"""
|
510
|
+
config = cls()
|
511
|
+
config.configure_server(host, port)
|
512
|
+
config.configure_auth_mode("api_key", key=api_key)
|
513
|
+
config.configure_ssl(False)
|
514
|
+
return config
|
515
|
+
|
516
|
+
@classmethod
|
517
|
+
def create_https_config(cls, host: str = "localhost", port: int = 8443,
|
518
|
+
cert_file: str = None, key_file: str = None,
|
519
|
+
ca_cert_file: str = None) -> 'ClientConfig':
|
520
|
+
"""
|
521
|
+
Create configuration for HTTPS connection without authentication.
|
522
|
+
|
523
|
+
Args:
|
524
|
+
host: Server host
|
525
|
+
port: Server port
|
526
|
+
cert_file: Client certificate file
|
527
|
+
key_file: Client key file
|
528
|
+
ca_cert_file: CA certificate file
|
529
|
+
|
530
|
+
Returns:
|
531
|
+
ClientConfig instance
|
532
|
+
"""
|
533
|
+
config = cls()
|
534
|
+
config.configure_ssl(True, cert_file=cert_file, key_file=key_file,
|
535
|
+
ca_cert_file=ca_cert_file)
|
536
|
+
config.configure_server(host, port)
|
537
|
+
config.configure_auth_mode("none")
|
538
|
+
return config
|
539
|
+
|
540
|
+
@classmethod
|
541
|
+
def create_https_token_config(cls, host: str = "localhost", port: int = 8443,
|
542
|
+
api_key: str = None, cert_file: str = None,
|
543
|
+
key_file: str = None, ca_cert_file: str = None) -> 'ClientConfig':
|
544
|
+
"""
|
545
|
+
Create configuration for HTTPS connection with API key authentication.
|
546
|
+
|
547
|
+
Args:
|
548
|
+
host: Server host
|
549
|
+
port: Server port
|
550
|
+
api_key: API key for authentication
|
551
|
+
cert_file: Client certificate file
|
552
|
+
key_file: Client key file
|
553
|
+
ca_cert_file: CA certificate file
|
554
|
+
|
555
|
+
Returns:
|
556
|
+
ClientConfig instance
|
557
|
+
"""
|
558
|
+
config = cls()
|
559
|
+
config.configure_ssl(True, cert_file=cert_file, key_file=key_file,
|
560
|
+
ca_cert_file=ca_cert_file)
|
561
|
+
config.configure_server(host, port)
|
562
|
+
config.configure_auth_mode("api_key", key=api_key)
|
563
|
+
return config
|
564
|
+
|
565
|
+
@classmethod
|
566
|
+
def create_mtls_config(cls, host: str = "localhost", port: int = 8443,
|
567
|
+
cert_file: str = None, key_file: str = None,
|
568
|
+
ca_cert_file: str = None) -> 'ClientConfig':
|
569
|
+
"""
|
570
|
+
Create configuration for mTLS connection with client certificates.
|
571
|
+
|
572
|
+
Args:
|
573
|
+
host: Server host
|
574
|
+
port: Server port
|
575
|
+
cert_file: Client certificate file
|
576
|
+
key_file: Client key file
|
577
|
+
ca_cert_file: CA certificate file
|
578
|
+
|
579
|
+
Returns:
|
580
|
+
ClientConfig instance
|
581
|
+
"""
|
582
|
+
config = cls()
|
583
|
+
config.configure_ssl(True, cert_file=cert_file, key_file=key_file,
|
584
|
+
ca_cert_file=ca_cert_file, client_cert_required=True)
|
585
|
+
config.configure_server(host, port)
|
586
|
+
config.configure_auth_mode("certificate", cert_file=cert_file,
|
587
|
+
key_file=key_file, ca_cert_file=ca_cert_file)
|
588
|
+
return config
|
589
|
+
|
590
|
+
|
591
|
+
# Singleton instance
|
592
|
+
config = ClientConfig()
|