# Copyright (c) 2025 Patrick Motsch # All rights reserved. """ Trigger Preprocessing Server action for Context operations. Triggers preprocessing server at customer tenant to update database with configuration. """ import logging import json import aiohttp from typing import Dict, Any from modules.workflows.methods.methodBase import action from modules.datamodels.datamodelChat import ActionResult, ActionDocument from modules.shared.configuration import APP_CONFIG logger = logging.getLogger(__name__) @action async def triggerPreprocessingServer(self, parameters: Dict[str, Any]) -> ActionResult: """ Trigger preprocessing server at customer tenant to update database with configuration. This action makes a POST request to the preprocessing server endpoint with the provided configuration JSON. The authorization secret is retrieved from APP_CONFIG using the provided config key. Parameters: - endpoint (str, required): The full URL endpoint for the preprocessing server API. - configJson (dict or str, required): Configuration JSON object to send to the preprocessing server. Can be provided as a dict or as a JSON string that will be parsed. - authSecretConfigKey (str, required): The APP_CONFIG key name to retrieve the authorization secret from. Returns: - ActionResult with ActionDocument containing "ok" on success, or error message on failure. """ try: endpoint = parameters.get("endpoint") if not endpoint: return ActionResult.isFailure(error="endpoint parameter is required") configJsonParam = parameters.get("configJson") if not configJsonParam: return ActionResult.isFailure(error="configJson parameter is required") authSecretConfigKey = parameters.get("authSecretConfigKey") if not authSecretConfigKey: return ActionResult.isFailure(error="authSecretConfigKey parameter is required") # Handle configJson as either dict or JSON string if isinstance(configJsonParam, str): try: configJson = json.loads(configJsonParam) except json.JSONDecodeError as e: return ActionResult.isFailure(error=f"configJson is not valid JSON: {str(e)}") elif isinstance(configJsonParam, dict): configJson = configJsonParam else: return ActionResult.isFailure(error=f"configJson must be a dict or JSON string, got {type(configJsonParam)}") # Get authorization secret from APP_CONFIG using the provided config key authSecret = APP_CONFIG.get(authSecretConfigKey) if not authSecret: errorMsg = f"{authSecretConfigKey} not found in APP_CONFIG" logger.error(errorMsg) return ActionResult.isFailure(error=errorMsg) # Prepare headers with authorization (default headers as in original function) headers = { "X-PP-API-Key": authSecret, "Content-Type": "application/json" } # Make POST request timeout = aiohttp.ClientTimeout(total=60) async with aiohttp.ClientSession(timeout=timeout) as session: async with session.post( endpoint, headers=headers, json=configJson ) as response: if response.status in [200, 201]: responseText = await response.text() logger.info(f"Preprocessing server trigger successful: {response.status}") logger.debug(f"Response: {responseText}") # Generate meaningful filename workflowContext = self.services.chat.getWorkflowContext() if hasattr(self.services, 'chat') else None filename = self._generateMeaningfulFileName( "preprocessing_result", "txt", workflowContext, "triggerPreprocessingServer" ) # Create validation metadata validationMetadata = self._createValidationMetadata( "triggerPreprocessingServer", endpoint=endpoint, statusCode=response.status, responseText=responseText ) # Return success with "ok" document document = ActionDocument( documentName=filename, documentData="ok", mimeType="text/plain", validationMetadata=validationMetadata ) return ActionResult.isSuccess(documents=[document]) else: errorText = await response.text() errorMsg = f"Preprocessing server trigger failed: {response.status} - {errorText}" logger.error(errorMsg) return ActionResult.isFailure(error=errorMsg) except Exception as e: errorMsg = f"Error triggering preprocessing server: {str(e)}" logger.error(errorMsg) return ActionResult.isFailure(error=errorMsg)