Add FastAPI backend and React frontend subprojects
Backend: - FastAPI app with 17 REST endpoints covering dashboard, monitoring, media index, file browser, and jobs - Reuses existing clients/domain/services unchanged - pydantic-settings config, dependency injection, CORS setup - Auto-generated OpenAPI docs at /docs Frontend: - Vite + React + TypeScript SPA - @tanstack/react-query for data fetching with polling - ag-grid-react for media table and file browser - recharts for monitoring charts - Tailwind CSS styling - 4 pages: Dashboard, Monitoring, Media, File Browser - Typed API client matching all backend endpoints Also: - docs/MIGRATION_PLAN.md with full architecture plan - Updated .gitignore for both subprojects - Streamlit app preserved for now (can coexist)
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""Jobs router — list templates and run jobs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
from dependencies import get_ssh_client
|
||||
from clients.ssh import RemoteSSHClient
|
||||
from jobs import JOB_TEMPLATES, run_job
|
||||
|
||||
router = APIRouter(prefix="/api/jobs", tags=["jobs"])
|
||||
|
||||
|
||||
class RunJobRequest(BaseModel):
|
||||
job_key: str
|
||||
path: str
|
||||
|
||||
|
||||
@router.get("/templates")
|
||||
def get_templates() -> list[dict[str, str]]:
|
||||
"""Return available job templates."""
|
||||
return [
|
||||
{
|
||||
"key": key,
|
||||
"name": template.name,
|
||||
"description": template.description,
|
||||
}
|
||||
for key, template in JOB_TEMPLATES.items()
|
||||
]
|
||||
|
||||
|
||||
@router.post("/run")
|
||||
def post_run_job(
|
||||
request: RunJobRequest,
|
||||
ssh: RemoteSSHClient = Depends(get_ssh_client),
|
||||
) -> dict[str, Any]:
|
||||
"""Run a job template on a remote path."""
|
||||
if request.job_key not in JOB_TEMPLATES:
|
||||
raise HTTPException(status_code=400, detail=f"Unknown job key: {request.job_key}")
|
||||
|
||||
result = run_job(ssh, request.job_key, request.path)
|
||||
return {
|
||||
"job_key": request.job_key,
|
||||
"path": request.path,
|
||||
"exit_status": result.exit_status,
|
||||
"stdout": result.stdout,
|
||||
"stderr": result.stderr,
|
||||
}
|
||||
Reference in New Issue
Block a user