[Artifacts] Artifact embed rendering engine
Goal
Authored papers and dashboards reference other artifacts via
{{artifact:ID}} markers in their content. This task builds the rendering engine that resolves these markers into inline HTML, making documents truly dynamic — a figure updates when re-generated, a hypothesis score changes when re-evaluated, a dataset grows as new data arrives.
Embed Marker Syntax
{{artifact:ARTIFACT_ID}} → default view for the artifact type
{{artifact:ARTIFACT_ID:figure}} → render as figure with caption
{{artifact:ARTIFACT_ID:table}} → render as data table
{{artifact:ARTIFACT_ID:summary}} → render as compact card
{{artifact:ARTIFACT_ID:chart}} → render as interactive chart
{{artifact:ARTIFACT_ID:link}} → render as hyperlink only
{{artifact:ARTIFACT_ID:full}} → render full detail (expanded)
Rendering Rules by Artifact Type
figure
- Default view:
<figure><img src="..."><figcaption>...</figcaption></figure>
- summary: thumbnail with title
- link:
[Figure: title](url)
hypothesis
- Default view: scored card with title, composite_score gauge, target_gene, evidence_for/against counts
- summary: one-line score badge
Hypothesis: title (score: 0.82)
- full: complete hypothesis with evidence matrix
model
- Default view: metric card with model_family, key evaluation metrics, parameter count
- summary:
Model: title (RMSE: 0.023)
- table: parameters table with values and sources
dataset / tabular_dataset
- Default view: summary card with row_count, column_count, source
- table: first 10 rows as HTML table with column headers
- summary: one-line
Dataset: title (50,000 rows)
paper
- Default view: citation card with title, authors, journal, year
- link: formatted citation
[Authors et al., Year]
protein_design
- Default view: card with sequence length, mutations, stability, binding affinity
- summary:
Protein: title (v3, Kd=120nM)
dashboard
- Default view: iframe embed of the live dashboard
- summary: snapshot card with last_rendered_at
notebook
- Default view: rendered notebook HTML (scrollable embed)
- summary: card with title and associated analysis
Implementation
resolve_embeds(content_html: str) -> str
import re
EMBED_PATTERN = re.compile(r'\{\{artifact:([^:}]+)(?::([^}]+))?\}\}')
def resolve_embeds(content_html: str) -> str:
"""Replace all {{artifact:ID[:view]}} markers with rendered HTML."""
def replace_embed(match):
artifact_id = match.group(1)
view = match.group(2) or 'default'
return render_artifact_embed(artifact_id, view)
return EMBED_PATTERN.sub(replace_embed, content_html)
def render_artifact_embed(artifact_id: str, view: str = 'default') -> str:
"""Render a single artifact as inline HTML based on its type and requested view."""
artifact = get_artifact(artifact_id)
if not artifact:
return f'<div class="embed-error">Artifact not found: {artifact_id}</div>'
artifact_type = artifact['artifact']['artifact_type']
renderer = EMBED_RENDERERS.get(artifact_type, render_generic_embed)
return renderer(artifact, view)
EMBED_RENDERERS = {
'figure': render_figure_embed,
'hypothesis': render_hypothesis_embed,
'model': render_model_embed,
'dataset': render_dataset_embed,
'tabular_dataset': render_dataset_embed,
'paper': render_paper_embed,
'protein_design': render_protein_embed,
'dashboard': render_dashboard_embed,
'notebook': render_notebook_embed,
'authored_paper': render_authored_paper_embed,
}
Integration Points
GET /paper/{id} calls resolve_embeds() before rendering
GET /dashboard/{id} calls resolve_embeds() after data source injection
GET /api/papers/authored/{id}?rendered=true returns HTML with resolved embeds
Acceptance Criteria
☐ resolve_embeds() finds and replaces all {{artifact:ID}} markers
☐ View parameter (figure, table, summary, chart, link, full) respected
☐ Each artifact type has a dedicated renderer
☐ Missing artifacts show error placeholder (not crash)
☐ Default view auto-selected based on artifact type
☐ Renderers produce valid HTML matching SciDEX dark theme
☐ Integration with authored paper rendering
☐ Integration with dashboard rendering
☐ Work log updated with timestamped entry
Dependencies
- a17-27-APAP0001 (authored papers use embeds)
- a17-28-DASH0001 (dashboards use embeds)
Dependents
- d16-25-DPAP0001 (demo: dynamic paper with embedded artifacts)
Work Log