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
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>
109 lines
3.4 KiB
Python
Executable File
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()
|