import json from app.tasks.worker import celery_app @celery_app.task(bind=True) def auto_classify_task(self, project_id: int, source_ids: list = None): """ Async task to run automatic classification on metadata. """ from app.core.database import SessionLocal from app.models.project import ClassificationProject from app.services.classification_engine import run_auto_classification db = SessionLocal() try: project = db.query(ClassificationProject).filter(ClassificationProject.id == project_id).first() if not project: return {"status": "failed", "reason": "project not found"} def progress_callback(scanned, matched, total): percent = int(scanned / total * 100) if total else 0 meta = { "scanned": scanned, "matched": matched, "total": total, "percent": percent, } self.update_state(state="PROGRESS", meta=meta) # Persist lightweight progress to DB for UI polling project.scan_progress = json.dumps(meta) db.commit() # Initialize project.status = "scanning" project.scan_progress = json.dumps({"scanned": 0, "matched": 0, "total": 0, "percent": 0}) db.commit() result = run_auto_classification( db, project_id, source_ids=source_ids, progress_callback=progress_callback, ) if result.get("success"): project.status = "assigning" else: project.status = "created" project.celery_task_id = None db.commit() return {"status": "completed", "project_id": project_id, "result": result} except Exception as e: db.rollback() project = db.query(ClassificationProject).filter(ClassificationProject.id == project_id).first() if project: project.status = "created" project.celery_task_id = None db.commit() return {"status": "failed", "reason": str(e)} finally: db.close()