|
42 | 42 | Config, |
43 | 43 | GlobalContext, |
44 | 44 | HookType, |
| 45 | + HttpHeaderPayload, |
| 46 | + HttpHeaderPayloadResult, |
45 | 47 | PluginCondition, |
46 | 48 | PluginContext, |
47 | 49 | PluginContextTable, |
@@ -431,6 +433,54 @@ async def post_resource_fetch(plugin: PluginRef, payload: ResourcePostFetchPaylo |
431 | 433 | return await plugin.plugin.resource_post_fetch(payload, context) |
432 | 434 |
|
433 | 435 |
|
| 436 | +async def pre_http_forwarding_call(plugin: PluginRef, payload: HttpHeaderPayload, context: PluginContext) -> HttpHeaderPayloadResult: |
| 437 | + """Call plugin's HTTP pre-forwarding call hook. |
| 438 | +
|
| 439 | + Args: |
| 440 | + plugin: The plugin to execute. |
| 441 | + payload: The set of HTTP headers to be analyzed. |
| 442 | + context: The plugin context. |
| 443 | +
|
| 444 | + Returns: |
| 445 | + Modified HTTP headers with processing status. |
| 446 | +
|
| 447 | + Examples: |
| 448 | + >>> from mcpgateway.plugins.framework.base import PluginRef |
| 449 | + >>> from mcpgateway.plugins.framework import Plugin, HttpHeaderPayload, PluginContext, GlobalContext |
| 450 | + >>> # Assuming you have a plugin instance: |
| 451 | + >>> # plugin_ref = PluginRef(my_plugin) |
| 452 | + >>> payload = HttpHeaderPayload({"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="}) |
| 453 | + >>> context = PluginContext(request_id="123") |
| 454 | + >>> # In async context: |
| 455 | + >>> # result = await pre_http_forwarding_call(plugin_ref, payload, context) |
| 456 | + """ |
| 457 | + return await plugin.plugin.http_pre_forwarding_call(payload, context) |
| 458 | + |
| 459 | + |
| 460 | +async def post_http_forwarding_call(plugin: PluginRef, payload: HttpHeaderPayload, context: PluginContext) -> HttpHeaderPayloadResult: |
| 461 | + """Call plugin's HTTP post-forwarding call hook. |
| 462 | +
|
| 463 | + Args: |
| 464 | + plugin: The plugin to execute. |
| 465 | + payload: The set of HTTP headers to be analyzed. |
| 466 | + context: The plugin context. |
| 467 | +
|
| 468 | + Returns: |
| 469 | + Modified HTTP headers with processing status. |
| 470 | +
|
| 471 | + Examples: |
| 472 | + >>> from mcpgateway.plugins.framework.base import PluginRef |
| 473 | + >>> from mcpgateway.plugins.framework import Plugin, HttpHeaderPayload, PluginContext, GlobalContext |
| 474 | + >>> # Assuming you have a plugin instance: |
| 475 | + >>> # plugin_ref = PluginRef(my_plugin) |
| 476 | + >>> payload = HttpHeaderPayload({"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="}) |
| 477 | + >>> context = PluginContext(request_id="123") |
| 478 | + >>> # In async context: |
| 479 | + >>> # result = await post_http_forwarding_call(plugin_ref, payload, context) |
| 480 | + """ |
| 481 | + return await plugin.plugin.http_post_forwarding_call(payload, context) |
| 482 | + |
| 483 | + |
434 | 484 | class PluginManager: |
435 | 485 | """Plugin manager for managing the plugin lifecycle. |
436 | 486 |
|
@@ -475,6 +525,7 @@ class PluginManager: |
475 | 525 | _post_tool_executor: PluginExecutor[ToolPostInvokePayload] = PluginExecutor[ToolPostInvokePayload]() |
476 | 526 | _resource_pre_executor: PluginExecutor[ResourcePreFetchPayload] = PluginExecutor[ResourcePreFetchPayload]() |
477 | 527 | _resource_post_executor: PluginExecutor[ResourcePostFetchPayload] = PluginExecutor[ResourcePostFetchPayload]() |
| 528 | + _http_executor: PluginExecutor[HttpHeaderPayload] = PluginExecutor[HttpHeaderPayload]() |
478 | 529 |
|
479 | 530 | # Context cleanup tracking |
480 | 531 | _context_store: Dict[str, Tuple[PluginContextTable, float]] = {} |
@@ -962,3 +1013,69 @@ async def resource_post_fetch( |
962 | 1013 | del self._context_store[global_context.request_id] |
963 | 1014 |
|
964 | 1015 | return result |
| 1016 | + |
| 1017 | + async def http_pre_forwarding_call( |
| 1018 | + self, payload: HttpHeaderPayload, global_context: GlobalContext, local_contexts: Optional[PluginContextTable] = None |
| 1019 | + ) -> tuple[HttpHeaderPayloadResult, PluginContextTable | None]: |
| 1020 | + """Execute pre-fetch hooks before an operation is called. |
| 1021 | +
|
| 1022 | + Args: |
| 1023 | + payload: The http payload containing http headers passed from requests to responses. |
| 1024 | + global_context: Shared context for all plugins with request metadata. |
| 1025 | + local_contexts: Optional existing contexts from previous hook executions. |
| 1026 | +
|
| 1027 | + Returns: |
| 1028 | + A tuple containing: |
| 1029 | + - HttpHeaderPayloadResult with processing status and modified headers |
| 1030 | + - PluginContextTable with plugin contexts for state management |
| 1031 | + """ |
| 1032 | + # Get plugins configured for this hook |
| 1033 | + plugins = self._registry.get_plugins_for_hook(HookType.HTTP_PRE_FORWARDING_CALL) |
| 1034 | + |
| 1035 | + def compare(payload: HttpHeaderPayload, conditions: list[PluginCondition], context: GlobalContext): |
| 1036 | + return True |
| 1037 | + |
| 1038 | + # Execute plugins |
| 1039 | + result = await self._http_executor.execute(plugins, payload, global_context, pre_http_forwarding_call, compare, local_contexts) |
| 1040 | + |
| 1041 | + # Store context for potential post-fetch |
| 1042 | + if result[1]: |
| 1043 | + self._context_store[global_context.request_id] = (result[1], time.time()) |
| 1044 | + |
| 1045 | + # Periodic cleanup |
| 1046 | + await self._cleanup_old_contexts() |
| 1047 | + |
| 1048 | + return result |
| 1049 | + |
| 1050 | + async def http_post_forwarding_call( |
| 1051 | + self, payload: HttpHeaderPayload, global_context: GlobalContext, local_contexts: Optional[PluginContextTable] = None |
| 1052 | + ) -> tuple[HttpHeaderPayloadResult, PluginContextTable | None]: |
| 1053 | + """Execute post-fetch hooks after an operation is complete. |
| 1054 | +
|
| 1055 | + Args: |
| 1056 | + payload: The http payload containing http headers passed from requests to responses. |
| 1057 | + global_context: Shared context for all plugins with request metadata. |
| 1058 | + local_contexts: Optional existing contexts from previous hook executions. |
| 1059 | +
|
| 1060 | + Returns: |
| 1061 | + A tuple containing: |
| 1062 | + - HttpHeaderPayloadResult with processing status and modified headers |
| 1063 | + - PluginContextTable with plugin contexts for state management |
| 1064 | + """ |
| 1065 | + # Get plugins configured for this hook |
| 1066 | + plugins = self._registry.get_plugins_for_hook(HookType.HTTP_POST_FORWARDING_CALL) |
| 1067 | + |
| 1068 | + def compare(payload: HttpHeaderPayload, conditions: list[PluginCondition], context: GlobalContext): |
| 1069 | + return True |
| 1070 | + |
| 1071 | + # Execute plugins |
| 1072 | + result = await self._http_executor.execute(plugins, payload, global_context, post_http_forwarding_call, compare, local_contexts) |
| 1073 | + |
| 1074 | + # Store context for potential post-fetch |
| 1075 | + if result[1]: |
| 1076 | + self._context_store[global_context.request_id] = (result[1], time.time()) |
| 1077 | + |
| 1078 | + # Periodic cleanup |
| 1079 | + await self._cleanup_old_contexts() |
| 1080 | + |
| 1081 | + return result |
0 commit comments