<commit_before>import sys
from multiprocessing.pool import ThreadPool
import traceback

from cloudshell.core.logger.qs_logger import get_qs_logger
from cloudshell.helpers.scripts import cloudshell_scripts_helpers as api_helpers

from cloudshell.workflow.orchestration.apps_configuration import AppsConfiguration
from cloudshell.workflow.orchestration.components import Components
from cloudshell.workflow.orchestration.workflow import Workflow
from cloudshell.workflow.profiler.env_profiler import profileit
from cloudshell.workflow.helpers import sandbox_helpers as helpers

class Sandbox(object):
    def __init__(self):
        self.automation_api = api_helpers.get_api_session()
        self.workflow = Workflow(self)

        self.connectivityContextDetails = helpers.get_connectivity_context_details()
        self.reservationContextDetails = helpers.get_reservation_context_details()
        self.global_inputs = helpers.get_global_inputs()
        self.additional_info_inputs = helpers.get_resource_additional_info_inputs()
        self.requirement_inputs = helpers.get_resource_requirement_inputs()
        self.id = self.reservationContextDetails.id

        reservation_description = self.automation_api.GetReservationDetails(self.id).ReservationDescription

        self.components = Components(reservation_description.Resources,
                                     reservation_description.Services,
                                     reservation_description.Apps)

        self.logger = get_qs_logger(log_file_prefix='CloudShell Sandbox Orchestration',
                                    log_group=self.id,
                                    log_category='Orchestration')

        self.apps_configuration = AppsConfiguration(sandbox=self)

    @profileit(scriptName='Setup')
    def execute_setup(self):
        api = self.automation_api

        self.logger.info('Setup execution started')

        api.WriteMessageToReservationOutput(reservationId=self.id,
                                            message='Beginning sandbox setup')

        ## prepare sandbox stage
        self.logger.info('Preparing connectivity for sandbox. ')
        api.WriteMessageToReservationOutput(reservationId=self.id, message='Preparing connectivity')
        api.PrepareSandboxConnectivity(self.id)

        self.automation_api.SetSetupStage('Provisioning', self.id)

        self._execute_stage(self.workflow._provisioning_functions, Workflow.PROVISIONING_STAGE_NAME)

        self._after_stage_ended(self.workflow._after_provisioning, Workflow.ON_PROVISIONING_ENDED_STAGE_NAME)

        self.automation_api.SetSetupStage('Connectivity', self.id)

        self._execute_stage(self.workflow._connectivity_functions, Workflow.CONNECTIVITY_STAGE_NAME)

        self._after_stage_ended(self.workflow._after_connectivity, Workflow.ON_CONNECTIVITY_ENDED_STAGE_NAME)

        self.automation_api.SetSetupStage('Configuration', self.id)

        self.components.refresh_components(self)

        self._execute_stage(self.workflow._configuration_functions, Workflow.CONFIGURATION_STAGE_NAME)

        self._after_stage_ended(self.workflow._after_configuration, Workflow.ON_CONFIGURATION_ENDED_STAGE_NAME)

        self.automation_api.SetSetupStage('Ended', self.id)

        self.logger.info('Setup for sandbox {0} completed'.format(self.id))

        api.WriteMessageToReservationOutput(reservationId=self.id,
                                            message='Sandbox setup finished successfully')

    @profileit(scriptName='Teardown')
    def execute_teardown(self):
        if self.workflow._teardown is None:
            self.logger.info('No teardown process was configured for the sandbox')

        else:
            self.logger.info('Teardown execution started')

            self._execute_workflow_process(self.workflow._teardown.function, self.workflow._teardown.components)

            self.logger.info('Teardown for sandbox {0} completed'.format(self.id))

            self.automation_api.WriteMessageToReservationOutput(reservationId=self.id,
                                                message='Sandbox teardown finished successfully')

    def _execute_workflow_process(self, func, components):
        self.logger.info("Executing method: {0}. ".format(func.__name__))
        execution_failed = 0
        try:
            func(self, components)
        except Exception as exc:
            execution_failed = 1
            print exc
            self.logger.error("Error executing function '{0}'. detailed error: {1}, {2}".format(func.__name__, str(exc), str(traceback.format_exc())))
        return execution_failed

    def _execute_stage(self, workflow_objects, stage_name):
        """
         :param list[WorkflowObject] workflow_objects:
         :param str stage_name:
         :return:
         """<commit_msg>make sure exceptions will be printed even if they don't have a message property<commit_after>import sys
from multiprocessing.pool import ThreadPool
import traceback

from cloudshell.core.logger.qs_logger import get_qs_logger
from cloudshell.helpers.scripts import cloudshell_scripts_helpers as api_helpers

from cloudshell.workflow.orchestration.apps_configuration import AppsConfiguration
from cloudshell.workflow.orchestration.components import Components
from cloudshell.workflow.orchestration.workflow import Workflow
from cloudshell.workflow.profiler.env_profiler import profileit
from cloudshell.workflow.helpers import sandbox_helpers as helpers

class Sandbox(object):
    def __init__(self):
        self.automation_api = api_helpers.get_api_session()
        self.workflow = Workflow(self)

        self.connectivityContextDetails = helpers.get_connectivity_context_details()
        self.reservationContextDetails = helpers.get_reservation_context_details()
        self.global_inputs = helpers.get_global_inputs()
        self.additional_info_inputs = helpers.get_resource_additional_info_inputs()
        self.requirement_inputs = helpers.get_resource_requirement_inputs()
        self.id = self.reservationContextDetails.id

        reservation_description = self.automation_api.GetReservationDetails(self.id).ReservationDescription

        self.components = Components(reservation_description.Resources,
                                     reservation_description.Services,
                                     reservation_description.Apps)

        self.logger = get_qs_logger(log_file_prefix='CloudShell Sandbox Orchestration',
                                    log_group=self.id,
                                    log_category='Orchestration')

        self.apps_configuration = AppsConfiguration(sandbox=self)

    @profileit(scriptName='Setup')
    def execute_setup(self):
        api = self.automation_api

        self.logger.info('Setup execution started')

        api.WriteMessageToReservationOutput(reservationId=self.id,
                                            message='Beginning sandbox setup')

        ## prepare sandbox stage
        self.logger.info('Preparing connectivity for sandbox. ')
        api.WriteMessageToReservationOutput(reservationId=self.id, message='Preparing connectivity')
        api.PrepareSandboxConnectivity(self.id)

        self.automation_api.SetSetupStage('Provisioning', self.id)

        self._execute_stage(self.workflow._provisioning_functions, Workflow.PROVISIONING_STAGE_NAME)

        self._after_stage_ended(self.workflow._after_provisioning, Workflow.ON_PROVISIONING_ENDED_STAGE_NAME)

        self.automation_api.SetSetupStage('Connectivity', self.id)

        self._execute_stage(self.workflow._connectivity_functions, Workflow.CONNECTIVITY_STAGE_NAME)

        self._after_stage_ended(self.workflow._after_connectivity, Workflow.ON_CONNECTIVITY_ENDED_STAGE_NAME)

        self.automation_api.SetSetupStage('Configuration', self.id)

        self.components.refresh_components(self)

        self._execute_stage(self.workflow._configuration_functions, Workflow.CONFIGURATION_STAGE_NAME)

        self._after_stage_ended(self.workflow._after_configuration, Workflow.ON_CONFIGURATION_ENDED_STAGE_NAME)

        self.automation_api.SetSetupStage('Ended', self.id)

        self.logger.info('Setup for sandbox {0} completed'.format(self.id))

        api.WriteMessageToReservationOutput(reservationId=self.id,
                                            message='Sandbox setup finished successfully')

    @profileit(scriptName='Teardown')
    def execute_teardown(self):
        if self.workflow._teardown is None:
            self.logger.info('No teardown process was configured for the sandbox')

        else:
            self.logger.info('Teardown execution started')

            self._execute_workflow_process(self.workflow._teardown.function, self.workflow._teardown.components)

            self.logger.info('Teardown for sandbox {0} completed'.format(self.id))

            self.automation_api.WriteMessageToReservationOutput(reservationId=self.id,
                                                message='Sandbox teardown finished successfully')

    def _execute_workflow_process(self, func, components):
        self.logger.info("Executing method: {0}. ".format(func.__name__))
        execution_failed = 0
        try:
            func(self, components)

        except Exception as exc:
            execution_failed = 1
            error = exc.message
            if not error or not isinstance(exc.message, str):
                try:
                    error = str(exc)
                except Exception:
                    pass

            print error
            self.logger.error("Error executing function '{0}'. detailed error: {1}, {2}".format(func.__name__, str(error), str(traceback.format_exc())))

        return execution_failed

    def _execute_stage(self, workflow_objects, stage_name):
        """
         :param list[WorkflowObject] workflow_objects:
         :param str stage_name:
         :return:
         """
{'fraction_non_alphanumeric': 0.07779562336880144, 'fraction_numerical': 0.0016061031921300944, 'mean_word_length': 3.0599022004889975, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '138192', 'n_tokens_mistral': 2703, 'n_tokens_neox': 2622, 'n_words': 434}