Complete phase two benchmarks, plot previews and static export workflow

This commit is contained in:
2026-09-07 02:54:52 +08:00
parent 95095197df
commit 89df10bc4e
59 changed files with 2535 additions and 83 deletions
+34
View File
@@ -0,0 +1,34 @@
"""Interactive previews use the same bounded parser and geometry as exports."""
import asyncio
from fastapi import APIRouter
from pydantic import BaseModel, Field
from app.plot.parser import parse_source
from app.plot.render import render_svg
from app.plot.model import PlotDiagnostic, StaticRenderResult
router = APIRouter(prefix='/api/plots', tags=['Function Plot'])
_slots = asyncio.Semaphore(2)
class PlotRequest(BaseModel):
source: str = Field(max_length=20000)
theme_id: str = Field(default='light', max_length=100)
class PlotResponse(BaseModel):
result: StaticRenderResult | None = None
diagnostics: list[PlotDiagnostic] = Field(default_factory=list)
node_count: int = 0
def preview(request):
parsed = parse_source(request.source)
if parsed.plot is None:
return PlotResponse(diagnostics=parsed.diagnostics)
if parsed.plot.node_count > 8000:
return PlotResponse(node_count=parsed.plot.node_count, diagnostics=[PlotDiagnostic(
severity='error', code='PLOT_BUDGET_EXCEEDED', message='图表累计表达式节点超过 8000 上限')])
return PlotResponse(result=render_svg(parsed.plot, request.theme_id),
diagnostics=parsed.diagnostics, node_count=parsed.plot.node_count)
@router.post('/function', response_model=PlotResponse)
async def render_function(request: PlotRequest):
async with _slots:
return await asyncio.to_thread(preview, request)