import logging from celery_progress.backend import ProgressRecorder, Progress try: from asgiref.sync import async_to_sync from channels.layers import get_channel_layer except ImportError: async_to_sync = get_channel_layer = None WEBSOCKETS_AVAILABLE = False else: WEBSOCKETS_AVAILABLE = get_channel_layer() logger = logging.getLogger(__name__) class WebSocketProgressRecorder(ProgressRecorder): @staticmethod def push_update(task_id): if WEBSOCKETS_AVAILABLE: try: channel_layer = get_channel_layer() async_to_sync(channel_layer.group_send)( task_id, {'type': 'update_task_progress', 'data': {**Progress(task_id).get_info()}} ) except AttributeError: # No channel layer to send to, so ignore it pass else: logger.info( 'Tried to use websocket progress bar, but dependencies were not installed / configured. ' 'Use pip install celery-progress[websockets] and setup channels to enable this feature.' 'See: https://channels.readthedocs.io/en/latest/ for more details.' ) def set_progress(self, current, total, description=""): super().set_progress(current, total, description) self.push_update(self.task.request.id) def stop_task(self, current, total, exc): super().stop_task(current, total, exc) self.push_update(self.task.request.id)