272 lines
7.3 KiB
Python
Executable File
272 lines
7.3 KiB
Python
Executable File
'''
|
|
This Module contains Generic abstract classes.
|
|
'''
|
|
|
|
from abc import ABCMeta, abstractmethod
|
|
from typing import cast, Any, TypeVar
|
|
# from celery import Task
|
|
|
|
|
|
abs_attr_type = TypeVar('abs_attr_type')
|
|
|
|
class DummyAttribute:
|
|
'''
|
|
A Dummy Type for abstract_attribute to return.
|
|
'''
|
|
pass
|
|
|
|
def abstract_attribute(obj = None, type_ = Any) -> abs_attr_type:
|
|
'''
|
|
Use this to make abstract attributes of given type.
|
|
|
|
____________________________________________________________________________
|
|
|
|
Arguments:
|
|
|
|
obj : Any -> It takes the object when using it as a decorator.
|
|
|
|
type_ : Any -> Provide the type of variable you want to declear.
|
|
(Default = Any)
|
|
'''
|
|
_obj = cast(type_, obj)
|
|
if obj is None:
|
|
_obj = DummyAttribute()
|
|
_obj.__is_abstract_attribute__ = True # type: ignore
|
|
return cast(abs_attr_type, _obj)
|
|
|
|
|
|
class MyABCMeta(ABCMeta):
|
|
|
|
def __call__(cls, *args, **kwargs):
|
|
instance = ABCMeta.__call__(cls, *args, **kwargs)
|
|
abstract_attributes = {
|
|
name
|
|
for name in dir(instance)
|
|
if getattr(getattr(instance, name), '__is_abstract_attribute__', False)
|
|
}
|
|
if abstract_attributes:
|
|
raise NotImplementedError(
|
|
"Can't instantiate abstract class {} with"
|
|
" abstract attributes: {}".format(
|
|
cls.__name__,
|
|
', '.join(abstract_attributes)
|
|
)
|
|
)
|
|
# return instance
|
|
|
|
# class GenericCeleryTask(Task,metaclass=MyABCMeta):
|
|
# '''
|
|
# This is a Abstract Class for implementation of Classs-Based
|
|
# Celery Tasks for MNF.
|
|
|
|
# It contains all the necessary methods that must be implemented
|
|
# by and any class inheriting it to be in-lined with the integration.
|
|
|
|
# Do read the doc-scrings of each method for insites.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# This Class itself inherits from Task which is the main Class for
|
|
# celery class-bases task implementation.
|
|
|
|
# For reference of implementation of GenericCeleryTask, checkout neutralAudit
|
|
# /tasks.py.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# By Amulya Paritosh
|
|
# '''
|
|
|
|
# track_started = True
|
|
# '''
|
|
# If enabled the task will report its status as 'started' when the task
|
|
# is executed by a worker. Disabled by default as the normal behavior
|
|
# is to not report that level of granularity. Tasks are either pending,
|
|
# finished, or waiting to be retried.
|
|
# '''
|
|
|
|
# name : str = abstract_attribute(type_ = str)
|
|
# '''
|
|
# This is an attribute which must be defined.
|
|
|
|
# `name = <app_name.module.class>`
|
|
# '''
|
|
|
|
# soft_time_limit : int = abstract_attribute(type_ = int)
|
|
# '''
|
|
# This is an attribute which must be defined.
|
|
|
|
# This is the time limit for which the task will run. If this time limit
|
|
# is exceeded, SoftTimeLimitExceeded error will be raised.
|
|
# '''
|
|
|
|
|
|
# @abstractmethod
|
|
# def to_run(self) -> bool:
|
|
# '''
|
|
# Put logic of checking if the queued task is to be run or not.
|
|
|
|
# This to_run function is the part of 2nd block of `run()` method (check out
|
|
# `run()` method to know more about the logic blocks of running the task).
|
|
|
|
# This method must be called in `run()` method.
|
|
# '''
|
|
# ...
|
|
|
|
# @abstractmethod
|
|
# def after_return(self, status, retval, task_id, args, kwargs, einfo) -> None:
|
|
# '''
|
|
# Handler called after the task returns.
|
|
|
|
# This method is called when the task returns irrespective of its success or
|
|
# failure.
|
|
|
|
# Can be used for freeing resources and deleting objects.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Arguments:
|
|
|
|
# status (str): Current task state.
|
|
|
|
# retval (Any): Task return value/exception.
|
|
|
|
# task_id (str): Unique id of the task.
|
|
|
|
# args (Tuple): Original arguments for the task.
|
|
|
|
# kwargs (Dict): Original keyword arguments for the task.
|
|
|
|
# einfo (~billiard.einfo.ExceptionInfo): Exception information.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Returns:
|
|
|
|
# None: The return value of this handler is ignored.
|
|
# '''
|
|
# ...
|
|
|
|
# @abstractmethod
|
|
# def on_failure(self, exc, task_id, args, kwargs, einfo) -> None:
|
|
# '''
|
|
# Error handler.
|
|
|
|
# This is run by the worker when the task fails.
|
|
|
|
# Put a control for expected exceptions here for their special handling.
|
|
# Check with `is_expected_exceptions()` static classmethod.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Arguments:
|
|
|
|
# exc (Exception): The exception raised by the task.
|
|
|
|
# task_id (str): Unique id of the failed task.
|
|
|
|
# args (Tuple): Original arguments for the task that failed.
|
|
|
|
# kwargs (Dict): Original keyword arguments for the task that failed.
|
|
|
|
# einfo (~billiard.einfo.ExceptionInfo): Exception information.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Returns:
|
|
# None: The return value of this handler is ignored.
|
|
# '''
|
|
# ...
|
|
|
|
# @abstractmethod
|
|
# def on_success(self, retval, task_id, args, kwargs) -> None:
|
|
# '''
|
|
# Success handler.
|
|
|
|
# Run by the worker if the task executes successfully.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Arguments:
|
|
|
|
# retval (Any): The return value of the task.
|
|
|
|
# task_id (str): Unique id of the executed task.
|
|
|
|
# args (Tuple): Original arguments for the executed task.
|
|
|
|
# kwargs (Dict): Original keyword arguments for the executed task.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Returns:
|
|
# None: The return value of this handler is ignored.
|
|
# '''
|
|
# ...
|
|
|
|
# @abstractmethod
|
|
# def on_retry(self, exc, task_id, args, kwargs, einfo) -> None:
|
|
# '''
|
|
# Retry handler.
|
|
|
|
# This is run by the worker when the task is to be retried.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Arguments:
|
|
|
|
# exc (Exception): The exception sent to :meth:`retry`.
|
|
|
|
# task_id (str): Unique id of the retried task.
|
|
|
|
# args (Tuple): Original arguments for the retried task.
|
|
|
|
# kwargs (Dict): Original keyword arguments for the retried task.
|
|
|
|
# einfo (~billiard.einfo.ExceptionInfo): Exception information.
|
|
|
|
# ____________________________________________________________________________
|
|
|
|
# Returns:
|
|
# None: The return value of this handler is ignored.
|
|
# '''
|
|
# ...
|
|
|
|
# @abstractmethod
|
|
# def run(self, *args, **kwargs) -> None:
|
|
# '''
|
|
# The body of the task executed by workers. Here write the main code blocks to
|
|
# be run.
|
|
|
|
# The Logic should be written in 3 blocks (its just a convention)
|
|
|
|
# block1 : initialization of certian required fields.
|
|
|
|
# block2 : check if to go ahed with the execution with to_run() method.
|
|
|
|
# block3 : main block of the code to run.
|
|
# '''
|
|
# ...
|
|
|
|
# @classmethod
|
|
# def is_expected_exceptions(cls, exc) -> bool:
|
|
# '''
|
|
# This checks if the provided exception was expected or not.
|
|
# ____________________________________________________________________________
|
|
|
|
# Returns :
|
|
# bool
|
|
# '''
|
|
# return isinstance(exc, cls.throws)
|
|
|
|
|
|
class ABCFileType(metaclass=MyABCMeta):
|
|
"""
|
|
All FileTypes to inherit it.
|
|
Contains some must have attributes.
|
|
"""
|
|
allowed_extentions : tuple = abstract_attribute(type_ = tuple)
|
|
|
|
def validate() -> bool:
|
|
return True
|