mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__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.
Potentially problematic release.
This version of mcp-proxy-adapter might be problematic. Click here for more details.
- mcp_proxy_adapter/__init__.py +47 -0
- mcp_proxy_adapter/__main__.py +13 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +66 -0
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +400 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_context.py +356 -0
- mcp_proxy_adapter/api/core/registration_manager.py +307 -0
- mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +181 -0
- mcp_proxy_adapter/api/middleware/__init__.py +21 -0
- mcp_proxy_adapter/api/middleware/base.py +54 -0
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
- mcp_proxy_adapter/api/middleware/factory.py +147 -0
- mcp_proxy_adapter/api/middleware/logging.py +31 -0
- mcp_proxy_adapter/api/middleware/performance.py +51 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
- mcp_proxy_adapter/api/openapi/__init__.py +21 -0
- mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
- mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
- mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
- mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
- mcp_proxy_adapter/api/schemas.py +270 -0
- mcp_proxy_adapter/api/tool_integration.py +131 -0
- mcp_proxy_adapter/api/tools.py +163 -0
- mcp_proxy_adapter/cli/__init__.py +12 -0
- mcp_proxy_adapter/cli/commands/__init__.py +15 -0
- mcp_proxy_adapter/cli/commands/client.py +100 -0
- mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
- mcp_proxy_adapter/cli/commands/generate.py +259 -0
- mcp_proxy_adapter/cli/commands/server.py +174 -0
- mcp_proxy_adapter/cli/commands/sets.py +132 -0
- mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
- mcp_proxy_adapter/cli/examples/__init__.py +8 -0
- mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
- mcp_proxy_adapter/cli/examples/https_token.py +96 -0
- mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
- mcp_proxy_adapter/cli/main.py +63 -0
- mcp_proxy_adapter/cli/parser.py +338 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
- mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
- mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
- mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
- mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
- mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
- mcp_proxy_adapter/client/proxy.py +123 -0
- mcp_proxy_adapter/commands/__init__.py +66 -0
- mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
- mcp_proxy_adapter/commands/base.py +389 -0
- mcp_proxy_adapter/commands/builtin_commands.py +30 -0
- mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
- mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
- mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
- mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
- mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
- mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
- mcp_proxy_adapter/commands/catalog_manager.py +97 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
- mcp_proxy_adapter/commands/command_registry.py +298 -0
- mcp_proxy_adapter/commands/config_command.py +102 -0
- mcp_proxy_adapter/commands/dependency_container.py +40 -0
- mcp_proxy_adapter/commands/dependency_manager.py +143 -0
- mcp_proxy_adapter/commands/echo_command.py +48 -0
- mcp_proxy_adapter/commands/health_command.py +142 -0
- mcp_proxy_adapter/commands/help_command.py +175 -0
- mcp_proxy_adapter/commands/hooks.py +172 -0
- mcp_proxy_adapter/commands/key_management_command.py +484 -0
- mcp_proxy_adapter/commands/load_command.py +123 -0
- mcp_proxy_adapter/commands/plugins_command.py +246 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +76 -0
- mcp_proxy_adapter/commands/registry/__init__.py +18 -0
- mcp_proxy_adapter/commands/registry/command_info.py +103 -0
- mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
- mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
- mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
- mcp_proxy_adapter/commands/reload_command.py +136 -0
- mcp_proxy_adapter/commands/result.py +157 -0
- mcp_proxy_adapter/commands/role_test_command.py +99 -0
- mcp_proxy_adapter/commands/roles_management_command.py +502 -0
- mcp_proxy_adapter/commands/security_command.py +472 -0
- mcp_proxy_adapter/commands/settings_command.py +113 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
- mcp_proxy_adapter/commands/token_management_command.py +500 -0
- mcp_proxy_adapter/commands/transport_management_command.py +129 -0
- mcp_proxy_adapter/commands/unload_command.py +92 -0
- mcp_proxy_adapter/config.py +32 -0
- mcp_proxy_adapter/core/__init__.py +8 -0
- mcp_proxy_adapter/core/app_factory.py +560 -0
- mcp_proxy_adapter/core/app_runner.py +318 -0
- mcp_proxy_adapter/core/auth_validator.py +508 -0
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
- mcp_proxy_adapter/core/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/client.py +608 -0
- mcp_proxy_adapter/core/client_manager.py +271 -0
- mcp_proxy_adapter/core/client_security.py +411 -0
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +237 -0
- mcp_proxy_adapter/core/config/config_factory.py +22 -0
- mcp_proxy_adapter/core/config/config_loader.py +66 -0
- mcp_proxy_adapter/core/config/feature_manager.py +31 -0
- mcp_proxy_adapter/core/config/simple_config.py +204 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
- mcp_proxy_adapter/core/config_converter.py +252 -0
- mcp_proxy_adapter/core/config_validator.py +211 -0
- mcp_proxy_adapter/core/crl_utils.py +362 -0
- mcp_proxy_adapter/core/errors.py +276 -0
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +250 -0
- mcp_proxy_adapter/core/mtls_asgi.py +140 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/mtls_proxy.py +229 -0
- mcp_proxy_adapter/core/mtls_server.py +154 -0
- mcp_proxy_adapter/core/protocol_manager.py +232 -0
- mcp_proxy_adapter/core/proxy/__init__.py +19 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +184 -0
- mcp_proxy_adapter/core/proxy_registration.py +80 -0
- mcp_proxy_adapter/core/role_utils.py +103 -0
- mcp_proxy_adapter/core/security_adapter.py +343 -0
- mcp_proxy_adapter/core/security_factory.py +96 -0
- mcp_proxy_adapter/core/security_integration.py +342 -0
- mcp_proxy_adapter/core/server_adapter.py +251 -0
- mcp_proxy_adapter/core/server_engine.py +217 -0
- mcp_proxy_adapter/core/settings.py +260 -0
- mcp_proxy_adapter/core/signal_handler.py +107 -0
- mcp_proxy_adapter/core/ssl_utils.py +161 -0
- mcp_proxy_adapter/core/transport_manager.py +153 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
- mcp_proxy_adapter/core/utils.py +101 -0
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +219 -0
- mcp_proxy_adapter/core/validation/file_validator.py +131 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
- mcp_proxy_adapter/core/validation/security_validator.py +140 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +58 -0
- mcp_proxy_adapter/examples/__init__.py +16 -0
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter/examples/check_config.py +413 -0
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/config_builder.py +234 -0
- mcp_proxy_adapter/examples/config_cli.py +282 -0
- mcp_proxy_adapter/examples/create_test_configs.py +174 -0
- mcp_proxy_adapter/examples/debug_request_state.py +130 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
- mcp_proxy_adapter/examples/demo_client.py +287 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
- mcp_proxy_adapter/examples/full_application/main.py +311 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
- mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
- mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
- mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
- mcp_proxy_adapter/examples/generate_config.py +502 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
- mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
- mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
- mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
- mcp_proxy_adapter/examples/queue_server_example.py +85 -0
- mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
- mcp_proxy_adapter/examples/required_certificates.py +208 -0
- mcp_proxy_adapter/examples/run_example.py +77 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
- mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
- mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
- mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
- mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
- mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
- mcp_proxy_adapter/examples/security_test_client.py +72 -0
- mcp_proxy_adapter/examples/setup/__init__.py +24 -0
- mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
- mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
- mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
- mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
- mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
- mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
- mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
- mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
- mcp_proxy_adapter/examples/test_config.py +205 -0
- mcp_proxy_adapter/examples/test_config_builder.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +308 -0
- mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
- mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
- mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
- mcp_proxy_adapter/examples/universal_client.py +674 -0
- mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +311 -0
- mcp_proxy_adapter/openapi.py +375 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/schemas/roles.json +37 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/version.py +5 -0
- mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
- mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
- {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
- mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
- mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
- adapters/__init__.py +0 -16
- analyzers/__init__.py +0 -14
- analyzers/docstring_analyzer.py +0 -199
- analyzers/type_analyzer.py +0 -151
- cli/__init__.py +0 -12
- cli/__main__.py +0 -79
- cli/command_runner.py +0 -233
- dispatchers/__init__.py +0 -14
- dispatchers/base_dispatcher.py +0 -85
- dispatchers/json_rpc_dispatcher.py +0 -198
- generators/__init__.py +0 -14
- generators/endpoint_generator.py +0 -172
- generators/openapi_generator.py +0 -254
- generators/rest_api_generator.py +0 -207
- mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
- mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
- mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
- mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
- openapi_schema/__init__.py +0 -38
- openapi_schema/command_registry.py +0 -312
- openapi_schema/rest_schema.py +0 -510
- openapi_schema/rpc_generator.py +0 -307
- openapi_schema/rpc_schema.py +0 -416
- validators/__init__.py +0 -14
- validators/base_validator.py +0 -23
- validators/docstring_validator.py +0 -75
- validators/metadata_validator.py +0 -76
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Implementation of a JSON-RPC based command dispatcher.
|
|
3
|
-
"""
|
|
4
|
-
from typing import Dict, Any, Callable, List, Optional, Union
|
|
5
|
-
import inspect
|
|
6
|
-
import logging
|
|
7
|
-
import traceback
|
|
8
|
-
from .base_dispatcher import BaseDispatcher
|
|
9
|
-
|
|
10
|
-
logger = logging.getLogger("command_registry")
|
|
11
|
-
|
|
12
|
-
class CommandError(Exception):
|
|
13
|
-
"""Base class for command errors"""
|
|
14
|
-
pass
|
|
15
|
-
|
|
16
|
-
class CommandNotFoundError(CommandError):
|
|
17
|
-
"""Error raised when attempting to execute a non-existent command"""
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
class CommandExecutionError(CommandError):
|
|
21
|
-
"""Error raised during command execution"""
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
class JsonRpcDispatcher(BaseDispatcher):
|
|
25
|
-
"""
|
|
26
|
-
JSON-RPC based command dispatcher.
|
|
27
|
-
|
|
28
|
-
Implements the BaseDispatcher interface for handling commands in JSON-RPC 2.0 format.
|
|
29
|
-
Supports registration, execution, and retrieval of command information.
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
def __init__(self):
|
|
33
|
-
"""Initializes a new dispatcher instance"""
|
|
34
|
-
self._handlers = {}
|
|
35
|
-
self._metadata = {}
|
|
36
|
-
|
|
37
|
-
# Register the built-in help command
|
|
38
|
-
self.register_handler(
|
|
39
|
-
command="help",
|
|
40
|
-
handler=self._help_command,
|
|
41
|
-
description="Returns information about available commands",
|
|
42
|
-
summary="Command help",
|
|
43
|
-
params={
|
|
44
|
-
"command": {
|
|
45
|
-
"type": "string",
|
|
46
|
-
"description": "Command name for detailed information",
|
|
47
|
-
"required": False
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
def register_handler(
|
|
53
|
-
self,
|
|
54
|
-
command: str,
|
|
55
|
-
handler: Callable,
|
|
56
|
-
description: str = "",
|
|
57
|
-
summary: str = "",
|
|
58
|
-
params: Dict[str, Any] = None
|
|
59
|
-
) -> None:
|
|
60
|
-
"""
|
|
61
|
-
Registers a command handler.
|
|
62
|
-
|
|
63
|
-
Args:
|
|
64
|
-
command: Command name
|
|
65
|
-
handler: Command handler function
|
|
66
|
-
description: Command description
|
|
67
|
-
summary: Brief command summary
|
|
68
|
-
params: Command parameters description
|
|
69
|
-
"""
|
|
70
|
-
if not params:
|
|
71
|
-
params = {}
|
|
72
|
-
|
|
73
|
-
# Save the handler
|
|
74
|
-
self._handlers[command] = handler
|
|
75
|
-
|
|
76
|
-
# Save metadata
|
|
77
|
-
self._metadata[command] = {
|
|
78
|
-
"description": description,
|
|
79
|
-
"summary": summary or command.replace("_", " ").title(),
|
|
80
|
-
"params": params
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
logger.debug(f"Registered command: {command}")
|
|
84
|
-
|
|
85
|
-
def execute(self, command: str, **kwargs) -> Any:
|
|
86
|
-
"""
|
|
87
|
-
Executes a command with the specified parameters.
|
|
88
|
-
|
|
89
|
-
Args:
|
|
90
|
-
command: Command name
|
|
91
|
-
**kwargs: Command parameters
|
|
92
|
-
|
|
93
|
-
Returns:
|
|
94
|
-
Any: Command execution result
|
|
95
|
-
|
|
96
|
-
Raises:
|
|
97
|
-
CommandNotFoundError: If command is not found
|
|
98
|
-
CommandExecutionError: On command execution error
|
|
99
|
-
"""
|
|
100
|
-
# Check if command exists
|
|
101
|
-
if command not in self._handlers:
|
|
102
|
-
raise CommandNotFoundError(f"Command '{command}' not found")
|
|
103
|
-
|
|
104
|
-
handler = self._handlers[command]
|
|
105
|
-
|
|
106
|
-
try:
|
|
107
|
-
# Get function signature
|
|
108
|
-
sig = inspect.signature(handler)
|
|
109
|
-
|
|
110
|
-
# If function accepts params dictionary, pass all parameters in it
|
|
111
|
-
if len(sig.parameters) == 1 and list(sig.parameters.keys())[0] == 'params':
|
|
112
|
-
return handler(params=kwargs)
|
|
113
|
-
|
|
114
|
-
# Otherwise pass parameters as named arguments
|
|
115
|
-
return handler(**kwargs)
|
|
116
|
-
except Exception as e:
|
|
117
|
-
# Log the error
|
|
118
|
-
logger.error(f"Error executing command '{command}': {str(e)}")
|
|
119
|
-
logger.debug(traceback.format_exc())
|
|
120
|
-
|
|
121
|
-
# Re-raise the exception
|
|
122
|
-
raise CommandExecutionError(f"Error executing command '{command}': {str(e)}")
|
|
123
|
-
|
|
124
|
-
def get_valid_commands(self) -> List[str]:
|
|
125
|
-
"""
|
|
126
|
-
Returns a list of all registered command names.
|
|
127
|
-
|
|
128
|
-
Returns:
|
|
129
|
-
List[str]: List of command names
|
|
130
|
-
"""
|
|
131
|
-
return list(self._handlers.keys())
|
|
132
|
-
|
|
133
|
-
def get_command_info(self, command: str) -> Optional[Dict[str, Any]]:
|
|
134
|
-
"""
|
|
135
|
-
Returns information about a command.
|
|
136
|
-
|
|
137
|
-
Args:
|
|
138
|
-
command: Command name
|
|
139
|
-
|
|
140
|
-
Returns:
|
|
141
|
-
Optional[Dict[str, Any]]: Command information or None if command not found
|
|
142
|
-
"""
|
|
143
|
-
if command not in self._metadata:
|
|
144
|
-
return None
|
|
145
|
-
|
|
146
|
-
return self._metadata[command]
|
|
147
|
-
|
|
148
|
-
def get_commands_info(self) -> Dict[str, Dict[str, Any]]:
|
|
149
|
-
"""
|
|
150
|
-
Returns information about all registered commands.
|
|
151
|
-
|
|
152
|
-
Returns:
|
|
153
|
-
Dict[str, Dict[str, Any]]: Dictionary {command_name: information}
|
|
154
|
-
"""
|
|
155
|
-
return self._metadata.copy()
|
|
156
|
-
|
|
157
|
-
def _help_command(self, params: Dict[str, Any] = None) -> Dict[str, Any]:
|
|
158
|
-
"""
|
|
159
|
-
Built-in help command for getting command information.
|
|
160
|
-
|
|
161
|
-
Args:
|
|
162
|
-
params: Command parameters
|
|
163
|
-
command: Command name for detailed information
|
|
164
|
-
|
|
165
|
-
Returns:
|
|
166
|
-
Dict[str, Any]: Command help information
|
|
167
|
-
"""
|
|
168
|
-
if not params:
|
|
169
|
-
params = {}
|
|
170
|
-
|
|
171
|
-
# If specific command is specified, return information only about it
|
|
172
|
-
if "command" in params and params["command"]:
|
|
173
|
-
command = params["command"]
|
|
174
|
-
if command not in self._metadata:
|
|
175
|
-
return {
|
|
176
|
-
"error": f"Command '{command}' not found",
|
|
177
|
-
"available_commands": list(self._metadata.keys())
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
"command": command,
|
|
182
|
-
"info": self._metadata[command]
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
# Otherwise return brief information about all commands
|
|
186
|
-
commands_info = {}
|
|
187
|
-
for cmd, info in self._metadata.items():
|
|
188
|
-
commands_info[cmd] = {
|
|
189
|
-
"summary": info["summary"],
|
|
190
|
-
"description": info["description"],
|
|
191
|
-
"params_count": len(info["params"])
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
"commands": commands_info,
|
|
196
|
-
"total": len(commands_info),
|
|
197
|
-
"note": "Use the 'command' parameter to get detailed information about a specific command"
|
|
198
|
-
}
|
generators/__init__.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Генераторы API на основе команд и их метаданных.
|
|
3
|
-
|
|
4
|
-
Этот модуль содержит классы для автоматической генерации API интерфейсов
|
|
5
|
-
(REST, OpenAPI и др.) на основе зарегистрированных команд.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from command_registry.generators.rest_api_generator import RestApiGenerator
|
|
9
|
-
from command_registry.generators.openapi_generator import OpenApiGenerator
|
|
10
|
-
|
|
11
|
-
__all__ = [
|
|
12
|
-
'RestApiGenerator',
|
|
13
|
-
'OpenApiGenerator',
|
|
14
|
-
]
|
generators/endpoint_generator.py
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
REST API endpoint generator based on registered commands.
|
|
3
|
-
"""
|
|
4
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
5
|
-
import inspect
|
|
6
|
-
import asyncio
|
|
7
|
-
from fastapi import APIRouter, Depends, Request, HTTPException
|
|
8
|
-
from pydantic import BaseModel, create_model
|
|
9
|
-
|
|
10
|
-
class EndpointGenerator:
|
|
11
|
-
"""
|
|
12
|
-
REST API endpoint generator based on registered commands.
|
|
13
|
-
|
|
14
|
-
Creates dynamic FastAPI endpoints by automatically generating
|
|
15
|
-
request and response models based on signatures and docstrings
|
|
16
|
-
of registered handler functions.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
def __init__(self, router: APIRouter, dispatcher: Any):
|
|
20
|
-
"""
|
|
21
|
-
Initialize endpoint generator.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
router: FastAPI router for registering endpoints
|
|
25
|
-
dispatcher: Command dispatcher providing access to registered commands
|
|
26
|
-
"""
|
|
27
|
-
self.router = router
|
|
28
|
-
self.dispatcher = dispatcher
|
|
29
|
-
self.registered_endpoints = []
|
|
30
|
-
|
|
31
|
-
def generate_endpoint(self, command_name: str, handler_func: Callable, metadata: Dict[str, Any]) -> None:
|
|
32
|
-
"""
|
|
33
|
-
Generates REST API endpoint for specified command.
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
command_name: Command name
|
|
37
|
-
handler_func: Command handler function
|
|
38
|
-
metadata: Command metadata from docstring
|
|
39
|
-
"""
|
|
40
|
-
# Get function signature
|
|
41
|
-
sig = inspect.signature(handler_func)
|
|
42
|
-
|
|
43
|
-
# Create request model based on function parameters
|
|
44
|
-
param_fields = {}
|
|
45
|
-
for name, param in sig.parameters.items():
|
|
46
|
-
# Skip self parameter
|
|
47
|
-
if name == 'self':
|
|
48
|
-
continue
|
|
49
|
-
|
|
50
|
-
# Get parameter type and default value
|
|
51
|
-
param_type = param.annotation if param.annotation != inspect.Parameter.empty else Any
|
|
52
|
-
default_value = ... if param.default == inspect.Parameter.empty else param.default
|
|
53
|
-
|
|
54
|
-
# Add field to model
|
|
55
|
-
param_fields[name] = (param_type, default_value)
|
|
56
|
-
|
|
57
|
-
# Create request model
|
|
58
|
-
request_model = create_model(
|
|
59
|
-
f"{command_name.capitalize()}Request",
|
|
60
|
-
**param_fields
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
# Create endpoint
|
|
64
|
-
endpoint_path = f"/{command_name}"
|
|
65
|
-
|
|
66
|
-
# Define endpoint handler
|
|
67
|
-
async def endpoint_handler(request_data: request_model):
|
|
68
|
-
# Call command through dispatcher
|
|
69
|
-
try:
|
|
70
|
-
# Get parameters from model
|
|
71
|
-
params = request_data.__dict__ if hasattr(request_data, "__dict__") else {}
|
|
72
|
-
|
|
73
|
-
# Call dispatcher's execute method
|
|
74
|
-
result = self.dispatcher.execute(command_name, **params)
|
|
75
|
-
|
|
76
|
-
# If result is coroutine, await its completion
|
|
77
|
-
if inspect.iscoroutine(result):
|
|
78
|
-
result = await result
|
|
79
|
-
|
|
80
|
-
return {"success": True, "result": result}
|
|
81
|
-
except Exception as e:
|
|
82
|
-
raise HTTPException(status_code=500, detail=str(e))
|
|
83
|
-
|
|
84
|
-
# Add documentation from metadata
|
|
85
|
-
if 'description' in metadata:
|
|
86
|
-
endpoint_handler.__doc__ = metadata['description']
|
|
87
|
-
|
|
88
|
-
# Register endpoint
|
|
89
|
-
self.router.post(endpoint_path, response_model=None)(endpoint_handler)
|
|
90
|
-
self.registered_endpoints.append(endpoint_path)
|
|
91
|
-
|
|
92
|
-
def generate_all_endpoints(self) -> List[str]:
|
|
93
|
-
"""
|
|
94
|
-
Generates endpoints for all registered commands.
|
|
95
|
-
|
|
96
|
-
Returns:
|
|
97
|
-
List[str]: List of created endpoints
|
|
98
|
-
"""
|
|
99
|
-
# Create endpoints for all commands
|
|
100
|
-
commands_info = self.dispatcher.get_commands_info()
|
|
101
|
-
|
|
102
|
-
for command_name, command_info in commands_info.items():
|
|
103
|
-
# Get command handler
|
|
104
|
-
handler = self.dispatcher._handlers[command_name] if hasattr(self.dispatcher, "_handlers") else None
|
|
105
|
-
|
|
106
|
-
# If handler couldn't be obtained, skip command
|
|
107
|
-
if not handler:
|
|
108
|
-
continue
|
|
109
|
-
|
|
110
|
-
self.generate_endpoint(
|
|
111
|
-
command_name,
|
|
112
|
-
handler,
|
|
113
|
-
command_info
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
# Create help endpoint
|
|
117
|
-
self.generate_help_endpoint()
|
|
118
|
-
|
|
119
|
-
return self.registered_endpoints
|
|
120
|
-
|
|
121
|
-
def generate_help_endpoint(self) -> None:
|
|
122
|
-
"""
|
|
123
|
-
Creates special /help endpoint that returns information
|
|
124
|
-
about all available commands and their endpoints.
|
|
125
|
-
"""
|
|
126
|
-
async def help_handler(command: Optional[str] = None):
|
|
127
|
-
if command:
|
|
128
|
-
# If specific command is specified, return information about it
|
|
129
|
-
command_info = self.dispatcher.get_command_info(command)
|
|
130
|
-
if not command_info:
|
|
131
|
-
return {
|
|
132
|
-
"success": False,
|
|
133
|
-
"error": f"Command '{command}' not found",
|
|
134
|
-
"available_commands": self.dispatcher.get_valid_commands()
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
# Add endpoint URL
|
|
138
|
-
endpoint_path = f"/{command}"
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
"success": True,
|
|
142
|
-
"command": command,
|
|
143
|
-
"info": command_info,
|
|
144
|
-
"endpoint": endpoint_path
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
# Otherwise return information about all commands
|
|
148
|
-
commands_info = {}
|
|
149
|
-
for cmd in self.dispatcher.get_valid_commands():
|
|
150
|
-
info = self.dispatcher.get_command_info(cmd)
|
|
151
|
-
if not info:
|
|
152
|
-
continue
|
|
153
|
-
|
|
154
|
-
endpoint_path = f"/{cmd}"
|
|
155
|
-
commands_info[cmd] = {
|
|
156
|
-
"summary": info.get("summary", ""),
|
|
157
|
-
"description": info.get("description", ""),
|
|
158
|
-
"endpoint": endpoint_path,
|
|
159
|
-
"params_count": len(info.get("params", {}))
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
"success": True,
|
|
164
|
-
"commands": commands_info,
|
|
165
|
-
"total": len(commands_info),
|
|
166
|
-
"endpoints": self.registered_endpoints,
|
|
167
|
-
"note": "Use 'command' parameter to get detailed information about a specific command"
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
help_handler.__doc__ = "Get list of all available commands and API endpoints"
|
|
171
|
-
self.router.get("/help", response_model=None)(help_handler)
|
|
172
|
-
self.registered_endpoints.append("/help")
|
generators/openapi_generator.py
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
OpenAPI schema generator for API documentation based on registered commands.
|
|
3
|
-
"""
|
|
4
|
-
from typing import Any, Dict, List, Optional, Callable
|
|
5
|
-
import inspect
|
|
6
|
-
from pydantic import BaseModel, create_model
|
|
7
|
-
|
|
8
|
-
class OpenApiGenerator:
|
|
9
|
-
"""
|
|
10
|
-
OpenAPI schema generator for API documentation based on registered commands.
|
|
11
|
-
|
|
12
|
-
Creates OpenAPI schema describing all registered commands and their parameters
|
|
13
|
-
for use in automatic API documentation.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
def __init__(self, dispatcher: Any, title: str = "Vector Store API",
|
|
17
|
-
version: str = "1.0.0", description: str = "Vector Store API Documentation"):
|
|
18
|
-
"""
|
|
19
|
-
Initialize OpenAPI schema generator.
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
dispatcher: Command dispatcher providing access to registered commands
|
|
23
|
-
title: API title
|
|
24
|
-
version: API version
|
|
25
|
-
description: API description
|
|
26
|
-
"""
|
|
27
|
-
self.dispatcher = dispatcher
|
|
28
|
-
self.title = title
|
|
29
|
-
self.version = version
|
|
30
|
-
self.description = description
|
|
31
|
-
|
|
32
|
-
def generate_schema(self) -> Dict[str, Any]:
|
|
33
|
-
"""
|
|
34
|
-
Generates complete OpenAPI schema for all registered commands.
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
Dict[str, Any]: OpenAPI schema as dictionary
|
|
38
|
-
"""
|
|
39
|
-
# Base OpenAPI schema structure
|
|
40
|
-
schema = {
|
|
41
|
-
"openapi": "3.0.0",
|
|
42
|
-
"info": {
|
|
43
|
-
"title": self.title,
|
|
44
|
-
"version": self.version,
|
|
45
|
-
"description": self.description
|
|
46
|
-
},
|
|
47
|
-
"paths": {},
|
|
48
|
-
"components": {
|
|
49
|
-
"schemas": {}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
# Get all registered commands
|
|
54
|
-
commands = self.dispatcher.get_registered_commands()
|
|
55
|
-
|
|
56
|
-
# Generate schemas for each command
|
|
57
|
-
for command_name, command_data in commands.items():
|
|
58
|
-
handler_func = command_data['handler']
|
|
59
|
-
metadata = command_data.get('metadata', {})
|
|
60
|
-
|
|
61
|
-
# Add path for endpoint
|
|
62
|
-
path = f"/{command_name}"
|
|
63
|
-
method = "post" # By default all commands are handled via POST
|
|
64
|
-
|
|
65
|
-
# Get request schema
|
|
66
|
-
request_schema = self._generate_request_schema(command_name, handler_func)
|
|
67
|
-
|
|
68
|
-
# Add response schema
|
|
69
|
-
response_schema = self._generate_response_schema(command_name, handler_func, metadata)
|
|
70
|
-
|
|
71
|
-
# Add path to schema
|
|
72
|
-
schema["paths"][path] = {
|
|
73
|
-
method: {
|
|
74
|
-
"summary": metadata.get('summary', f"Execute {command_name} command"),
|
|
75
|
-
"description": metadata.get('description', ""),
|
|
76
|
-
"operationId": f"{command_name}",
|
|
77
|
-
"requestBody": {
|
|
78
|
-
"required": True,
|
|
79
|
-
"content": {
|
|
80
|
-
"application/json": {
|
|
81
|
-
"schema": request_schema
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
"responses": {
|
|
86
|
-
"200": {
|
|
87
|
-
"description": "Successful operation",
|
|
88
|
-
"content": {
|
|
89
|
-
"application/json": {
|
|
90
|
-
"schema": response_schema
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
"500": {
|
|
95
|
-
"description": "Internal server error",
|
|
96
|
-
"content": {
|
|
97
|
-
"application/json": {
|
|
98
|
-
"schema": {
|
|
99
|
-
"type": "object",
|
|
100
|
-
"properties": {
|
|
101
|
-
"success": {
|
|
102
|
-
"type": "boolean",
|
|
103
|
-
"example": False
|
|
104
|
-
},
|
|
105
|
-
"error": {
|
|
106
|
-
"type": "string"
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
# Add /help endpoint
|
|
118
|
-
schema["paths"]["/help"] = {
|
|
119
|
-
"get": {
|
|
120
|
-
"summary": "Get API help",
|
|
121
|
-
"description": "Get list of all available commands and API endpoints",
|
|
122
|
-
"operationId": "getHelp",
|
|
123
|
-
"responses": {
|
|
124
|
-
"200": {
|
|
125
|
-
"description": "Successful operation",
|
|
126
|
-
"content": {
|
|
127
|
-
"application/json": {
|
|
128
|
-
"schema": {
|
|
129
|
-
"type": "object",
|
|
130
|
-
"properties": {
|
|
131
|
-
"success": {
|
|
132
|
-
"type": "boolean",
|
|
133
|
-
"example": True
|
|
134
|
-
},
|
|
135
|
-
"registered_commands": {
|
|
136
|
-
"type": "object",
|
|
137
|
-
"additionalProperties": {
|
|
138
|
-
"type": "object",
|
|
139
|
-
"properties": {
|
|
140
|
-
"endpoint": {
|
|
141
|
-
"type": "string"
|
|
142
|
-
},
|
|
143
|
-
"description": {
|
|
144
|
-
"type": "string"
|
|
145
|
-
},
|
|
146
|
-
"parameters": {
|
|
147
|
-
"type": "object"
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
"endpoints": {
|
|
153
|
-
"type": "array",
|
|
154
|
-
"items": {
|
|
155
|
-
"type": "string"
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return schema
|
|
168
|
-
|
|
169
|
-
def _generate_request_schema(self, command_name: str, handler_func: Callable) -> Dict[str, Any]:
|
|
170
|
-
"""
|
|
171
|
-
Generates request schema for specified command.
|
|
172
|
-
|
|
173
|
-
Args:
|
|
174
|
-
command_name: Command name
|
|
175
|
-
handler_func: Command handler function
|
|
176
|
-
|
|
177
|
-
Returns:
|
|
178
|
-
Dict[str, Any]: Request schema in OpenAPI format
|
|
179
|
-
"""
|
|
180
|
-
# Get function signature
|
|
181
|
-
sig = inspect.signature(handler_func)
|
|
182
|
-
|
|
183
|
-
# Create request schema
|
|
184
|
-
properties = {}
|
|
185
|
-
required = []
|
|
186
|
-
|
|
187
|
-
for name, param in sig.parameters.items():
|
|
188
|
-
# Skip self parameter
|
|
189
|
-
if name == 'self':
|
|
190
|
-
continue
|
|
191
|
-
|
|
192
|
-
# Get parameter type
|
|
193
|
-
param_type = param.annotation if param.annotation != inspect.Parameter.empty else Any
|
|
194
|
-
|
|
195
|
-
# Determine type for OpenAPI
|
|
196
|
-
if param_type == str:
|
|
197
|
-
prop_type = {"type": "string"}
|
|
198
|
-
elif param_type == int:
|
|
199
|
-
prop_type = {"type": "integer"}
|
|
200
|
-
elif param_type == float:
|
|
201
|
-
prop_type = {"type": "number"}
|
|
202
|
-
elif param_type == bool:
|
|
203
|
-
prop_type = {"type": "boolean"}
|
|
204
|
-
elif param_type == list or param_type == List:
|
|
205
|
-
prop_type = {"type": "array", "items": {"type": "string"}}
|
|
206
|
-
elif param_type == dict or param_type == Dict:
|
|
207
|
-
prop_type = {"type": "object"}
|
|
208
|
-
else:
|
|
209
|
-
prop_type = {"type": "object"}
|
|
210
|
-
|
|
211
|
-
# Add property to schema
|
|
212
|
-
properties[name] = prop_type
|
|
213
|
-
|
|
214
|
-
# If parameter is required, add it to required list
|
|
215
|
-
if param.default == inspect.Parameter.empty:
|
|
216
|
-
required.append(name)
|
|
217
|
-
|
|
218
|
-
schema = {
|
|
219
|
-
"type": "object",
|
|
220
|
-
"properties": properties
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if required:
|
|
224
|
-
schema["required"] = required
|
|
225
|
-
|
|
226
|
-
return schema
|
|
227
|
-
|
|
228
|
-
def _generate_response_schema(self, command_name: str, handler_func: Callable,
|
|
229
|
-
metadata: Dict[str, Any]) -> Dict[str, Any]:
|
|
230
|
-
"""
|
|
231
|
-
Generates response schema for specified command.
|
|
232
|
-
|
|
233
|
-
Args:
|
|
234
|
-
command_name: Command name
|
|
235
|
-
handler_func: Command handler function
|
|
236
|
-
metadata: Command metadata
|
|
237
|
-
|
|
238
|
-
Returns:
|
|
239
|
-
Dict[str, Any]: Response schema in OpenAPI format
|
|
240
|
-
"""
|
|
241
|
-
# Base response structure
|
|
242
|
-
return {
|
|
243
|
-
"type": "object",
|
|
244
|
-
"properties": {
|
|
245
|
-
"success": {
|
|
246
|
-
"type": "boolean",
|
|
247
|
-
"example": True
|
|
248
|
-
},
|
|
249
|
-
"result": {
|
|
250
|
-
"type": "object",
|
|
251
|
-
"description": metadata.get("returns", "Command result")
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|