- Backend: Refactored tasks.py to directly invoke run_single_fna_pipeline.py for consistency. - Backend: Changed output format to ZIP and added auto-cleanup of intermediate files. - Backend: Fixed language parameter passing in API and tasks. - Frontend: Removed CRISPR Fusion UI elements from Submit and Monitor views. - Frontend: Implemented simulated progress bar for better UX. - Frontend: Restored One-click load button and added result file structure documentation. - Docker: Fixed critical Restarting loop by removing incorrect image directive in docker-compose.yml. - Docker: Optimized Dockerfile to correct .pixi environment path issues and prevent accidental deletion of frontend assets.
61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
from fastapi import APIRouter, HTTPException
|
|
from fastapi.responses import FileResponse
|
|
from pathlib import Path
|
|
import os
|
|
|
|
router = APIRouter()
|
|
|
|
# Define the path to examples relative to this file
|
|
# This file: backend/app/api/v1/examples.py
|
|
# Root: backend/app/api/v1/../../../../.. = root (where Data/ is)
|
|
# But in Docker, backend/ is at /app/backend and Data/ is at /app/Data
|
|
# So we need to go up 5 levels to get to /app (or project root)
|
|
|
|
current_file = Path(__file__).resolve()
|
|
# Go up 5 levels: v1 -> api -> app -> backend -> root
|
|
PROJECT_ROOT = current_file.parent.parent.parent.parent.parent
|
|
EXAMPLES_DIR = PROJECT_ROOT / "Data" / "examples"
|
|
|
|
@router.get("/")
|
|
async def list_examples():
|
|
"""List available example files"""
|
|
if not EXAMPLES_DIR.exists():
|
|
return []
|
|
|
|
files = []
|
|
# Sort files to ensure consistent order (e.g. C15.fna, then 97-27.fna)
|
|
# Actually just grab all .fna files
|
|
if EXAMPLES_DIR.exists():
|
|
for f in sorted(EXAMPLES_DIR.glob("*.fna")):
|
|
files.append({
|
|
"name": f.name,
|
|
"size": f.stat().st_size
|
|
})
|
|
return files
|
|
|
|
@router.get("/{filename}")
|
|
async def get_example(filename: str):
|
|
"""Get an example file content"""
|
|
file_path = EXAMPLES_DIR / filename
|
|
|
|
# Ensure directory exists
|
|
if not EXAMPLES_DIR.exists():
|
|
raise HTTPException(status_code=404, detail="Examples directory not found")
|
|
|
|
# Security check to prevent path traversal
|
|
try:
|
|
if not file_path.resolve().is_relative_to(EXAMPLES_DIR.resolve()):
|
|
raise HTTPException(status_code=403, detail="Access denied")
|
|
except ValueError:
|
|
# Can happen if paths are on different drives or completely messed up
|
|
raise HTTPException(status_code=403, detail="Access denied")
|
|
|
|
if not file_path.exists() or not file_path.is_file():
|
|
raise HTTPException(status_code=404, detail="File not found")
|
|
|
|
return FileResponse(
|
|
path=file_path,
|
|
filename=filename,
|
|
media_type="application/octet-stream"
|
|
)
|