Files
xiaoxia-saas/apps/worker/worker_app/tasks/classification.py
T
CI Bot 1a57878f76
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 1m12s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 2m17s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 1m33s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 3m14s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
chore(backend): Phase 3 清理 — 未使用依赖删除 + pyflakes 警告清零 + 测试文件冗余清理
1. 未使用依赖清理:
   - 从 requirements-base.txt 移除 cryptography 和 pyOpenSSL

2. pyflakes 警告清零 (apps/ + packages/ + tests/):
   - 移除 17 处未使用的 import (F401)
   - 修复 26 处未使用的局部变量 (F841):
     * 有副作用的赋值转为裸调用
     * 无副作用的赋值直接删除
   - 修复 1 处未使用的异常变量 (F841)
   - 修复 1 处空 except 块

3. 测试文件冗余清理:
   - 删除 tests/integration/test_project_management.py (模块级 skip,测试不存在的模块)
   - 删除 tests/integration/fixtures/duplication_routes_fixed.py (未被引用)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:14:46 +08:00

109 lines
3.4 KiB
Python
Executable File

from celery.utils.log import get_task_logger
from worker_app.celery_app import celery_app
from packages.adapters.sqlalchemy_impl.asset_repository import (
SQLAlchemyAssetRepository,
)
from packages.adapters.sqlalchemy_impl.classification_job_repository import (
SQLAlchemyClassificationJobRepository,
)
from packages.domain import (
ClassificationJobStatus,
ClassificationStatus,
)
from .asset_analyzer import classify_asset_real
logger = get_task_logger(__name__)
@celery_app.task(bind=True, name="worker.classify_asset", max_retries=2)
def classify_asset(self, job_id: str) -> dict:
"""
Classify asset task.
Steps:
1. Fetch ClassificationJob from repository
2. Fetch Asset from repository
3. Run real classification based on video features
4. Update ClassificationJob with result
5. Update Asset with classification and status
6. Return result
"""
from worker_app.db import SessionLocal
# 创建数据库 session 和 repository
session = SessionLocal()
try:
job_repo = SQLAlchemyClassificationJobRepository(session)
asset_repo = SQLAlchemyAssetRepository(session)
job = job_repo.get(job_id)
if job is None:
return {"status": "failed", "error": "job not found"}
try:
# Update job status to PROCESSING
job.status = ClassificationJobStatus.PROCESSING
job_repo.update(job)
session.commit()
# Get the asset to find the video path
asset = asset_repo.get(job.asset_id)
if asset is None:
raise ValueError(f"Asset not found: {job.asset_id}")
# Determine media path from storage_key
# In production, this would be a full URL/path to the media file
video_path = asset.storage_key
# Run real classification
classification, confidence = classify_asset_real(video_path)
# Update job with classification result
job.status = ClassificationJobStatus.COMPLETED
job.classification = classification
job.confidence = confidence
job_repo.update(job)
# Update asset with classification status and result
asset.classification_status = ClassificationStatus.COMPLETED
asset_repo.update(asset)
session.commit()
logger.info(
f"Classification completed for asset {asset.id}: " f"category={classification}, confidence={confidence}"
)
return {
"status": "completed",
"job_id": job.id,
"classification": classification,
"confidence": confidence,
}
except Exception as e:
session.rollback()
logger.error(f"Classification failed for job {job_id}: {e}")
# Update job status to FAILED
job.status = ClassificationJobStatus.FAILED
job.error_message = str(e)
job_repo.update(job)
# Update asset classification status to FAILED
asset = asset_repo.get(job.asset_id)
if asset:
asset.classification_status = ClassificationStatus.FAILED
asset_repo.update(asset)
session.commit()
return {
"status": "failed",
"job_id": job.id,
"error": str(e),
}
finally:
session.close()