UniteLabs
Concepts

Artifacts

Structured data and files produced by a workflow run — persisted and linked to the run record for traceability and downstream use.

Artifacts are structured outputs attached to a run — reports, measurement summaries, annotated images, and links to external files. They appear in the platform UI under the run's Artifacts tab and are persisted for traceability and downstream use.

For unitelabs-sdk< 0.10.0, import flow and task from Prefect instead. Use flow in place of both workflow and phase decorators, and task as step decorators.

Artifacts are distinct from logs: logs capture the execution narrative, artifacts capture the scientific results.

Producing artifacts

Use Prefect's artifact functions from any phase or step. The most common type is a markdown artifact, which can embed tables, images, and rich text directly in the run view.

Measurement report — summarize results as a markdown table:

workflows/plate_read.py
from unitelabs.sdk import get_logger
from unitelabs.sdk.automate import phase
from prefect.artifacts import create_markdown_artifact

@phase()
async def report(plate_id: str, hits: list[str], hit_rate: float):
    logger = get_logger()

    rows = "\n".join(f"| {well} |" for well in hits) or "| — |"
    await create_markdown_artifact(
        key="plate-read-report",
        markdown=f"""## Plate Read Report

**Plate:** `{plate_id}`
**Hit rate:** {hit_rate:.1f}%

| Hit well |
|----------|
{rows}
""",
        description=f"{len(hits)} hits on {plate_id}",
    )
    logger.info(f"Report artifact published — {len(hits)} hits")

Annotated image — embed a base64-encoded image inline:

workflows/detection.py
import base64
from unitelabs.sdk.automate import phase
from prefect.artifacts import create_markdown_artifact

@phase()
async def detection(camera_service_name: str) -> dict:
    image = await capture_snapshot(camera_service_name)
    result = detect_plate_in_roi(image)

    _, buf = cv2.imencode(".png", image)
    img_b64 = base64.b64encode(buf).decode()

    await create_markdown_artifact(
        key="detection-result",
        markdown=f"""## Plate Detection

**Result:** {"✅ PLATE PRESENT" if result["plate_present"] else "❌ EMPTY"}

![Detection](data:image/png;base64,{img_b64})
""",
        description="Camera-based plate detection",
    )
    return result

External file link — reference a file in object storage or a local path:

workflows/imaging.py
from unitelabs.sdk.automate import phase
from prefect.artifacts import create_link_artifact

@phase()
async def imaging(target: Plate):
    image_path = await microscope.capture(target)
    await create_link_artifact(
        key="plate-image",
        link=str(image_path),
        description="Captured plate image",
    )

Accessing artifacts

Platform UI: open a run and navigate to the Artifacts tab. Each artifact shows its name, type, and the phase that produced it.

API:

Terminal
curl https://api.unitelabs.io/v1/runs/{run_id}/artifacts \
  -H "Authorization: Bearer $API_TOKEN"

Download a specific artifact:

Terminal
curl https://api.unitelabs.io/v1/runs/{run_id}/artifacts/plate_image \
  -H "Authorization: Bearer $API_TOKEN" \
  -o plate_image.tiff

Artifact traceability

Every artifact is linked to:

  • The run that produced it
  • The workflow version that was executing
  • The phase and step that created it
  • The inputs the run was started with

This chain of custody makes it possible to reproduce any result or trace a measurement back to the exact protocol and reagent batch that generated it.

  • Runs: artifacts are scoped to a specific run
  • Logs: execution narrative, separate from result data
  • Phase: the level at which artifacts are typically produced and returned