Files
bttoxin-pipeline/backend/app/api/v1/examples.py
zly c75c85c53b Refactor: Unified pipeline execution, simplified UI, and fixed Docker config
- 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.
2026-01-20 20:25:25 +08:00

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"
)