first commit
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from .config import settings
|
||||
from .extractor import SolidWorksExtractor
|
||||
from .grader import FeatureGrader
|
||||
from .knowledge import KnowledgeRepository
|
||||
from .models import (
|
||||
AuditPartRequest,
|
||||
ObservationRequest,
|
||||
SessionMode,
|
||||
StandardKind,
|
||||
StartSessionRequest,
|
||||
SubmitTestRequest,
|
||||
)
|
||||
from .sessions import LearningService, SessionStore
|
||||
from .skillflow import normalize_steps
|
||||
|
||||
|
||||
app = FastAPI(title=settings.app_name)
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=[
|
||||
"http://localhost:5173",
|
||||
"http://127.0.0.1:5173",
|
||||
"http://localhost:5174",
|
||||
"http://127.0.0.1:5174",
|
||||
"http://localhost:5175",
|
||||
"http://127.0.0.1:5175",
|
||||
],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
knowledge = KnowledgeRepository()
|
||||
store = SessionStore()
|
||||
grader = FeatureGrader()
|
||||
learning = LearningService(store, grader)
|
||||
extractor = SolidWorksExtractor()
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health() -> dict[str, object]:
|
||||
return {
|
||||
"ok": True,
|
||||
"service": settings.app_name,
|
||||
"standards": len(knowledge.list_standards()),
|
||||
"software_paths": settings.software_paths(),
|
||||
}
|
||||
|
||||
|
||||
@app.post("/api/knowledge/reload")
|
||||
async def reload_knowledge() -> dict[str, object]:
|
||||
knowledge.reload()
|
||||
return {"ok": True, "standards": len(knowledge.list_standards())}
|
||||
|
||||
|
||||
@app.get("/api/standards")
|
||||
async def list_standards(query: str = "", kind: StandardKind | None = None) -> dict[str, object]:
|
||||
items = knowledge.list_standards(query=query, kind=kind)
|
||||
return {"items": [item.model_dump(mode="json", exclude={"raw"}) for item in items]}
|
||||
|
||||
|
||||
@app.get("/api/standards/{standard_id}")
|
||||
async def get_standard(standard_id: str) -> dict[str, object]:
|
||||
try:
|
||||
return knowledge.require(standard_id).model_dump(mode="json")
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/api/teaching/sessions")
|
||||
async def start_teaching(request: StartSessionRequest) -> dict[str, object]:
|
||||
try:
|
||||
standard = knowledge.require(request.standard_id)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
return store.start(SessionMode.teaching, standard).model_dump(mode="json")
|
||||
|
||||
|
||||
@app.post("/api/testing/sessions")
|
||||
async def start_testing(request: StartSessionRequest) -> dict[str, object]:
|
||||
try:
|
||||
standard = knowledge.require(request.standard_id)
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
return store.start(SessionMode.testing, standard).model_dump(mode="json")
|
||||
|
||||
|
||||
@app.get("/api/sessions/{session_id}")
|
||||
async def get_session(session_id: str) -> dict[str, object]:
|
||||
try:
|
||||
return store.require(session_id).model_dump(mode="json")
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/api/teaching/sessions/{session_id}/observations")
|
||||
async def submit_teaching_observation(session_id: str, request: ObservationRequest) -> dict[str, object]:
|
||||
observed = normalize_steps({"steps": request.steps})
|
||||
try:
|
||||
result = learning.submit_teaching_observation(session_id, observed)
|
||||
return result.model_dump(mode="json")
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/api/teaching/sessions/{session_id}/audit-part")
|
||||
async def audit_part_for_teaching(session_id: str, request: AuditPartRequest) -> dict[str, object]:
|
||||
try:
|
||||
observed = extractor.audit_part(request.part_path)
|
||||
result = learning.submit_teaching_observation(session_id, observed[-1:] if observed else [])
|
||||
return {"observed_steps": [item.model_dump(mode="json") for item in observed], "result": result.model_dump(mode="json")}
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/api/teaching/sessions/{session_id}/audit-active-part")
|
||||
async def audit_active_part_for_teaching(session_id: str) -> dict[str, object]:
|
||||
try:
|
||||
session = store.require(session_id)
|
||||
observed = extractor.audit_active_part()
|
||||
current_index = session.current_step_index
|
||||
current_step = observed[current_index : current_index + 1] if current_index < len(observed) else []
|
||||
result = learning.submit_teaching_observation(session_id, current_step)
|
||||
return {
|
||||
"observed_steps": [item.model_dump(mode="json") for item in observed],
|
||||
"submitted_steps": [item.model_dump(mode="json") for item in current_step],
|
||||
"result": result.model_dump(mode="json"),
|
||||
}
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@app.post("/api/testing/sessions/{session_id}/submit")
|
||||
async def submit_test(session_id: str, request: SubmitTestRequest) -> dict[str, object]:
|
||||
try:
|
||||
observed = extractor.audit_part(request.part_path) if request.part_path else normalize_steps({"steps": request.steps})
|
||||
report = learning.submit_test(session_id, observed)
|
||||
return report.model_dump(mode="json")
|
||||
except KeyError as exc:
|
||||
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
Reference in New Issue
Block a user