Dash Text Annotate 0.1.0: Text span annotation inside your Dash app

I’ve released Dash Text Annotate, an open-source component for selecting and labeling passages in a Dash app. It works with plain text and returns structured annotations to ordinary Python callbacks.

Use it to mark people, organizations, dates, or your own categories in documents. It supports overlapping labels, visible passage badges, keyboard passage search, relabeling, undo/redo, and read-only review. Your app controls storage and document loading.

Live annotation demo: label a person and a date, undo, redo, and save.

python -m pip install dash-text-annotate==0.1.0

Here’s a small complete app:

import json
from dash import Dash, Input, Output, html
from dash_text_annotate import DashTextAnnotate

app = Dash(__name__)
app.layout = html.Div([
    DashTextAnnotate(
        id="annotator",
        text="Acme opened an office in Berlin.",
        tag="ORG",
        tag_colors={"ORG": "#79b9a5"},
    ),
    html.Pre(id="annotations"),
])

@app.callback(Output("annotations", "children"), Input("annotator", "entities"))
def show_annotations(entities):
    return json.dumps(entities or [], ensure_ascii=False, indent=2)

if __name__ == "__main__":
    app.run(debug=True)

Each annotation has a stable ID, start/end offsets, the selected text, and a label. The default offsets are Python Unicode code-point indices, so text[start:end] gives you the exact passage, including when the document contains emoji.

Python 3.10+ and Dash 3/4 are supported. The package includes its JavaScript and CSS; there is no Node.js installation or CDN requirement for users. It is MIT licensed and powered by Recogito Text Annotator.

Feedback welcome in the issue tracker, especially experiences with different documents, keyboard workflows, and Dash themes.

Very cool!

For some reason the screenshot is coming through for me… could you try sharing some more screenshots of the feature? Would love to see it in action.

Thanks for sharing :relieved_face:

Seems like I cannot edit the original post. Here the broken gif:

annotation-demo