embed-client-dev 4.0.78__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/__init__.py +36 -0
- embed_client/__main__.py +15 -0
- embed_client/_version.py +3 -0
- embed_client/adapter_config_factory.py +213 -0
- embed_client/adapter_config_normalizer.py +135 -0
- embed_client/adapter_generator_bridge.py +166 -0
- embed_client/auth.py +189 -0
- embed_client/cli.py +483 -0
- embed_client/cli_core.py +427 -0
- embed_client/client_factory.py +515 -0
- embed_client/client_factory_examples.py +375 -0
- embed_client/client_factory_helpers.py +59 -0
- embed_client/config.py +408 -0
- embed_client/config_defaults.py +77 -0
- embed_client/config_examples.py +228 -0
- embed_client/config_generator.py +652 -0
- embed_client/config_generator_cli.py +151 -0
- embed_client/config_presets.py +245 -0
- embed_client/config_validator.py +246 -0
- embed_client/config_validator_cli.py +141 -0
- embed_client/constants.py +52 -0
- embed_client/demo_cli.py +78 -0
- embed_client/demo_security_cli.py +206 -0
- embed_client/embed_file_output_validate.py +348 -0
- embed_client/embed_file_status_store.py +80 -0
- embed_client/embedding_client.py +1929 -0
- embed_client/embedding_client_helpers.py +105 -0
- embed_client/example_async_usage.py +357 -0
- embed_client/example_async_usage_demo.py +282 -0
- embed_client/example_async_usage_ru.py +340 -0
- embed_client/example_async_usage_ru_demo.py +313 -0
- embed_client/exceptions.py +122 -0
- embed_client/identifier_types.py +56 -0
- embed_client/json_embed_file_preflight.py +128 -0
- embed_client/local_json_embed_file.py +73 -0
- embed_client/md_embed_file_prep.py +197 -0
- embed_client/response_normalizer.py +160 -0
- embed_client/response_parsers.py +219 -0
- embed_client/security_cli.py +200 -0
- embed_client/security_cli_core.py +227 -0
- embed_client/ssl_examples.py +278 -0
- embed_client/ssl_manager.py +141 -0
- embed_client_dev-4.0.78.dist-info/METADATA +155 -0
- embed_client_dev-4.0.78.dist-info/RECORD +48 -0
- embed_client_dev-4.0.78.dist-info/WHEEL +5 -0
- embed_client_dev-4.0.78.dist-info/entry_points.txt +4 -0
- embed_client_dev-4.0.78.dist-info/licenses/LICENSE +21 -0
- embed_client_dev-4.0.78.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI entry point for the embed-client configuration validator.
|
|
3
|
+
|
|
4
|
+
This module provides the command-line interface for validating configuration
|
|
5
|
+
files using `ConfigValidator`.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from embed_client.config_validator import ConfigValidator
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main() -> int:
|
|
21
|
+
"""
|
|
22
|
+
CLI entry point for the configuration validator.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Exit code (0 for success, 1 for failure)
|
|
26
|
+
"""
|
|
27
|
+
parser = argparse.ArgumentParser(
|
|
28
|
+
description="Validate embed-client configuration files",
|
|
29
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
30
|
+
epilog="""
|
|
31
|
+
Examples:
|
|
32
|
+
# Validate a single config file
|
|
33
|
+
embed-config-validator --file configs/http.json
|
|
34
|
+
|
|
35
|
+
# Validate all configs in a directory
|
|
36
|
+
embed-config-validator --dir configs
|
|
37
|
+
|
|
38
|
+
# Validate and show detailed errors
|
|
39
|
+
embed-config-validator --file configs/mtls.json --verbose
|
|
40
|
+
""",
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"--file",
|
|
44
|
+
type=str,
|
|
45
|
+
help="Path to configuration file to validate",
|
|
46
|
+
)
|
|
47
|
+
parser.add_argument(
|
|
48
|
+
"--dir",
|
|
49
|
+
type=str,
|
|
50
|
+
help="Directory containing configuration files to validate",
|
|
51
|
+
)
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"--verbose",
|
|
54
|
+
action="store_true",
|
|
55
|
+
help="Show detailed error messages",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
args = parser.parse_args()
|
|
59
|
+
|
|
60
|
+
if not args.file and not args.dir:
|
|
61
|
+
parser.print_help()
|
|
62
|
+
return 1
|
|
63
|
+
|
|
64
|
+
validator = ConfigValidator()
|
|
65
|
+
|
|
66
|
+
if args.file:
|
|
67
|
+
# Validate single file
|
|
68
|
+
config_path = Path(args.file)
|
|
69
|
+
if not config_path.is_absolute():
|
|
70
|
+
config_path = Path.cwd() / config_path
|
|
71
|
+
|
|
72
|
+
print(f"š Validating: {config_path}")
|
|
73
|
+
is_valid, message, errors = validator.validate_config_file(config_path)
|
|
74
|
+
|
|
75
|
+
if is_valid:
|
|
76
|
+
print(f"ā
Configuration is valid: {message}")
|
|
77
|
+
return 0
|
|
78
|
+
else:
|
|
79
|
+
print(f"ā Configuration validation failed: {message}")
|
|
80
|
+
if errors and args.verbose:
|
|
81
|
+
print("\nErrors:")
|
|
82
|
+
for error in errors:
|
|
83
|
+
print(f" ⢠{error}")
|
|
84
|
+
elif errors:
|
|
85
|
+
print(f" Found {len(errors)} error(s). Use --verbose to see details.")
|
|
86
|
+
return 1
|
|
87
|
+
|
|
88
|
+
elif args.dir:
|
|
89
|
+
# Validate directory
|
|
90
|
+
config_dir = Path(args.dir)
|
|
91
|
+
if not config_dir.is_absolute():
|
|
92
|
+
config_dir = Path.cwd() / config_dir
|
|
93
|
+
|
|
94
|
+
if not config_dir.exists():
|
|
95
|
+
print(f"ā Directory not found: {config_dir}")
|
|
96
|
+
return 1
|
|
97
|
+
|
|
98
|
+
print(f"š Validating configurations in: {config_dir}")
|
|
99
|
+
print("=" * 70)
|
|
100
|
+
|
|
101
|
+
results = validator.validate_config_directory(config_dir)
|
|
102
|
+
|
|
103
|
+
if not results:
|
|
104
|
+
print("ā ļø No configuration files found")
|
|
105
|
+
return 1
|
|
106
|
+
|
|
107
|
+
all_valid = True
|
|
108
|
+
for config_name, (is_valid, message, errors) in results.items():
|
|
109
|
+
status = "ā
" if is_valid else "ā"
|
|
110
|
+
print(f"{status} {config_name:35s} - {message}")
|
|
111
|
+
|
|
112
|
+
if not is_valid:
|
|
113
|
+
all_valid = False
|
|
114
|
+
if errors and args.verbose:
|
|
115
|
+
for error in errors:
|
|
116
|
+
print(f" ā ļø {error}")
|
|
117
|
+
|
|
118
|
+
print("=" * 70)
|
|
119
|
+
|
|
120
|
+
if all_valid:
|
|
121
|
+
print(f"ā
All {len(results)} configuration files are valid!")
|
|
122
|
+
return 0
|
|
123
|
+
else:
|
|
124
|
+
failed = [
|
|
125
|
+
(name, errors)
|
|
126
|
+
for name, (valid, _, errors) in results.items()
|
|
127
|
+
if not valid
|
|
128
|
+
]
|
|
129
|
+
print(f"ā {len(failed)} configuration file(s) failed validation:")
|
|
130
|
+
for name, errors in failed:
|
|
131
|
+
print(f" - {name}")
|
|
132
|
+
if args.verbose and errors:
|
|
133
|
+
for error in errors:
|
|
134
|
+
print(f" ⢠{error}")
|
|
135
|
+
return 1
|
|
136
|
+
|
|
137
|
+
return 0
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
if __name__ == "__main__":
|
|
141
|
+
sys.exit(main())
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared constants for embed-client package (aligned with embedding service server).
|
|
3
|
+
|
|
4
|
+
Author: Vasiliy Zdanovskiy
|
|
5
|
+
email: vasilyvz@gmail.com
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
# Embed command (schema, default policy) ā matches server embed/constants.py
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
EMBED_COMMAND_SCHEMA_DEFAULT_ERROR_POLICY = "fail_fast"
|
|
15
|
+
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
# Environment variable names for embedding service connection
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
EMBEDDING_SERVICE_BASE_URL_ENV: str = "EMBEDDING_SERVICE_BASE_URL"
|
|
20
|
+
EMBEDDING_SERVICE_PORT_ENV: str = "EMBEDDING_SERVICE_PORT"
|
|
21
|
+
|
|
22
|
+
# Default connection settings
|
|
23
|
+
DEFAULT_BASE_URL: str = "http://localhost"
|
|
24
|
+
DEFAULT_PORT: int = 8001
|
|
25
|
+
|
|
26
|
+
# Default poll interval (seconds) when waiting for queued job completion
|
|
27
|
+
DEFAULT_POLL_INTERVAL: float = 0.3
|
|
28
|
+
|
|
29
|
+
# Max UTF-8 bytes per string item in local json_array preflight (override via
|
|
30
|
+
# EMBED_CLIENT_MAX_JSON_BLOCK_BYTES).
|
|
31
|
+
DEFAULT_MAX_JSON_EMBED_BLOCK_BYTES: int = 1_048_576
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_embed_project_root(module_file: Union[str, Path]) -> Path:
|
|
35
|
+
"""
|
|
36
|
+
Return project root (parent of parent of the given module file).
|
|
37
|
+
|
|
38
|
+
Use from main or CLI: ``get_embed_project_root(__file__)``.
|
|
39
|
+
"""
|
|
40
|
+
return Path(module_file).resolve().parent.parent
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
"EMBED_COMMAND_SCHEMA_DEFAULT_ERROR_POLICY",
|
|
45
|
+
"EMBEDDING_SERVICE_BASE_URL_ENV",
|
|
46
|
+
"EMBEDDING_SERVICE_PORT_ENV",
|
|
47
|
+
"DEFAULT_BASE_URL",
|
|
48
|
+
"DEFAULT_PORT",
|
|
49
|
+
"DEFAULT_POLL_INTERVAL",
|
|
50
|
+
"DEFAULT_MAX_JSON_EMBED_BLOCK_BYTES",
|
|
51
|
+
"get_embed_project_root",
|
|
52
|
+
]
|
embed_client/demo_cli.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Demo CLI Application for Text Vectorization
|
|
4
|
+
Simple demonstration of the CLI functionality.
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
# Add the project root to the path
|
|
15
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
16
|
+
|
|
17
|
+
from embed_client.cli import VectorizationCLI # noqa: E402
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def demo_vectorization():
|
|
21
|
+
"""Demonstrate vectorization functionality."""
|
|
22
|
+
print("š Embed-Client CLI Demo")
|
|
23
|
+
print("=" * 40)
|
|
24
|
+
|
|
25
|
+
# Configuration for demo
|
|
26
|
+
config = {
|
|
27
|
+
"server": {"host": "http://localhost", "port": 8001},
|
|
28
|
+
"auth": {"method": "none"},
|
|
29
|
+
"ssl": {"enabled": False},
|
|
30
|
+
"security": {"enabled": False},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
cli = VectorizationCLI()
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
# Connect to service
|
|
37
|
+
print("š Connecting to embedding service...")
|
|
38
|
+
if not await cli.connect(config):
|
|
39
|
+
print("ā Failed to connect to service")
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
# Health check
|
|
43
|
+
print("\nš„ Checking service health...")
|
|
44
|
+
await cli.health_check()
|
|
45
|
+
|
|
46
|
+
# Get help
|
|
47
|
+
print("\nā Getting help from service...")
|
|
48
|
+
await cli.get_help()
|
|
49
|
+
|
|
50
|
+
# Get commands
|
|
51
|
+
print("\nš Getting available commands...")
|
|
52
|
+
await cli.get_commands()
|
|
53
|
+
|
|
54
|
+
# Vectorize texts
|
|
55
|
+
print("\nš¤ Vectorizing texts...")
|
|
56
|
+
texts = ["Hello world", "This is a test", "Machine learning is awesome"]
|
|
57
|
+
|
|
58
|
+
print(f"š Vectorizing {len(texts)} texts:")
|
|
59
|
+
for i, text in enumerate(texts):
|
|
60
|
+
print(f" {i+1}. {text}")
|
|
61
|
+
|
|
62
|
+
await cli.vectorize_texts(texts, "json")
|
|
63
|
+
|
|
64
|
+
print("\nā
Demo completed successfully!")
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
print(f"ā Demo failed: {e}")
|
|
68
|
+
finally:
|
|
69
|
+
await cli.disconnect()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
async def main():
|
|
73
|
+
"""Main demo function."""
|
|
74
|
+
await demo_vectorization()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Demo Security CLI Application
|
|
4
|
+
Demonstrates all 8 security modes using the security CLI.
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
# Add the project root to the path
|
|
15
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
16
|
+
|
|
17
|
+
from embed_client.security_cli import ( # noqa: E402
|
|
18
|
+
SecurityCLI,
|
|
19
|
+
create_config_from_security_mode,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def demo_security_mode(mode: str, host: str, port: int, **kwargs):
|
|
24
|
+
"""Demonstrate a specific security mode."""
|
|
25
|
+
print(f"\nš Demonstrating {mode} mode...")
|
|
26
|
+
print("=" * 50)
|
|
27
|
+
|
|
28
|
+
# Create configuration
|
|
29
|
+
config = create_config_from_security_mode(mode, host, port, **kwargs)
|
|
30
|
+
|
|
31
|
+
cli = SecurityCLI()
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
# Connect to service
|
|
35
|
+
print(f"š Connecting using {mode} mode...")
|
|
36
|
+
if not await cli.connect(config):
|
|
37
|
+
print(f"ā Failed to connect using {mode} mode")
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
# Health check
|
|
41
|
+
print("š„ Checking service health...")
|
|
42
|
+
health_ok = await cli.health_check()
|
|
43
|
+
if not health_ok:
|
|
44
|
+
print(f"ā Health check failed for {mode} mode")
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
# Get help
|
|
48
|
+
print("ā Getting help from service...")
|
|
49
|
+
await cli.get_help()
|
|
50
|
+
|
|
51
|
+
# Get commands
|
|
52
|
+
print("š Getting available commands...")
|
|
53
|
+
await cli.get_commands()
|
|
54
|
+
|
|
55
|
+
# Vectorize texts
|
|
56
|
+
texts = [
|
|
57
|
+
f"Hello from {mode} mode",
|
|
58
|
+
f"Security test for {mode}",
|
|
59
|
+
f"Vectorization using {mode}",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
print(f"š¤ Vectorizing {len(texts)} texts using {mode} mode...")
|
|
63
|
+
for i, text in enumerate(texts):
|
|
64
|
+
print(f" {i+1}. {text}")
|
|
65
|
+
|
|
66
|
+
# Test different output formats
|
|
67
|
+
print("\nš Testing JSON format:")
|
|
68
|
+
await cli.vectorize_texts(texts, "json")
|
|
69
|
+
|
|
70
|
+
print("\nš Testing CSV format:")
|
|
71
|
+
await cli.vectorize_texts(texts, "csv")
|
|
72
|
+
|
|
73
|
+
print("\nš Testing vectors format:")
|
|
74
|
+
await cli.vectorize_texts(texts, "vectors")
|
|
75
|
+
|
|
76
|
+
print(f"ā
{mode} mode demonstration completed successfully!")
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
except Exception as e:
|
|
80
|
+
print(f"ā {mode} mode demonstration failed: {e}")
|
|
81
|
+
return False
|
|
82
|
+
finally:
|
|
83
|
+
await cli.disconnect()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def demo_all_security_modes():
|
|
87
|
+
"""Demonstrate all 8 security modes."""
|
|
88
|
+
print("š Security CLI Demo - All 8 Security Modes")
|
|
89
|
+
print("=" * 60)
|
|
90
|
+
|
|
91
|
+
# Demo configurations for each mode
|
|
92
|
+
demos = [
|
|
93
|
+
{
|
|
94
|
+
"mode": "http",
|
|
95
|
+
"host": "localhost",
|
|
96
|
+
"port": 10001,
|
|
97
|
+
"description": "Plain HTTP without authentication",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"mode": "http_token",
|
|
101
|
+
"host": "localhost",
|
|
102
|
+
"port": 10002,
|
|
103
|
+
"api_key": "admin-secret-key",
|
|
104
|
+
"description": "HTTP with API Key authentication",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"mode": "http_token_roles",
|
|
108
|
+
"host": "localhost",
|
|
109
|
+
"port": 10003,
|
|
110
|
+
"api_key": "admin-secret-key",
|
|
111
|
+
"description": "HTTP with API Key and role-based access control",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"mode": "https",
|
|
115
|
+
"host": "localhost",
|
|
116
|
+
"port": 10011,
|
|
117
|
+
"cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/server/embedding-service.crt",
|
|
118
|
+
"key_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/server/embedding-service.key",
|
|
119
|
+
"description": "HTTPS with server certificate verification",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"mode": "https_token",
|
|
123
|
+
"host": "localhost",
|
|
124
|
+
"port": 10012,
|
|
125
|
+
"api_key": "admin-secret-key",
|
|
126
|
+
"cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/server/embedding-service.crt",
|
|
127
|
+
"key_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/server/embedding-service.key",
|
|
128
|
+
"description": "HTTPS with server certificates + authentication",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"mode": "https_token_roles",
|
|
132
|
+
"host": "localhost",
|
|
133
|
+
"port": 10013,
|
|
134
|
+
"api_key": "admin-secret-key",
|
|
135
|
+
"cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/server/embedding-service.crt",
|
|
136
|
+
"key_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/server/embedding-service.key",
|
|
137
|
+
"description": "HTTPS with server certificates + authentication + roles",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"mode": "mtls",
|
|
141
|
+
"host": "localhost",
|
|
142
|
+
"port": 10021,
|
|
143
|
+
"cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/client/embedding-service.crt",
|
|
144
|
+
"key_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/client/embedding-service.key",
|
|
145
|
+
"ca_cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/ca/ca.crt",
|
|
146
|
+
"description": "Mutual TLS with client and server certificates",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"mode": "mtls_roles",
|
|
150
|
+
"host": "localhost",
|
|
151
|
+
"port": 10022,
|
|
152
|
+
"cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/client/embedding-service.crt",
|
|
153
|
+
"key_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/client/embedding-service.key",
|
|
154
|
+
"ca_cert_file": "/home/vasilyvz/projects/tools/embed/mtls_certificates/ca/ca.crt",
|
|
155
|
+
"description": "mTLS with role-based access control",
|
|
156
|
+
},
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
results = {}
|
|
160
|
+
|
|
161
|
+
for demo in demos:
|
|
162
|
+
mode = demo["mode"]
|
|
163
|
+
description = demo["description"]
|
|
164
|
+
|
|
165
|
+
print(f"\nš {mode.upper()} - {description}")
|
|
166
|
+
print("-" * 50)
|
|
167
|
+
|
|
168
|
+
# Extract parameters for the demo
|
|
169
|
+
demo_params = {
|
|
170
|
+
k: v
|
|
171
|
+
for k, v in demo.items()
|
|
172
|
+
if k not in ["mode", "host", "port", "description"]
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
success = await demo_security_mode(
|
|
176
|
+
demo["mode"], demo["host"], demo["port"], **demo_params
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
results[mode] = success
|
|
180
|
+
|
|
181
|
+
# Print summary
|
|
182
|
+
print("\nš Demo Results Summary:")
|
|
183
|
+
print("=" * 50)
|
|
184
|
+
for mode, success in results.items():
|
|
185
|
+
status = "ā
SUCCESS" if success else "ā FAILED"
|
|
186
|
+
print(f"{mode:20} {status}")
|
|
187
|
+
|
|
188
|
+
total_demos = len(results)
|
|
189
|
+
successful_demos = sum(1 for success in results.values() if success)
|
|
190
|
+
failed_demos = total_demos - successful_demos
|
|
191
|
+
|
|
192
|
+
print("\nš Demo completed!")
|
|
193
|
+
print(f"š Results: {successful_demos}/{total_demos} demos successful")
|
|
194
|
+
if failed_demos > 0:
|
|
195
|
+
print(f"ā {failed_demos} demos failed")
|
|
196
|
+
else:
|
|
197
|
+
print("ā
All demos successful!")
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
async def main():
|
|
201
|
+
"""Main demo function."""
|
|
202
|
+
await demo_all_security_modes()
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
if __name__ == "__main__":
|
|
206
|
+
asyncio.run(main())
|