Centralize HTML5 response helpers
This commit is contained in:
@@ -1620,10 +1620,7 @@ async def api_health() -> dict[str, str]:
|
||||
|
||||
@app.get("/html5")
|
||||
async def html5_index() -> Response:
|
||||
return Response(
|
||||
render_html5_index(_project_summaries()),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_index(_project_summaries()))
|
||||
|
||||
|
||||
@app.post("/html5/projects")
|
||||
@@ -1633,10 +1630,7 @@ async def html5_create_project(request: Request) -> Response:
|
||||
if not project_id:
|
||||
raise HTTPException(status_code=400, detail="project_id is required.")
|
||||
await create_project(ProjectCreateRequest(project_id=project_id, name=_form_value(form, "name")))
|
||||
return Response(
|
||||
render_html5_project_rows(_project_summaries()),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_project_rows(_project_summaries()))
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/delete")
|
||||
@@ -1644,31 +1638,25 @@ async def html5_delete_project(project_id: str, request: Request) -> Response:
|
||||
form = await _html5_form_data(request)
|
||||
confirmation = _form_value(form, "confirmation") or ""
|
||||
await delete_project(project_id, ProjectDeleteRequest(confirmation=confirmation))
|
||||
return Response(
|
||||
render_html5_project_rows(_project_summaries()),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_project_rows(_project_summaries()))
|
||||
|
||||
|
||||
@app.get("/html5/operations")
|
||||
async def html5_operations(project_id: str = "", status: str = "", kind: str = "") -> Response:
|
||||
return Response(
|
||||
return _html5_response(
|
||||
render_html5_operations(
|
||||
_html5_operation_jobs(project_id=project_id, status=status, kind=kind),
|
||||
project_id=project_id,
|
||||
status=status,
|
||||
kind=kind,
|
||||
),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@app.get("/html5/operations/jobs")
|
||||
async def html5_operation_jobs(project_id: str = "", status: str = "", kind: str = "") -> Response:
|
||||
return Response(
|
||||
render_html5_operation_rows(_html5_operation_jobs(project_id=project_id, status=status, kind=kind)),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
jobs = _html5_operation_jobs(project_id=project_id, status=status, kind=kind)
|
||||
return _html5_response(render_html5_operation_rows(jobs))
|
||||
|
||||
|
||||
@app.get("/html5/operations/jobs/{job_id}/detail")
|
||||
@@ -1676,18 +1664,13 @@ async def html5_operation_job_detail(job_id: str) -> Response:
|
||||
job = _operations.jobs.get(job_id)
|
||||
if job is None:
|
||||
raise HTTPException(status_code=404, detail=f"Unknown operation job: {job_id}")
|
||||
return Response(
|
||||
render_html5_operation_detail(job),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_operation_detail(job))
|
||||
|
||||
|
||||
@app.get("/html5/operations/summary")
|
||||
async def html5_operation_summary(project_id: str = "", status: str = "", kind: str = "") -> Response:
|
||||
return Response(
|
||||
render_html5_operation_summary(_html5_operation_jobs(project_id=project_id, status=status, kind=kind)),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
jobs = _html5_operation_jobs(project_id=project_id, status=status, kind=kind)
|
||||
return _html5_response(render_html5_operation_summary(jobs))
|
||||
|
||||
|
||||
@app.get("/html5/operations/events")
|
||||
@@ -1708,11 +1691,7 @@ async def html5_operations_events(
|
||||
break
|
||||
time.sleep(3)
|
||||
|
||||
return StreamingResponse(
|
||||
stream_operations(),
|
||||
media_type="text/event-stream",
|
||||
headers=_html5_sse_headers(),
|
||||
)
|
||||
return _html5_sse_response(stream_operations())
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/editor")
|
||||
@@ -1733,7 +1712,7 @@ async def html5_project_editor(project_id: str, q: str = "") -> Response:
|
||||
error=str(error.detail),
|
||||
q=q,
|
||||
)
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/events")
|
||||
@@ -1774,29 +1753,19 @@ async def html5_project_events(project_id: str, once: bool = False) -> Streaming
|
||||
break
|
||||
await asyncio.sleep(5)
|
||||
|
||||
return StreamingResponse(
|
||||
stream_status(),
|
||||
media_type="text/event-stream",
|
||||
headers=_html5_sse_headers(),
|
||||
)
|
||||
return _html5_sse_response(stream_status())
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/symbols")
|
||||
async def html5_project_symbols(project_id: str, q: str = "") -> Response:
|
||||
snapshot = _project_snapshot_or_404(project_id)
|
||||
return Response(
|
||||
render_html5_symbols(snapshot, q, project_id),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_symbols(snapshot, q, project_id))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/symbols/{lineage_id}/detail")
|
||||
async def html5_project_symbol_detail(project_id: str, lineage_id: str) -> Response:
|
||||
references = await project_symbol_references(project_id, lineage_id, direction="both")
|
||||
return Response(
|
||||
render_html5_symbol_detail(project_id, references),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_symbol_detail(project_id, references))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/source/by-path")
|
||||
@@ -1812,10 +1781,7 @@ async def html5_project_source_by_path(project_id: str, path: str) -> Response:
|
||||
)
|
||||
if node is None:
|
||||
raise HTTPException(status_code=404, detail=f"Source not found: {path}")
|
||||
return Response(
|
||||
render_html5_source(node),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_source(node))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/source/{lineage_id}")
|
||||
@@ -1824,28 +1790,19 @@ async def html5_project_source(project_id: str, lineage_id: str) -> Response:
|
||||
node = _find_snapshot_node(snapshot, lineage_id)
|
||||
if node is None:
|
||||
raise HTTPException(status_code=404, detail=f"Lineage not found: {lineage_id}")
|
||||
return Response(
|
||||
render_html5_source(node),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_source(node))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/report")
|
||||
async def html5_project_report(project_id: str) -> Response:
|
||||
report = await project_report(project_id)
|
||||
return Response(
|
||||
render_html5_project_report(project_id, report),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_project_report(project_id, report))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/review")
|
||||
async def html5_project_review(project_id: str) -> Response:
|
||||
findings = await get_review(project_id)
|
||||
return Response(
|
||||
render_html5_review(project_id, findings),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_review(project_id, findings))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/flowchart")
|
||||
@@ -1856,9 +1813,8 @@ async def html5_project_flowchart(
|
||||
limit: int = 80,
|
||||
) -> Response:
|
||||
flowchart = await project_flowchart(project_id, focus=focus, depth=depth, limit=limit)
|
||||
return Response(
|
||||
return _html5_response(
|
||||
render_html5_flowchart(project_id, flowchart, focus=focus, depth=depth),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
|
||||
|
||||
@@ -1902,25 +1858,22 @@ async def html5_project_object_context(project_id: str, object_name: str, mode:
|
||||
oob=True,
|
||||
)
|
||||
review_context = render_html5_review(project_id, focused_findings, title="Review объекта", oob=True)
|
||||
return Response(
|
||||
return _html5_response(
|
||||
object_context + flowchart_context + source_context + symbol_context + report_context + review_context,
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/authoring/changes")
|
||||
async def html5_project_authoring_changes(project_id: str) -> Response:
|
||||
return Response(
|
||||
return _html5_response(
|
||||
render_html5_authoring_changes(project_id, _authoring_change_summaries(project_id)),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/authoring/changes/{change_id}")
|
||||
async def html5_project_authoring_change_detail(project_id: str, change_id: str) -> Response:
|
||||
return Response(
|
||||
return _html5_response(
|
||||
render_html5_authoring_change_detail(project_id, _authoring_rollback_preview(project_id, change_id)),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
|
||||
|
||||
@@ -1939,7 +1892,7 @@ async def html5_project_authoring_apply_rollback(project_id: str, change_id: str
|
||||
html = render_html5_authoring_rollback_result(project_id, result)
|
||||
except HTTPException as error:
|
||||
html = render_html5_authoring_rollback_result(project_id, error=str(error.detail))
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/authoring/completion-preview")
|
||||
@@ -1963,7 +1916,7 @@ async def html5_project_authoring_completion_preview(project_id: str, request: R
|
||||
html = render_html5_authoring_preview_result(project_id, preview)
|
||||
except HTTPException as error:
|
||||
html = render_html5_authoring_preview_result(project_id, error=str(error.detail))
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/authoring/semantic-diff-preview")
|
||||
@@ -1995,7 +1948,7 @@ async def html5_project_authoring_semantic_diff_preview(project_id: str, request
|
||||
)
|
||||
except HTTPException as error:
|
||||
html = render_html5_authoring_diff_result(project_id, error=str(error.detail))
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/authoring/apply-change-set")
|
||||
@@ -2018,7 +1971,7 @@ async def html5_project_authoring_apply_change_set(project_id: str, request: Req
|
||||
html = render_html5_authoring_apply_result(project_id, result)
|
||||
except HTTPException as error:
|
||||
html = render_html5_authoring_apply_result(project_id, error=str(error.detail))
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/authoring/metadata-object-preview")
|
||||
@@ -2032,7 +1985,7 @@ async def html5_project_authoring_metadata_object_preview(project_id: str, reque
|
||||
except (HTTPException, ValueError) as error:
|
||||
detail = getattr(error, "detail", str(error))
|
||||
html = render_html5_metadata_preview_result(project_id, error=str(detail))
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/authoring/apply-metadata-object")
|
||||
@@ -2051,25 +2004,21 @@ async def html5_project_authoring_apply_metadata_object(project_id: str, request
|
||||
except (HTTPException, ValueError) as error:
|
||||
detail = getattr(error, "detail", str(error))
|
||||
html = render_html5_metadata_apply_result(project_id, error=str(detail))
|
||||
return Response(html, media_type="text/html; charset=utf-8")
|
||||
return _html5_response(html)
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/setup")
|
||||
async def html5_project_setup(project_id: str) -> Response:
|
||||
setup = _project_setup_response(project_id)
|
||||
return Response(
|
||||
return _html5_response(
|
||||
render_html5_project_setup(project_id=project_id, projects=_project_summaries(), setup=setup),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/setup/summary")
|
||||
async def html5_project_setup_summary(project_id: str) -> Response:
|
||||
setup = _project_setup_response(project_id)
|
||||
return Response(
|
||||
render_html5_setup_summary(project_id, setup),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_setup_summary(project_id, setup))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/setup/events")
|
||||
@@ -2100,11 +2049,7 @@ async def html5_project_setup_events(project_id: str, once: bool = False) -> Str
|
||||
break
|
||||
await asyncio.sleep(2)
|
||||
|
||||
return StreamingResponse(
|
||||
stream_setup(),
|
||||
media_type="text/event-stream",
|
||||
headers=_html5_sse_headers(),
|
||||
)
|
||||
return _html5_sse_response(stream_setup())
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/setup/source")
|
||||
@@ -2114,10 +2059,7 @@ async def html5_project_setup_source(project_id: str, request: Request) -> Respo
|
||||
current = _project_setup_response(project_id)
|
||||
settings = current.settings.model_copy(update={"structure_source": source})
|
||||
setup = await save_project_settings(project_id, settings)
|
||||
return Response(
|
||||
render_html5_setup_summary(project_id, setup),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_setup_summary(project_id, setup))
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/setup/settings")
|
||||
@@ -2132,10 +2074,7 @@ async def html5_project_setup_settings(project_id: str, request: Request) -> Res
|
||||
}
|
||||
)
|
||||
setup = await save_project_settings(project_id, settings)
|
||||
return Response(
|
||||
render_html5_settings_panel(project_id, setup, saved=True),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_settings_panel(project_id, setup, saved=True))
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/setup/check")
|
||||
@@ -2143,10 +2082,7 @@ async def html5_project_setup_check(project_id: str, request: Request) -> Respon
|
||||
form = await _html5_form_data(request)
|
||||
source = ImportSourceKind(_form_value(form, "source") or _current_import_source(project_id).value)
|
||||
check = _import_check_response(project_id, source, ImportRequest(source=source))
|
||||
return Response(
|
||||
render_html5_import_check(project_id, check),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_import_check(project_id, check))
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/setup/import")
|
||||
@@ -2156,10 +2092,7 @@ async def html5_project_setup_import(project_id: str, request: Request) -> Respo
|
||||
structure_only = _form_value(form, "structure_only") in {"1", "true", "on", "yes"}
|
||||
_execute_import_project(project_id, ImportRequest(source=source, structure_only=structure_only))
|
||||
setup = _project_setup_response(project_id)
|
||||
return Response(
|
||||
render_html5_setup_summary(project_id, setup),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_setup_summary(project_id, setup))
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/setup/import-job")
|
||||
@@ -2167,10 +2100,7 @@ async def html5_project_setup_import_job(project_id: str, request: Request) -> R
|
||||
form = await _html5_form_data(request)
|
||||
source = ImportSourceKind(_form_value(form, "source") or _current_import_source(project_id).value)
|
||||
job = await start_project_import_job(project_id, source, ImportRequest(source=source))
|
||||
return Response(
|
||||
render_html5_import_job(project_id, job),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_import_job(project_id, job))
|
||||
|
||||
|
||||
@app.get("/html5/projects/{project_id}/setup/jobs/{job_id}")
|
||||
@@ -2178,20 +2108,14 @@ async def html5_project_setup_job(project_id: str, job_id: str) -> Response:
|
||||
job = _operations.jobs.get(job_id)
|
||||
if job is None or job.payload.get("project_id") != project_id:
|
||||
raise HTTPException(status_code=404, detail=f"Unknown import job: {job_id}")
|
||||
return Response(
|
||||
render_html5_import_job(project_id, job),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_import_job(project_id, job))
|
||||
|
||||
|
||||
@app.post("/html5/projects/{project_id}/setup/reindex")
|
||||
async def html5_project_setup_reindex(project_id: str) -> Response:
|
||||
await reindex_project(project_id)
|
||||
setup = _project_setup_response(project_id)
|
||||
return Response(
|
||||
render_html5_setup_summary(project_id, setup),
|
||||
media_type="text/html; charset=utf-8",
|
||||
)
|
||||
return _html5_response(render_html5_setup_summary(project_id, setup))
|
||||
|
||||
|
||||
@app.get("/version")
|
||||
@@ -8517,6 +8441,18 @@ def _html5_sse_headers() -> dict[str, str]:
|
||||
}
|
||||
|
||||
|
||||
def _html5_response(fragment: str) -> Response:
|
||||
return Response(fragment, media_type="text/html; charset=utf-8")
|
||||
|
||||
|
||||
def _html5_sse_response(content: Any) -> StreamingResponse:
|
||||
return StreamingResponse(
|
||||
content,
|
||||
media_type="text/event-stream",
|
||||
headers=_html5_sse_headers(),
|
||||
)
|
||||
|
||||
|
||||
def _html5_sse_if_changed(last_fragments: dict[str, str], event: str, fragment: str):
|
||||
if last_fragments.get(event) == fragment:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user