コード例 #1
0
class AbstractTask:
    def __init__(self, priority=0, type=''):
        '''Initializates the AbstractTask and generates assigns an
        unique task_id as combintaion of:
        task_{type}_{uuid4}

        :return Class instance
        '''
        self.priority = priority
        self.creation_time = datetime.now()
        self.type = type
        self.execution_information = None

        # For instance:
        # task_Api-request_63f1bd71-f441-4519-8a41-44643ccb4dad
        self._task_id = \
            f'task_{type}_{uuid.uuid4()}'

        self.logger = CustomLogger(__name__)
        #print("LOGGER", self.logger)
        self.logger.info(f"{self._task_id}")

    @property
    def task_id(self):
        return self._task_id

    @task_id.setter
    def task_id(self, value):
        self._task_id = value

    @abstractmethod
    def execute(self):
        pass
コード例 #2
0
 def __init__(self, priority, config: ConfigApiRequestTask):
     ''' Instantiates an Api request task
     :param priority: from 0 (most important) to any greater integer
     :param config(ConfigApiRequestTask): Configuration parameters
     '''
     super().__init__(priority, type='Api-request')
     self.config = config
     self.logger = CustomLogger(__name__)
コード例 #3
0
    def __init__(self, params, db_connection: MongoDbConnection=None,
                 dynamic_configs=None):
        self.type_task = params["type_task"]
        self.configuration_id = params["configuration_id"]
        if db_connection is None:
            self.connection_to_db = current_app.mongo_connection
            # self.connection_to_db = g.db # global db connection
        else:
            self.connection_to_db = db_connection
        self.dynamic_configs = params.get('dynamic_configs', {})

        self.result = None
        self.errors = None
        self.logger = CustomLogger(__name__)
コード例 #4
0
ファイル: db_task.py プロジェクト: strymsg/task-scheduler-at
    def __init__(self, priority, config:ConfigDbTask):
        """Instantiates a Database task
        ...
        Attributes
        ----------
        priority : int
            a number from 0 (most important) to any greater integer
        config : ConfigDbTask
            a configuration object containing the parameters nedded to run the task 
        """
        super().__init__(priority, type='Db')
        self.config = config

        self.config.db_connection.connect()
        self.logger = CustomLogger(__name__)
コード例 #5
0
ファイル: db_task.py プロジェクト: strymsg/task-scheduler-at
class DbTask(AbstractTask):
    """This class defines the operations to be performed with a specific DB
    ...
    Attributes
    ----------
    priority : int
        number assigns a level of priority to run the task
    config : ConfigDbTask
        a configuration object containing the parameters nedded to run the task 
    Methods
    -------
    validate():
        Verifies the content of a given data before makes a query to the DB.
    insert():
        Inserts a given data into a specific DB.
    get():
        Get a given data from a specific DB.
    delete():
        Deletes a given data from a specific DB.
    update():
        Updates a given data from a specific DB.
    """
    def __init__(self, priority, config:ConfigDbTask):
        """Instantiates a Database task
        ...
        Attributes
        ----------
        priority : int
            a number from 0 (most important) to any greater integer
        config : ConfigDbTask
            a configuration object containing the parameters nedded to run the task 
        """
        super().__init__(priority, type='Db')
        self.config = config

        self.config.db_connection.connect()
        self.logger = CustomLogger(__name__)

    def insert(self):  
        return self.config.db_connection.insert(self.config.query, self.config.key_id)
 
    def get(self):
        return self.config.db_connection.get(self.config.key_id)
 
    def update(self):
        return self.config.db_connection.update(self.config.key_id, self.config.query)
 
    def delete(self):
        return self.config.db_connection.delete(self.config.key_id)
 
    def execute(self):
        if self.config is None:
            self.logger.error("Need a configuration object to do query to the DB")
            raise  ConfigurationError("Need a configuration object to do query to the DB")
        else:
            if self.config.query_type.upper() == "INSERT":
                return self.insert()
            elif self.config.query_type.upper() == "GET":
                return self.get()
            elif self.config.query_type.upper() == "UPDATE":
                return self.update()
            elif self.config.query_type.upper() == "DELETE":
                return self.delete()
コード例 #6
0
class ApiRequestTask(AbstractTask):
    def __init__(self, priority, config: ConfigApiRequestTask):
        ''' Instantiates an Api request task
        :param priority: from 0 (most important) to any greater integer
        :param config(ConfigApiRequestTask): Configuration parameters
        '''
        super().__init__(priority, type='Api-request')
        self.config = config
        self.logger = CustomLogger(__name__)

    def do_request(self):
        '''Do api request using requests library using config object
        :return: dict with response objects cotaining:
        { 
          'json': <dict>, # json convertion or {}
          'text': <str>,  # string response
          'status_code': <str>, 
          'headers': <dict>,
          'url': <str>
         }
        If an error occurs it raises an HTTPError exceptio
        '''
        if self.config is None:
            raise Exception("Need a config object to do request")

        response = None
        try:
            # TODO: add support to send api_token
            response = requests.request(
                self.config.http_method.upper(),
                self.config.url,
                params=None,
                data=self.config.body,
                headers=self.config.headers,
                cookies=None,
                files=None,
                auth=None,
                timeout=None,
                allow_redirects=True,
                proxies=None,
                hooks=None,
                stream=None,
                verify=None,
                cert=None
            )
            response_json = {}
            try:
                response_json = response.json()
            except JSONDecodeError as json_err:
                pass
            res_dict = {
                'json': response_json,
                'text': response.text,
                'status_code': response.status_code,
                'headers': response.headers,
                'url': response.url
            }
            #self.logger.debug("Api-request executed")
            #self.logger.debug(res_dict)
            return res_dict
        # TODO: Log all exceptions
        except HTTPError as http_err:
            self.logger.info(f'HTTPError: {http_err}')
            raise http_err
        except RequestException as request_err:
            self.logger.info(f'RequestException: {request_err}')
            raise request_err
        except ConnectionError as conn_err:
            self.logger.info(f'ConnectionError: {conn_err}')
            raise conn_err
        except URLRequired as url_err: 
            self.logger.info(f'URLRequired: {url_err}')
            raise url_err

    def execute(self):
        ''' Performs an API request and returns 
        a dictionary with response results or raises exception
        '''
        try:
            response = self.do_request()
            return response
        except Exception as E:
            raise E
コード例 #7
0
class TaskManager:
    """
    Class used to execute a specific task with its configuration through the 
    RunTask endpoint request.
    ...
    Attributes
    ----------
    params : dict
    params[type_task]: str
        it is the type of the task e.g. "Api-request" or "Db" or "File" to be searched for
    params[configuration_id]: str
        it is the ID of the configuration to be searched for
    db_connection: MongoDbConnection
        the connection has to be passed to the Mongo DB
    Methods
    -------
    execute():
        Executes the task with its configuration 
    instantiate():
        Initializes the configuration object and the task object to be executed
    """ 

    def __init__(self, params, db_connection: MongoDbConnection=None,
                 dynamic_configs=None):
        self.type_task = params["type_task"]
        self.configuration_id = params["configuration_id"]
        if db_connection is None:
            self.connection_to_db = current_app.mongo_connection
            # self.connection_to_db = g.db # global db connection
        else:
            self.connection_to_db = db_connection
        self.dynamic_configs = params.get('dynamic_configs', {})

        self.result = None
        self.errors = None
        self.logger = CustomLogger(__name__)
        

    def run(self):
        """Executes the task and saves its results to the DB.
        It creates a config object and task result to be into Db using self.save_into_db()
        :returns: True if there is no error and False if some error occurs (logs it)
        """
        if self.type_task == "Api-request":
            self.config = ConfigApiRequestTask(**self.dynamic_configs)
            self.task = ApiRequestTask(
                priority=0, # fixed priority
                config=self.config
            )
        elif self.type_task == 'Db':
            self.config = ConfigDbTask(self.dynamic_configs)
            self.task = DbTask(
                            priority=0,
                            config=self.config
                            )
        elif self.type_task == 'File':
            self.config = ConfigFileTask(self.dynamic_configs)
            self.task = FileTask(
                            priority=0,
                            config=self.config
                            )
        
        try:
            self.result = self.task.execute()
        except Exception as e:
            self.errors = str(e)
            self.logger.error(f'Error executing task: {self.errors}')
            return False
        
        res = self.save_into_db()
        return res

        
    def save_into_db(self):
        '''Saves the task execution results to the DB. Creates both documents
        config and task_results following the schema defined at docs/Mongo-schema.md
        
        :returns: A dict with task_result_id and config_id.
        Empty values if error occurs, errors are logged.
        '''
        config_dbobj = {}
        if self.type_task == "Api-request":
            config_dbobj = {
                #'_id': ObjectId(self.config['config_id']),
                'config_id': self.config.config_id,
                'url': self.config.url,
                'http_method': self.config.http_method,
                'headers': json.dumps(self.config.headers),
                'body': json.dumps(self.config.body),
                'api_token': self.config.api_token
                }
        elif self.type_task == 'Db':
            config_dbobj = {
                "config_id": self.config.config_id,
                "config_type": self.type_task,
                "key_id": self.config.key_id,
                "query_type": self.config.query_type,
                "query":  json.dumps(self.config.query),
                "connector": json.dumps(self.config.connector)
                }
        elif self.type_task == 'File':
            # TODO: implement
            pass

        task_resultdb = {
            "task_result_id": f"task-result_{uuid.uuid4()}",
            "runBy": "user",
            "time": dt.now().strftime('%d/%m/%Y %H:%M:%S'),
            "error_message": str(self.errors),
            "result": str(self.result)
            }

        task_obj = {
            "task_id": self.task.task_id,
            "creation_time": self.task.creation_time.strftime('%d/%m/%Y %H:%M:%S'),
            "priority": 0,
            "type": self.task.type,
            "config": self.config.config_id,
            "tasks_results": [task_resultdb["task_result_id"]]
        }

        try:
            self.connection_to_db.connect()
            self.connection_to_db.insert('config', config_dbobj)
            self.connection_to_db.insert('tasks', task_obj)
            self.connection_to_db.insert('task_result', task_resultdb)
            self.logger.info(f'Task execution saved to DB')
            return {
                'config_id': config_dbobj['config_id'],
                'task_id': task_obj['task_id'],
                'task_result_id': task_resultdb['task_result_id']
            }
        except Exception as err:
            self.logger.error(f'Error registering task results into db: {err}')
            return {'task_result_id': '', 'config_id': '', 'task_id': ''}
            
    # def execute(self):
    #     """Executes the task given the configs and saves its results in self object
    #     :return:
    #     """

    #     run_arg = {
    #         "type": self.type_task,
    #         "configs": ObjectId(self.configuration_id)
    #     }
    #     task_args = self.connection_to_db.get("tasks", run_arg)[0]
    #     config_args = self.connection_to_db.get("configs", {"_id":ObjectId(self.configuration_id)})[0]
    #     self.instantiate(task_args, config_args)
        
    #     try:
    #         self.result = self.task.execute()
    #         return self.result
    #     except Exception as e:
    #         self.errors = str(e)
    #         self.logger.info(f'Error executing task: {self.errors}')
    #         return self.errors

    # def instantiate(self, task_args, config_args):
    #     if self.type_task == "Api-request":
    #         self.config = ConfigApiRequestTask(config_args)
    #         self.task = ApiRequestTask(
    #                         priority=task_args["priority"],
    #                         config=self.config
    #                         )

    #     elif self.type_task == "Db":
    #         self.config = ConfigDbTask(config_args)
    #         self.task = DbTask(
    #                         priority=task_args["priority"],
    #                         config=self.config
    #                         )

    #     elif self.type_task == "File":
    #         self.config = ConfigFileTask(config_args)
    #         self.task = FileTask(
    #                         priority=task_args["priority"],
    #                         config=self.config
    #                         )