How to Customize OpenMed Output to HTML Format: A Complete Guide

You can customize OpenMed's HTML output by using the format_predictions function with output_format="html" or by subclassing OutputFormatter in openmed/processing/outputs.py to override colors, templates, and filtering logic.

OpenMed (maziyarpanahi/openmed) provides flexible formatting capabilities for model predictions through its openmed.processing.outputs module. When building medical NLP applications that require visual entity highlighting, you can generate rich HTML output complete with colored entity spans, confidence tooltips, and customizable CSS styling. This guide covers the architecture and practical techniques for tailoring HTML output to your specific UI requirements.

Understanding the HTML Output Architecture

The HTML generation system centers on three core components defined in openmed/processing/outputs.py: the data structures holding predictions, the formatter class that transforms them, and the rendering methods that generate the final markup.

Core Data Structures

PredictionResult aggregates all entities from a single inference pass. It contains the original text, model name, timestamp, processing time, and a list of EntityPrediction objects. Each EntityPrediction represents a single detected entity with its label, confidence score, and character offsets.

The OutputFormatter Class

The OutputFormatter class manages the conversion from raw model outputs to formatted strings. It accepts formatting flags such as include_confidence, confidence_threshold, and group_entities during initialization. The format_predictions method constructs a PredictionResult from raw predictions, while to_html renders that result as an HTML string.

The HTML structure includes a wrapper <div class="openmed-result">, metadata headers displaying model name and timestamp, the original text with embedded <span> tags for each entity (carrying color-coded backgrounds and title attributes for tooltips), and a summary list of all detected entities.

Basic HTML Generation

For standard HTML output without customization, use the module-level format_predictions function. This instantiates OutputFormatter internally and returns the rendered HTML.

from openmed.processing.outputs import format_predictions

# Raw predictions from your medical NER model

raw_predictions = [
    {"entity": "B-PER", "word": "John", "score": 0.98, "start": 0, "end": 4},
    {"entity": "B-ORG", "word": "Acme Corp", "score": 0.95, "start": 10, "end": 19},
]

text = "John works at Acme Corp."

html = format_predictions(
    predictions=raw_predictions,
    original_text=text,
    model_name="medical-ner-model",
    output_format="html",
    include_confidence=True,
    confidence_threshold=0.5,
)

print(html)  # Returns HTML string ready for web rendering

The function processes predictions in openmed/processing/outputs.py by sorting entities by start offset and iteratively inserting HTML tags while tracking offset shifts caused by the inserted markup.

Customizing OpenMed HTML Output

Customization requires subclassing OutputFormatter and overriding specific methods. The two primary extension points are entity color mapping and HTML template generation.

Modifying Entity Colors

Override _get_entity_color to implement custom color schemes for different entity types. The base method maps lowercase labels to CSS colors (e.g., "person" → #FFE4E1), but you can redefine this logic to match your application's design system.

from openmed.processing.outputs import OutputFormatter

class CustomHtmlFormatter(OutputFormatter):
    def _get_entity_color(self, label: str) -> str:
        """Return pink for conditions, default colors for others."""
        if label.lower() == "condition":
            return "#FFC0CB"
        return super()._get_entity_color(label)

# Usage

formatter = CustomHtmlFormatter(include_confidence=True)
result = formatter.format_predictions(raw_predictions, text, "my-model")
html = formatter.to_html(result)

Custom HTML Templates

To inject additional CSS or modify the HTML structure, override to_html. The method assembles HTML as plain strings, making it straightforward to prepend stylesheets or alter the wrapper markup.

class StyledHtmlFormatter(OutputFormatter):
    def to_html(self, result):
        # Generate base HTML

        base_html = super().to_html(result)
        
        # Insert custom CSS after opening div

        custom_style = """
        <style>
            .entity { font-weight: bold; border-radius: 3px; }
            .entity-person { background-color: #e3f2fd; }
            .entity-organization { background-color: #f3e5f5; }
        </style>
        """
        return base_html.replace(
            '<div class="openmed-result">', 
            f'<div class="openmed-result">{custom_style}', 
            1
        )

Filtering by Confidence Threshold

Control which entities appear in the HTML using the confidence_threshold parameter. Entities below the threshold are excluded from the PredictionResult before HTML generation.

html = format_predictions(
    predictions=raw_predictions,
    original_text=text,
    model_name="medical-ner-model",
    output_format="html",
    confidence_threshold=0.9,  # Only entities ≥90% confidence

)

Advanced Customization Examples

For production deployments requiring specific styling or preprocessing, combine subclassing with preprocessing hooks.

Adding Custom CSS Classes

class ClinicalFormatter(OutputFormatter):
    def _get_entity_color(self, label: str) -> str:
        # Standard medical color coding

        color_map = {
            "medication": "#ffebee",
            "condition": "#fff3e0",
            "procedure": "#e8f5e9",
            "symptom": "#e3f2fd"
        }
        return color_map.get(label.lower(), "#f5f5f5")
    
    def to_html(self, result):
        base = super().to_html(result)
        # Add clinical disclaimer footer

        disclaimer = "<footer class='disclaimer'>Reviewed by clinical staff</footer>"
        return base.replace("</div>", f"{disclaimer}</div>", 1)

Summary

  • Primary entry point: Use format_predictions in openmed/processing/outputs.py with output_format="html" for standard HTML generation.
  • Architecture: The OutputFormatter class handles the conversion from PredictionResult to HTML via the to_html method.
  • Color customization: Override _get_entity_color in subclasses to implement entity-specific color schemes.
  • Template customization: Override to_html to inject CSS, modify wrapper elements, or add disclaimers.
  • Confidence filtering: Pass confidence_threshold to filter low-confidence entities before rendering.
  • Source files: Core logic resides in openmed/processing/outputs.py, with CLI examples in openmed/cli/main.py.

Frequently Asked Questions

How do I change entity colors in OpenMed HTML output?

Subclass OutputFormatter and override the _get_entity_color method in openmed/processing/outputs.py. This method receives the entity label as a string and returns a CSS color value. Return custom hex codes for specific labels and call super()._get_entity_color(label) for default behavior on others.

Can I add custom CSS styles to OpenMed HTML output?

Yes. Create a subclass of OutputFormatter and override the to_html method. Call super().to_html(result) to get the base HTML string, then use string manipulation (such as replace) to inject a <style> block or additional CSS classes before returning the final HTML.

How do I filter low-confidence predictions from HTML output?

Pass the confidence_threshold parameter to format_predictions or initialize OutputFormatter with this value. Entities with confidence scores below the threshold are excluded from the PredictionResult before HTML generation, ensuring only high-confidence predictions appear in the rendered output.

What is the difference between format_predictions and OutputFormatter?

format_predictions is a convenience function that instantiates OutputFormatter internally, calls format_predictions (the method), and returns the formatted output. OutputFormatter is the class containing the actual formatting logic, HTML generation (to_html), and customization hooks like _get_entity_color. Use the function for simple cases and the class directly when subclassing for customization.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →