Initial commit: BtToxin Pipeline project structure
This commit is contained in:
98
backend/app/api/v1/jobs.py
Normal file
98
backend/app/api/v1/jobs.py
Normal file
@@ -0,0 +1,98 @@
|
||||
"""任务管理 API"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
import uuid
|
||||
import shutil
|
||||
|
||||
from ...database import get_db
|
||||
from ...models.job import Job, JobStatus
|
||||
from ...schemas.job import JobResponse
|
||||
from ...workers.tasks import run_bttoxin_analysis
|
||||
from ...config import settings
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
UPLOAD_DIR = Path(settings.UPLOAD_DIR)
|
||||
RESULTS_DIR = Path(settings.RESULTS_DIR)
|
||||
UPLOAD_DIR.mkdir(exist_ok=True)
|
||||
RESULTS_DIR.mkdir(exist_ok=True)
|
||||
|
||||
@router.post("/create", response_model=JobResponse)
|
||||
async def create_job(
|
||||
files: List[UploadFile] = File(...),
|
||||
sequence_type: str = "nucl",
|
||||
scaf_suffix: str = ".fna",
|
||||
threads: int = 4,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""创建新任务"""
|
||||
job_id = str(uuid.uuid4())
|
||||
|
||||
job_input_dir = UPLOAD_DIR / job_id
|
||||
job_output_dir = RESULTS_DIR / job_id
|
||||
job_input_dir.mkdir(parents=True)
|
||||
job_output_dir.mkdir(parents=True)
|
||||
|
||||
uploaded_files = []
|
||||
for file in files:
|
||||
file_path = job_input_dir / file.filename
|
||||
with open(file_path, "wb") as buffer:
|
||||
shutil.copyfileobj(file.file, buffer)
|
||||
uploaded_files.append(file.filename)
|
||||
|
||||
job = Job(
|
||||
id=job_id,
|
||||
status=JobStatus.PENDING,
|
||||
input_files=uploaded_files,
|
||||
sequence_type=sequence_type,
|
||||
scaf_suffix=scaf_suffix,
|
||||
threads=threads
|
||||
)
|
||||
|
||||
db.add(job)
|
||||
db.commit()
|
||||
db.refresh(job)
|
||||
|
||||
task = run_bttoxin_analysis.delay(
|
||||
job_id=job_id,
|
||||
input_dir=str(job_input_dir),
|
||||
output_dir=str(job_output_dir),
|
||||
sequence_type=sequence_type,
|
||||
scaf_suffix=scaf_suffix,
|
||||
threads=threads
|
||||
)
|
||||
|
||||
job.celery_task_id = task.id
|
||||
db.commit()
|
||||
|
||||
return job
|
||||
|
||||
@router.get("/{job_id}", response_model=JobResponse)
|
||||
async def get_job(job_id: str, db: Session = Depends(get_db)):
|
||||
"""获取任务详情"""
|
||||
job = db.query(Job).filter(Job.id == job_id).first()
|
||||
if not job:
|
||||
raise HTTPException(status_code=404, detail="Job not found")
|
||||
return job
|
||||
|
||||
@router.get("/{job_id}/progress")
|
||||
async def get_job_progress(job_id: str, db: Session = Depends(get_db)):
|
||||
"""获取任务进度"""
|
||||
job = db.query(Job).filter(Job.id == job_id).first()
|
||||
if not job:
|
||||
raise HTTPException(status_code=404, detail="Job not found")
|
||||
|
||||
if job.celery_task_id:
|
||||
from ...core.celery_app import celery_app
|
||||
task = celery_app.AsyncResult(job.celery_task_id)
|
||||
|
||||
return {
|
||||
'job_id': job_id,
|
||||
'status': job.status,
|
||||
'celery_state': task.state,
|
||||
'progress': task.info if task.state == 'PROGRESS' else None
|
||||
}
|
||||
|
||||
return {'job_id': job_id, 'status': job.status}
|
||||
Reference in New Issue
Block a user