diff --git a/src/disk_checker/web/__init__.py b/src/disk_checker/web/__init__.py index e814ef1..3753ac5 100644 --- a/src/disk_checker/web/__init__.py +++ b/src/disk_checker/web/__init__.py @@ -1 +1,6 @@ -"""Web backend module for disk-checker API.""" \ No newline at end of file +"""Web backend module for disk-checker API.""" + +from .web_routes import web_router +from .routes import api_router + +__all__ = ["web_router", "api_router"] \ No newline at end of file diff --git a/src/disk_checker/web/routes.py b/src/disk_checker/web/routes.py index e8da937..96fa619 100644 --- a/src/disk_checker/web/routes.py +++ b/src/disk_checker/web/routes.py @@ -1,56 +1,12 @@ """API routes for disk-checker web backend.""" -import asyncio -import tempfile -from pathlib import Path -from typing import List, Optional, Dict +from fastapi import APIRouter, Request -from fastapi import APIRouter, UploadFile, File, HTTPException, Depends, Request -from fastapi.responses import JSONResponse, FileResponse -import pandas as pd - -from disk_checker.core.extractor import load_latency_csv -from disk_checker.core.helpers import percentile_table from disk_checker.core.tool_scanner import ToolInfo +api_router = APIRouter() -from disk_checker.plotting.plots import generate_plot -from disk_checker.web.models import ( - JobStatusResponse, -) - - -router = APIRouter() - - -@router.get("/jobs/{job_id}", response_model=JobStatusResponse) -async def get_job_status(job_id: str, request: Request): - """ - Check the status of a benchmark job. - """ - jobs = request.app.state.jobs - if job_id not in jobs: - raise HTTPException(status_code=404, detail="Job not found") - - job = jobs[job_id] - task = job["task"] - - if task.done(): - result = task.result() - return JobStatusResponse(**result) - - return JobStatusResponse(job_id=job_id, status="running") - - -@router.get("/jobs", response_model=List[str]) -async def list_jobs(request: Request): - """ - List all benchmark jobs. - """ - return list(request.app.state.jobs.keys()) - - -@router.get("/tools") +@api_router.get("/tools") async def get_available_tools(request: Request): """ Get list of available benchmarking tools. diff --git a/src/disk_checker/web/server.py b/src/disk_checker/web/server.py index 05841c7..fedc834 100644 --- a/src/disk_checker/web/server.py +++ b/src/disk_checker/web/server.py @@ -2,14 +2,31 @@ import asyncio +from pathlib import Path + from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager import logging from disk_checker.core.orchestrator import Orchestrator from disk_checker.core.tool_scanner import scan_tools +# Import and include routers +from disk_checker.web.routes import api_router +from disk_checker.web.web_routes import web_router + +# Get application root +BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent +TEMPLATES_DIR = BASE_DIR / "templates" +STATIC_DIR = BASE_DIR / "static" + +# Setup templates +templates = Jinja2Templates(directory=str(TEMPLATES_DIR)) + +# Setup logger logger = logging.getLogger(__name__) @@ -24,6 +41,10 @@ async def lifespan(app: FastAPI): app.state.available_tools = await asyncio.to_thread(scan_tools) logger.info(f"Available tools: {list(app.state.available_tools.keys())}") + # Store templates and static_dir path in app.state + app.state.templates = templates + app.state.static_dir = STATIC_DIR + logger.info("Disk Checker API started") yield @@ -37,7 +58,13 @@ app = FastAPI( version="0.1.0", lifespan=lifespan, ) +# Setup static files +app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") +# Include routers +app.include_router(api_router, prefix="/api/v1") +app.include_router(web_router) +# Add CORS (permissive by default) app.add_middleware( CORSMiddleware, allow_origins=["*"], @@ -46,13 +73,8 @@ app.add_middleware( allow_headers=["*"], ) - +# Simple health endpoint @app.get("/health") async def health_check(): """Health check endpoint.""" - return {"status": "ok", "version": "0.1.0"} - - -# Import and include routers -from disk_checker.web.routes import router as api_router -app.include_router(api_router, prefix="/api/v1") \ No newline at end of file + return {"status": "ok", "version": "0.1.0"} \ No newline at end of file diff --git a/src/disk_checker/web/web_routes.py b/src/disk_checker/web/web_routes.py new file mode 100644 index 0000000..63fa5b5 --- /dev/null +++ b/src/disk_checker/web/web_routes.py @@ -0,0 +1,19 @@ +from fastapi import APIRouter, Request +from fastapi.templating import Jinja2Templates +from typing import Dict + +web_router = APIRouter() + +@web_router.get("/") +async def render_home(request: Request): + """ + Render the main page + """ + tools = request.app.state.available_tools + return request.app.state.templates.TemplateResponse( + name="index.html", + request=request, + context={ + "tools":tools + } + ) \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..c7651d5 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,17 @@ +/* Basic styling for Disk Checker */ +.container { + max-width: 1200px; +} + +.card { + transition: transform 0.2s; +} + +.card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0,0,0,0.1); +} + +.badge { + font-size: 0.9rem; +} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..c0ca987 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,26 @@ + + + + + + Disk Checker + + + + + + + + +
+ {% block content %}{% endblock %} +
+ + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..5d54f6a --- /dev/null +++ b/templates/index.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} + +{% block content %} +
+

Available Benchmarking Tools

+ + + {% if tools %} +
+ {% for tool_name, tool in tools.items() %} +
+
+
+
{{ tool.name }}
+

+ {% if tool.available %} + Available + {% if tool.version %} + {{ tool.version }} + {% endif %} + {% else %} + Not Installed + {% endif %} +

+
+
+
+ {% endfor %} +
+ {% endif %} + +
+
+{% endblock %} \ No newline at end of file