# File: app/task_loader.py import os import json import importlib from app.celery_app import celery def register_tasks(app): project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) plugins_dir = os.path.join(project_root, 'plugins') task_modules = [] app.logger.info("🔌 Discovering Celery plugins…") for name in sorted(os.listdir(plugins_dir)): manifest = os.path.join(plugins_dir, name, 'plugin.json') if not os.path.isfile(manifest): continue try: meta = json.load(open(manifest)) except Exception as e: app.logger.error(f"[Celery] Failed to load {name}/plugin.json: {e}") continue # a) collect task modules cfg = meta.get('tasks') if isinstance(cfg, str): task_modules.append(cfg) elif isinstance(cfg, dict) and cfg.get('module'): task_modules.append(cfg['module']) elif isinstance(cfg, list): for entry in cfg: if isinstance(entry, str): task_modules.append(entry) elif isinstance(entry, dict) and entry.get('module'): task_modules.append(entry['module']) # b) run tasks_init hooks (now passing Celery, not Flask) for hook in meta.get('tasks_init', []): module_name = hook.get('module') fn_name = hook.get('callable') if not module_name or not fn_name: continue try: m = importlib.import_module(module_name) fn = getattr(m, fn_name) fn(celery) except Exception as e: app.logger.error(f"[Celery] tasks_init {name}:{module_name}.{fn_name} failed: {e}") if task_modules: celery.autodiscover_tasks(task_modules) app.logger.info(f"[Celery] Autodiscovered tasks: {task_modules}")