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
analyzers/type_analyzer.py
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Type analyzer for extracting information from function type annotations.
|
|
3
|
-
"""
|
|
4
|
-
import inspect
|
|
5
|
-
from typing import Dict, Any, List, Optional, Callable, Union, get_origin, get_args, get_type_hints
|
|
6
|
-
|
|
7
|
-
class TypeAnalyzer:
|
|
8
|
-
"""
|
|
9
|
-
Type analyzer for extracting information from function type annotations.
|
|
10
|
-
|
|
11
|
-
This class is responsible for analyzing type annotations of command handler functions
|
|
12
|
-
and converting them to JSON Schema/OpenAPI type format.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
def __init__(self):
|
|
16
|
-
# Mapping Python types to OpenAPI types
|
|
17
|
-
self.type_map = {
|
|
18
|
-
str: "string",
|
|
19
|
-
int: "integer",
|
|
20
|
-
float: "number",
|
|
21
|
-
bool: "boolean",
|
|
22
|
-
list: "array",
|
|
23
|
-
dict: "object",
|
|
24
|
-
Any: "object",
|
|
25
|
-
None: "null",
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
def analyze(self, handler: Callable) -> Dict[str, Any]:
|
|
29
|
-
"""
|
|
30
|
-
Analyzes function type annotations and returns metadata.
|
|
31
|
-
|
|
32
|
-
Args:
|
|
33
|
-
handler: Handler function to analyze
|
|
34
|
-
|
|
35
|
-
Returns:
|
|
36
|
-
Dict[str, Any]: Metadata about parameter types and return value
|
|
37
|
-
"""
|
|
38
|
-
result = {
|
|
39
|
-
"parameters": {},
|
|
40
|
-
"returns": None
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
# Get function signature
|
|
44
|
-
sig = inspect.signature(handler)
|
|
45
|
-
|
|
46
|
-
# Get type annotations
|
|
47
|
-
type_hints = self._get_type_hints(handler)
|
|
48
|
-
|
|
49
|
-
# Analyze parameters
|
|
50
|
-
for param_name, param in sig.parameters.items():
|
|
51
|
-
# Skip self for methods
|
|
52
|
-
if param_name == 'self':
|
|
53
|
-
continue
|
|
54
|
-
|
|
55
|
-
# If parameter is named params, assume it's a dictionary of all parameters
|
|
56
|
-
if param_name == 'params':
|
|
57
|
-
continue
|
|
58
|
-
|
|
59
|
-
# Determine if parameter is required
|
|
60
|
-
required = param.default == inspect.Parameter.empty
|
|
61
|
-
|
|
62
|
-
# Determine parameter type
|
|
63
|
-
param_type = "object" # Default type
|
|
64
|
-
|
|
65
|
-
if param_name in type_hints:
|
|
66
|
-
param_type = self._map_type_to_openapi(type_hints[param_name])
|
|
67
|
-
|
|
68
|
-
# Create parameter metadata
|
|
69
|
-
param_metadata = {
|
|
70
|
-
"type": param_type,
|
|
71
|
-
"required": required
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
# Add default value if exists
|
|
75
|
-
if param.default != inspect.Parameter.empty:
|
|
76
|
-
# Some default values cannot be serialized to JSON
|
|
77
|
-
# So we convert them to string representation for such cases
|
|
78
|
-
if param.default is None or isinstance(param.default, (str, int, float, bool, list, dict)):
|
|
79
|
-
param_metadata["default"] = param.default
|
|
80
|
-
|
|
81
|
-
# Add parameter to metadata
|
|
82
|
-
result["parameters"][param_name] = param_metadata
|
|
83
|
-
|
|
84
|
-
# Analyze return value
|
|
85
|
-
if 'return' in type_hints:
|
|
86
|
-
result["returns"] = self._map_type_to_openapi(type_hints['return'])
|
|
87
|
-
|
|
88
|
-
return result
|
|
89
|
-
|
|
90
|
-
def _get_type_hints(self, handler: Callable) -> Dict[str, Any]:
|
|
91
|
-
"""
|
|
92
|
-
Gets type annotations of a function.
|
|
93
|
-
|
|
94
|
-
Args:
|
|
95
|
-
handler: Handler function
|
|
96
|
-
|
|
97
|
-
Returns:
|
|
98
|
-
Dict[str, Any]: Type annotations
|
|
99
|
-
"""
|
|
100
|
-
try:
|
|
101
|
-
return get_type_hints(handler)
|
|
102
|
-
except Exception:
|
|
103
|
-
# If failed to get annotations via get_type_hints,
|
|
104
|
-
# extract them manually from __annotations__
|
|
105
|
-
return getattr(handler, "__annotations__", {})
|
|
106
|
-
|
|
107
|
-
def _map_type_to_openapi(self, type_hint: Any) -> Union[str, Dict[str, Any]]:
|
|
108
|
-
"""
|
|
109
|
-
Converts Python type to OpenAPI type.
|
|
110
|
-
|
|
111
|
-
Args:
|
|
112
|
-
type_hint: Python type
|
|
113
|
-
|
|
114
|
-
Returns:
|
|
115
|
-
Union[str, Dict[str, Any]]: OpenAPI type string representation or schema
|
|
116
|
-
"""
|
|
117
|
-
# Check for None
|
|
118
|
-
if type_hint is None:
|
|
119
|
-
return "null"
|
|
120
|
-
|
|
121
|
-
# Handle primitive types
|
|
122
|
-
if type_hint in self.type_map:
|
|
123
|
-
return self.type_map[type_hint]
|
|
124
|
-
|
|
125
|
-
# Check for generic types
|
|
126
|
-
origin = get_origin(type_hint)
|
|
127
|
-
if origin is not None:
|
|
128
|
-
# Handle List[X], Dict[X, Y], etc.
|
|
129
|
-
if origin in (list, List):
|
|
130
|
-
args = get_args(type_hint)
|
|
131
|
-
if args:
|
|
132
|
-
item_type = self._map_type_to_openapi(args[0])
|
|
133
|
-
return {
|
|
134
|
-
"type": "array",
|
|
135
|
-
"items": item_type if isinstance(item_type, dict) else {"type": item_type}
|
|
136
|
-
}
|
|
137
|
-
return "array"
|
|
138
|
-
elif origin in (dict, Dict):
|
|
139
|
-
# For dict we just return object, as OpenAPI
|
|
140
|
-
# doesn't have a direct equivalent for Dict[X, Y]
|
|
141
|
-
return "object"
|
|
142
|
-
elif origin is Union:
|
|
143
|
-
# For Union we take the first type that is not None
|
|
144
|
-
args = get_args(type_hint)
|
|
145
|
-
for arg in args:
|
|
146
|
-
if arg is not type(None):
|
|
147
|
-
return self._map_type_to_openapi(arg)
|
|
148
|
-
return "object"
|
|
149
|
-
|
|
150
|
-
# Default to object
|
|
151
|
-
return "object"
|
cli/__init__.py
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Командный интерфейс для запуска команд из командной строки.
|
|
3
|
-
|
|
4
|
-
Этот модуль предоставляет инструменты для создания командной строки
|
|
5
|
-
на основе зарегистрированных команд.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from command_registry.cli.command_runner import CommandRunner
|
|
9
|
-
|
|
10
|
-
__all__ = [
|
|
11
|
-
'CommandRunner',
|
|
12
|
-
]
|
cli/__main__.py
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
"""
|
|
3
|
-
Entry point for the command registry CLI interface.
|
|
4
|
-
|
|
5
|
-
This module allows running commands from the command line
|
|
6
|
-
using the command dispatcher.
|
|
7
|
-
|
|
8
|
-
Usage:
|
|
9
|
-
python -m command_registry.cli [command] [args...]
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import os
|
|
13
|
-
import sys
|
|
14
|
-
import importlib.util
|
|
15
|
-
from typing import Optional
|
|
16
|
-
|
|
17
|
-
from command_registry.cli.command_runner import CommandRunner
|
|
18
|
-
from command_registry.dispatchers.base_dispatcher import BaseDispatcher
|
|
19
|
-
from command_registry.dispatchers.command_dispatcher import CommandDispatcher
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def find_dispatcher() -> BaseDispatcher:
|
|
23
|
-
"""
|
|
24
|
-
Finds and creates command dispatcher.
|
|
25
|
-
|
|
26
|
-
Search order:
|
|
27
|
-
1. Checks DISPATCHER_MODULE environment variable
|
|
28
|
-
2. Looks for app.py in current directory
|
|
29
|
-
3. Creates new CommandDispatcher
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
BaseDispatcher: Command dispatcher
|
|
33
|
-
"""
|
|
34
|
-
# Check environment variable
|
|
35
|
-
dispatcher_module = os.environ.get("DISPATCHER_MODULE")
|
|
36
|
-
if dispatcher_module:
|
|
37
|
-
try:
|
|
38
|
-
module_path, attr_name = dispatcher_module.rsplit(":", 1)
|
|
39
|
-
module = importlib.import_module(module_path)
|
|
40
|
-
return getattr(module, attr_name)
|
|
41
|
-
except (ValueError, ImportError, AttributeError) as e:
|
|
42
|
-
print(f"Failed to load dispatcher from {dispatcher_module}: {e}",
|
|
43
|
-
file=sys.stderr)
|
|
44
|
-
|
|
45
|
-
# Check app.py file
|
|
46
|
-
app_path = os.path.join(os.getcwd(), "app.py")
|
|
47
|
-
if os.path.exists(app_path):
|
|
48
|
-
try:
|
|
49
|
-
spec = importlib.util.spec_from_file_location("app", app_path)
|
|
50
|
-
if spec and spec.loader:
|
|
51
|
-
app = importlib.util.module_from_spec(spec)
|
|
52
|
-
spec.loader.exec_module(app)
|
|
53
|
-
|
|
54
|
-
# Look for dispatcher in module
|
|
55
|
-
dispatcher = getattr(app, "dispatcher", None)
|
|
56
|
-
if dispatcher and isinstance(dispatcher, BaseDispatcher):
|
|
57
|
-
return dispatcher
|
|
58
|
-
except Exception as e:
|
|
59
|
-
print(f"Failed to load dispatcher from app.py: {e}",
|
|
60
|
-
file=sys.stderr)
|
|
61
|
-
|
|
62
|
-
# Create new dispatcher if not found
|
|
63
|
-
return CommandDispatcher()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def main() -> None:
|
|
67
|
-
"""
|
|
68
|
-
Main function for running CLI interface.
|
|
69
|
-
"""
|
|
70
|
-
# Get dispatcher
|
|
71
|
-
dispatcher = find_dispatcher()
|
|
72
|
-
|
|
73
|
-
# Create and run CommandRunner
|
|
74
|
-
runner = CommandRunner(dispatcher)
|
|
75
|
-
runner.run(sys.argv[1:])
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if __name__ == "__main__":
|
|
79
|
-
main()
|
cli/command_runner.py
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Command line utility for executing commands.
|
|
3
|
-
|
|
4
|
-
Provides a command line interface for the command dispatcher,
|
|
5
|
-
allowing execution of registered commands and getting help information.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import argparse
|
|
9
|
-
import json
|
|
10
|
-
import sys
|
|
11
|
-
from typing import Any, Dict, List, Optional, Sequence
|
|
12
|
-
|
|
13
|
-
from command_registry.dispatchers.base_dispatcher import BaseDispatcher
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class CommandRunner:
|
|
17
|
-
"""
|
|
18
|
-
Command line utility for executing commands.
|
|
19
|
-
|
|
20
|
-
Converts command line arguments into dispatcher command calls.
|
|
21
|
-
Provides ability to get help information about commands.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def __init__(self, dispatcher: BaseDispatcher):
|
|
25
|
-
"""
|
|
26
|
-
Initializes CommandRunner.
|
|
27
|
-
|
|
28
|
-
Args:
|
|
29
|
-
dispatcher: Command dispatcher for executing commands
|
|
30
|
-
"""
|
|
31
|
-
self.dispatcher = dispatcher
|
|
32
|
-
|
|
33
|
-
def build_parser(self) -> argparse.ArgumentParser:
|
|
34
|
-
"""
|
|
35
|
-
Creates argument parser based on registered commands.
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
Command line argument parser
|
|
39
|
-
"""
|
|
40
|
-
parser = argparse.ArgumentParser(
|
|
41
|
-
description="Execute commands from command registry",
|
|
42
|
-
add_help=False, # Disable standard help
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
# Add main arguments
|
|
46
|
-
parser.add_argument(
|
|
47
|
-
"command",
|
|
48
|
-
help="Command name to execute or 'help' to get list of commands",
|
|
49
|
-
nargs="?",
|
|
50
|
-
default="help",
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
parser.add_argument(
|
|
54
|
-
"--help", "-h",
|
|
55
|
-
action="store_true",
|
|
56
|
-
help="Show help for specified command",
|
|
57
|
-
dest="show_help",
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
parser.add_argument(
|
|
61
|
-
"--json",
|
|
62
|
-
action="store_true",
|
|
63
|
-
help="Output result in JSON format",
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
return parser
|
|
67
|
-
|
|
68
|
-
def _handle_help_command(self, args: Optional[List[str]] = None) -> None:
|
|
69
|
-
"""
|
|
70
|
-
Outputs help information about available commands.
|
|
71
|
-
|
|
72
|
-
Args:
|
|
73
|
-
args: List of arguments, if first argument is command name,
|
|
74
|
-
outputs help for that command
|
|
75
|
-
"""
|
|
76
|
-
if args and len(args) > 0 and args[0] != "help":
|
|
77
|
-
# Help for specific command
|
|
78
|
-
command_name = args[0]
|
|
79
|
-
if command_name not in self.dispatcher.get_valid_commands():
|
|
80
|
-
print(f"Unknown command: {command_name}", file=sys.stderr)
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
info = self.dispatcher.get_command_info(command_name)
|
|
84
|
-
|
|
85
|
-
print(f"\nCommand: {command_name}\n")
|
|
86
|
-
|
|
87
|
-
if info.get("description"):
|
|
88
|
-
print(f"Description: {info['description']}\n")
|
|
89
|
-
|
|
90
|
-
if "parameters" in info and info["parameters"]:
|
|
91
|
-
print("Parameters:")
|
|
92
|
-
for name, param_info in info["parameters"].items():
|
|
93
|
-
param_type = param_info.get("type", "any")
|
|
94
|
-
required = param_info.get("required", False)
|
|
95
|
-
description = param_info.get("description", "")
|
|
96
|
-
|
|
97
|
-
req_str = " (required)" if required else ""
|
|
98
|
-
print(f" {name} ({param_type}){req_str}")
|
|
99
|
-
if description:
|
|
100
|
-
print(f" {description}")
|
|
101
|
-
print()
|
|
102
|
-
|
|
103
|
-
if "returns" in info and info["returns"]:
|
|
104
|
-
print(f"Returns: {info['returns']}")
|
|
105
|
-
|
|
106
|
-
print("\nUsage:")
|
|
107
|
-
params_str = " ".join(
|
|
108
|
-
f"--{name}=<value>" for name in info.get("parameters", {})
|
|
109
|
-
)
|
|
110
|
-
print(f" python -m command_registry.cli {command_name} {params_str}")
|
|
111
|
-
else:
|
|
112
|
-
# General help
|
|
113
|
-
commands = self.dispatcher.get_commands_info()
|
|
114
|
-
|
|
115
|
-
print("\nAvailable commands:\n")
|
|
116
|
-
for name, info in commands.items():
|
|
117
|
-
description = info.get("description", "No description")
|
|
118
|
-
# Show only first line of description for brevity
|
|
119
|
-
short_desc = description.split("\n")[0]
|
|
120
|
-
print(f" {name:<20} {short_desc}")
|
|
121
|
-
|
|
122
|
-
print("\nTo get detailed information about a command use:")
|
|
123
|
-
print(" python -m command_registry.cli help <command>")
|
|
124
|
-
print(" python -m command_registry.cli <command> --help")
|
|
125
|
-
|
|
126
|
-
def run(self, args: Sequence[str]) -> None:
|
|
127
|
-
"""
|
|
128
|
-
Runs command based on provided arguments.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
args: Command line arguments (without program name)
|
|
132
|
-
"""
|
|
133
|
-
parser = self.build_parser()
|
|
134
|
-
|
|
135
|
-
# Parse arguments
|
|
136
|
-
parsed_args, remaining = parser.parse_known_args(args)
|
|
137
|
-
|
|
138
|
-
# Handle help command or --help flag
|
|
139
|
-
if parsed_args.command == "help" or parsed_args.show_help:
|
|
140
|
-
if parsed_args.command == "help":
|
|
141
|
-
self._handle_help_command(remaining)
|
|
142
|
-
else:
|
|
143
|
-
self._handle_help_command([parsed_args.command])
|
|
144
|
-
return
|
|
145
|
-
|
|
146
|
-
# Check command existence
|
|
147
|
-
if parsed_args.command not in self.dispatcher.get_valid_commands():
|
|
148
|
-
print(f"Unknown command: {parsed_args.command}", file=sys.stderr)
|
|
149
|
-
print("Use 'help' to get list of available commands", file=sys.stderr)
|
|
150
|
-
sys.exit(1)
|
|
151
|
-
|
|
152
|
-
# Convert remaining arguments to command parameters
|
|
153
|
-
command_params = {}
|
|
154
|
-
command_info = self.dispatcher.get_command_info(parsed_args.command)
|
|
155
|
-
expected_params = command_info.get("parameters", {})
|
|
156
|
-
|
|
157
|
-
# Parse parameters from remaining arguments
|
|
158
|
-
i = 0
|
|
159
|
-
while i < len(remaining):
|
|
160
|
-
arg = remaining[i]
|
|
161
|
-
|
|
162
|
-
# Support --param=value format
|
|
163
|
-
if arg.startswith("--") and "=" in arg:
|
|
164
|
-
param_name, value = arg[2:].split("=", 1)
|
|
165
|
-
command_params[param_name] = self._parse_value(value)
|
|
166
|
-
i += 1
|
|
167
|
-
# Support --param value format
|
|
168
|
-
elif arg.startswith("--"):
|
|
169
|
-
param_name = arg[2:]
|
|
170
|
-
if i + 1 < len(remaining) and not remaining[i + 1].startswith("--"):
|
|
171
|
-
command_params[param_name] = self._parse_value(remaining[i + 1])
|
|
172
|
-
i += 2
|
|
173
|
-
else:
|
|
174
|
-
# Boolean flag
|
|
175
|
-
command_params[param_name] = True
|
|
176
|
-
i += 1
|
|
177
|
-
else:
|
|
178
|
-
print(f"Unknown argument: {arg}", file=sys.stderr)
|
|
179
|
-
i += 1
|
|
180
|
-
|
|
181
|
-
# Check required parameters
|
|
182
|
-
for param_name, param_info in expected_params.items():
|
|
183
|
-
if param_info.get("required", False) and param_name not in command_params:
|
|
184
|
-
print(f"Missing required parameter: {param_name}", file=sys.stderr)
|
|
185
|
-
sys.exit(1)
|
|
186
|
-
|
|
187
|
-
try:
|
|
188
|
-
# Execute command
|
|
189
|
-
result = self.dispatcher.execute(parsed_args.command, **command_params)
|
|
190
|
-
|
|
191
|
-
# Output result
|
|
192
|
-
if parsed_args.json:
|
|
193
|
-
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
194
|
-
elif result is not None:
|
|
195
|
-
print(result)
|
|
196
|
-
except Exception as e:
|
|
197
|
-
print(f"Error executing command: {e}", file=sys.stderr)
|
|
198
|
-
sys.exit(1)
|
|
199
|
-
|
|
200
|
-
def _parse_value(self, value_str: str) -> Any:
|
|
201
|
-
"""
|
|
202
|
-
Parses string value into corresponding type.
|
|
203
|
-
|
|
204
|
-
Args:
|
|
205
|
-
value_str: String representation of value
|
|
206
|
-
|
|
207
|
-
Returns:
|
|
208
|
-
Parsed value of corresponding type
|
|
209
|
-
"""
|
|
210
|
-
# Boolean values
|
|
211
|
-
if value_str.lower() in ("true", "yes", "y", "1"):
|
|
212
|
-
return True
|
|
213
|
-
if value_str.lower() in ("false", "no", "n", "0"):
|
|
214
|
-
return False
|
|
215
|
-
|
|
216
|
-
# Numbers
|
|
217
|
-
try:
|
|
218
|
-
if "." in value_str:
|
|
219
|
-
return float(value_str)
|
|
220
|
-
return int(value_str)
|
|
221
|
-
except ValueError:
|
|
222
|
-
pass
|
|
223
|
-
|
|
224
|
-
# JSON
|
|
225
|
-
if (value_str.startswith("{") and value_str.endswith("}")) or \
|
|
226
|
-
(value_str.startswith("[") and value_str.endswith("]")):
|
|
227
|
-
try:
|
|
228
|
-
return json.loads(value_str)
|
|
229
|
-
except json.JSONDecodeError:
|
|
230
|
-
pass
|
|
231
|
-
|
|
232
|
-
# Default - string
|
|
233
|
-
return value_str
|
dispatchers/__init__.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Command dispatchers for registering and executing commands.
|
|
3
|
-
|
|
4
|
-
This module contains base classes and implementations of command dispatchers
|
|
5
|
-
that are responsible for registering and executing commands.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from .base_dispatcher import BaseDispatcher
|
|
9
|
-
from .json_rpc_dispatcher import JsonRpcDispatcher
|
|
10
|
-
|
|
11
|
-
__all__ = [
|
|
12
|
-
'BaseDispatcher',
|
|
13
|
-
'JsonRpcDispatcher',
|
|
14
|
-
]
|
dispatchers/base_dispatcher.py
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Base command dispatcher class.
|
|
3
|
-
"""
|
|
4
|
-
from abc import ABC, abstractmethod
|
|
5
|
-
from typing import Dict, Any, Callable, List, Optional
|
|
6
|
-
|
|
7
|
-
class BaseDispatcher(ABC):
|
|
8
|
-
"""
|
|
9
|
-
Abstract base class for command dispatchers.
|
|
10
|
-
|
|
11
|
-
Defines the interface that all command dispatchers must implement.
|
|
12
|
-
Dispatchers are responsible for registering and executing commands.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
@abstractmethod
|
|
16
|
-
def register_handler(
|
|
17
|
-
self,
|
|
18
|
-
command: str,
|
|
19
|
-
handler: Callable,
|
|
20
|
-
description: str = "",
|
|
21
|
-
summary: str = "",
|
|
22
|
-
params: Dict[str, Any] = None
|
|
23
|
-
) -> None:
|
|
24
|
-
"""
|
|
25
|
-
Registers a command handler.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
command: Command name
|
|
29
|
-
handler: Command handler function
|
|
30
|
-
description: Command description
|
|
31
|
-
summary: Brief command summary
|
|
32
|
-
params: Command parameters description
|
|
33
|
-
"""
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
@abstractmethod
|
|
37
|
-
def execute(self, command: str, **kwargs) -> Any:
|
|
38
|
-
"""
|
|
39
|
-
Executes a command with the specified parameters.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
command: Command name
|
|
43
|
-
**kwargs: Command parameters
|
|
44
|
-
|
|
45
|
-
Returns:
|
|
46
|
-
Any: Command execution result
|
|
47
|
-
|
|
48
|
-
Raises:
|
|
49
|
-
CommandNotFoundError: If command is not found
|
|
50
|
-
CommandExecutionError: On command execution error
|
|
51
|
-
"""
|
|
52
|
-
pass
|
|
53
|
-
|
|
54
|
-
@abstractmethod
|
|
55
|
-
def get_valid_commands(self) -> List[str]:
|
|
56
|
-
"""
|
|
57
|
-
Returns a list of all registered command names.
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
List[str]: List of command names
|
|
61
|
-
"""
|
|
62
|
-
pass
|
|
63
|
-
|
|
64
|
-
@abstractmethod
|
|
65
|
-
def get_command_info(self, command: str) -> Optional[Dict[str, Any]]:
|
|
66
|
-
"""
|
|
67
|
-
Returns information about a command.
|
|
68
|
-
|
|
69
|
-
Args:
|
|
70
|
-
command: Command name
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
Optional[Dict[str, Any]]: Command information or None if command not found
|
|
74
|
-
"""
|
|
75
|
-
pass
|
|
76
|
-
|
|
77
|
-
@abstractmethod
|
|
78
|
-
def get_commands_info(self) -> Dict[str, Dict[str, Any]]:
|
|
79
|
-
"""
|
|
80
|
-
Returns information about all registered commands.
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
Dict[str, Dict[str, Any]]: Dictionary {command_name: information}
|
|
84
|
-
"""
|
|
85
|
-
pass
|