CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-chainlit

Build production-ready conversational AI applications in minutes with rich UI components and LLM integrations

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

ui-elements.mddocs/

UI Elements

Rich UI components for enhancing chat interfaces with media, data visualizations, interactive elements, and task management. These elements can be attached to messages or sent independently to create engaging conversational experiences.

Capabilities

Media Display Elements

Display images, audio, video, and files within the chat interface with flexible sizing and positioning options.

import chainlit as cl

class Image:
    """
    Display images in the chat interface with flexible sizing and positioning.
    
    Args:
        name: str - Element identifier
        path: Optional[str] - Local file path to image
        content: Optional[bytes] - Image bytes data
        url: Optional[str] - Remote image URL
        display: ElementDisplay - Display mode ("inline", "side", "page")
        size: ElementSize - Image size ("small", "medium", "large")
        
    Returns:
        Image element instance
    """
    def __init__(
        self,
        name: str,
        path: Optional[str] = None,
        content: Optional[bytes] = None,
        url: Optional[str] = None,
        display: ElementDisplay = "inline",
        size: ElementSize = "medium"
    ): ...
    
    async def send(self) -> "Image":
        """Send the image element to the UI."""

class Audio:
    """
    Audio playback element with auto-play control.
    
    Args:
        name: str - Element identifier
        path: Optional[str] - Local audio file path
        content: Optional[bytes] - Audio bytes data
        url: Optional[str] - Remote audio URL
        display: ElementDisplay - Display mode
        auto_play: bool - Auto-play audio (default: False)
        
    Returns:
        Audio element instance
    """
    def __init__(
        self,
        name: str,
        path: Optional[str] = None,
        content: Optional[bytes] = None,
        url: Optional[str] = None,
        display: ElementDisplay = "inline",
        auto_play: bool = False
    ): ...
    
    async def send(self) -> "Audio":
        """Send the audio element to the UI."""

class Video:
    """
    Video playback element with ReactPlayer configuration support.
    
    Args:
        name: str - Element identifier
        path: Optional[str] - Local video file path
        content: Optional[bytes] - Video bytes data
        url: Optional[str] - Remote video URL
        display: ElementDisplay - Display mode
        size: ElementSize - Video size (default: "medium")
        player_config: Optional[dict] - ReactPlayer configuration options
        
    Returns:
        Video element instance
    """
    def __init__(
        self,
        name: str,
        path: Optional[str] = None,
        content: Optional[bytes] = None,
        url: Optional[str] = None,
        display: ElementDisplay = "inline",
        size: ElementSize = "medium",
        player_config: Optional[dict] = None
    ): ...
    
    async def send(self) -> "Video":
        """Send the video element to the UI."""

class File:
    """
    Generic file download element for any file type.
    
    Args:
        name: str - Element identifier and display name
        path: Optional[str] - Local file path
        content: Optional[bytes] - File bytes data
        url: Optional[str] - Remote file URL
        display: ElementDisplay - Display mode
        
    Returns:
        File element instance
    """
    def __init__(
        self,
        name: str,
        path: Optional[str] = None,
        content: Optional[bytes] = None,
        url: Optional[str] = None,
        display: ElementDisplay = "inline"
    ): ...
    
    async def send(self) -> "File":
        """Send the file element to the UI."""

Usage examples for media elements:

import chainlit as cl

@cl.on_message
async def handle_media(message: cl.Message):
    # Display an image from file path
    await cl.Image(
        name="chart", 
        path="./chart.png",
        size="large"
    ).send()
    
    # Display image from bytes
    with open("image.jpg", "rb") as f:
        image_bytes = f.read()
    
    await cl.Image(
        name="photo",
        content=image_bytes,
        display="side"
    ).send()
    
    # Audio with auto-play
    await cl.Audio(
        name="notification",
        path="./notification.mp3",
        auto_play=True
    ).send()
    
    # Video with custom player config
    await cl.Video(
        name="demo",
        url="https://example.com/video.mp4",
        player_config={"controls": True, "volume": 0.5}
    ).send()
    
    # File download
    await cl.File(
        name="report.pdf",
        path="./generated_report.pdf"
    ).send()

Data Visualization Elements

Display formatted text, interactive charts, DataFrames, and PDF documents for rich data presentation.

class Text:
    """
    Display formatted text with optional syntax highlighting (not a message).
    
    Args:
        name: str - Element identifier
        content: str - Text content to display
        language: Optional[str] - Syntax highlighting language
        display: ElementDisplay - Display mode
        
    Returns:
        Text element instance
    """
    def __init__(
        self,
        name: str,
        content: str,
        language: Optional[str] = None,
        display: ElementDisplay = "inline"
    ): ...
    
    async def send(self) -> "Text":
        """Send the text element to the UI."""

class Plotly:
    """
    Interactive Plotly charts with automatic JSON conversion.
    
    Args:
        name: str - Element identifier
        figure: Any - Plotly figure object (plotly.graph_objects.Figure)
        size: ElementSize - Chart size (default: "medium")
        display: ElementDisplay - Display mode
        
    Returns:
        Plotly element instance
        
    Note:
        Automatically converts figure to JSON format for display
    """
    def __init__(
        self,
        name: str,
        figure: Any,
        size: ElementSize = "medium",
        display: ElementDisplay = "inline"
    ): ...
    
    async def send(self) -> "Plotly":
        """Send the Plotly chart to the UI."""

class Pyplot:
    """
    Matplotlib pyplot charts with automatic PNG conversion.
    
    Args:
        name: str - Element identifier  
        figure: Any - Matplotlib Figure object
        size: ElementSize - Chart size (default: "medium")
        display: ElementDisplay - Display mode
        
    Returns:
        Pyplot element instance
        
    Note:
        Automatically converts to PNG format for display
    """
    def __init__(
        self,
        name: str,
        figure: Any,
        size: ElementSize = "medium",
        display: ElementDisplay = "inline"
    ): ...
    
    async def send(self) -> "Pyplot":
        """Send the matplotlib chart to the UI."""

class Dataframe:
    """
    Display pandas DataFrames with automatic JSON conversion.
    
    Args:
        name: str - Element identifier
        data: Any - Pandas DataFrame object
        size: ElementSize - Display size (default: "large")
        display: ElementDisplay - Display mode
        
    Returns:
        Dataframe element instance
        
    Note:
        Automatically converts DataFrame to JSON format for display
    """
    def __init__(
        self,
        name: str,
        data: Any,
        size: ElementSize = "large",
        display: ElementDisplay = "inline"
    ): ...
    
    async def send(self) -> "Dataframe":
        """Send the DataFrame to the UI."""

class Pdf:
    """
    PDF document viewer with page navigation support.
    
    Args:
        name: str - Element identifier
        path: Optional[str] - Local PDF file path
        content: Optional[bytes] - PDF bytes data
        url: Optional[str] - Remote PDF URL
        display: ElementDisplay - Display mode
        page: Optional[int] - Initial page to display
        mime: str - MIME type (default: "application/pdf")
        
    Returns:
        Pdf element instance
    """
    def __init__(
        self,
        name: str,
        path: Optional[str] = None,
        content: Optional[bytes] = None,
        url: Optional[str] = None,
        display: ElementDisplay = "inline",
        page: Optional[int] = None,
        mime: str = "application/pdf"
    ): ...
    
    async def send(self) -> "Pdf":
        """Send the PDF viewer to the UI."""

Usage examples for data visualization:

import chainlit as cl
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import pandas as pd

@cl.on_message
async def show_visualizations(message: cl.Message):
    # Display formatted code
    code = "def hello():\n    return 'world'"
    await cl.Text(
        name="code_sample",
        content=code,
        language="python"
    ).send()
    
    # Interactive Plotly chart
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=[1, 2, 3, 4], y=[10, 11, 12, 13]))
    fig.update_layout(title="Sample Chart")
    
    await cl.Plotly(
        name="interactive_chart",
        figure=fig,
        size="large"
    ).send()
    
    # Matplotlib chart
    plt.figure(figsize=(10, 6))
    plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
    plt.title("Matplotlib Chart")
    
    await cl.Pyplot(
        name="static_chart",
        figure=plt.gcf()
    ).send()
    plt.close()
    
    # DataFrame display
    df = pd.DataFrame({
        'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['NY', 'LA', 'Chicago']
    })
    
    await cl.Dataframe(
        name="user_data",
        data=df
    ).send()
    
    # PDF viewer
    await cl.Pdf(
        name="documentation",
        path="./user_guide.pdf",
        page=1
    ).send()

Interactive Elements and Actions

Create custom interactive components and action buttons that trigger callbacks.

class CustomElement:
    """
    Custom UI component with arbitrary properties for advanced interactions.
    
    Args:
        name: str - Element identifier
        props: Dict - Custom properties for the element
        display: ElementDisplay - Display mode  
        mime: str - MIME type (default: "application/json")
        
    Returns:
        CustomElement instance
    """
    def __init__(
        self,
        name: str,
        props: Dict,
        display: ElementDisplay = "inline",
        mime: str = "application/json"
    ): ...
    
    async def update(self, props: Dict) -> "CustomElement":
        """Update element properties dynamically."""
        
    async def send(self) -> "CustomElement":
        """Send the custom element to the UI."""

class Action:
    """
    Interactive buttons that trigger callbacks when clicked.
    
    Args:
        name: str - Action identifier for callbacks
        payload: Dict - Data passed to callback when triggered
        label: str - Button text displayed to user
        tooltip: str - Hover tooltip text
        icon: Optional[str] - Lucide icon name
        
    Returns:
        Action instance
    """
    def __init__(
        self,
        name: str,
        payload: Dict,
        label: str,
        tooltip: str = "",
        icon: Optional[str] = None
    ): ...
    
    async def send(self, for_id: Optional[str] = None) -> "Action":
        """Send action button, optionally for a specific message."""
        
    async def remove(self) -> None:
        """Remove the action button from the UI."""

Usage examples for interactive elements:

import chainlit as cl

@cl.on_message
async def interactive_demo(message: cl.Message):
    # Custom element with interactive properties
    custom_props = {
        "type": "rating",
        "max_rating": 5,
        "current_rating": 0,
        "allow_half": True
    }
    
    rating_element = cl.CustomElement(
        name="user_rating",
        props=custom_props
    )
    await rating_element.send()
    
    # Action buttons
    actions = [
        cl.Action(
            name="approve",
            label="Approve", 
            payload={"action": "approve", "id": 123},
            icon="check"
        ),
        cl.Action(
            name="reject",
            label="Reject",
            payload={"action": "reject", "id": 123}, 
            icon="x"
        )
    ]
    
    # Send message with actions
    msg = await cl.Message(
        "Please review this request:",
        actions=actions
    ).send()

@cl.action_callback("approve")
async def handle_approval(action: cl.Action):
    await cl.Message(f"Request {action.payload['id']} approved!").send()

@cl.action_callback("reject") 
async def handle_rejection(action: cl.Action):
    await cl.Message(f"Request {action.payload['id']} rejected.").send()

Task Management

Create and manage dynamic task lists with status tracking for complex workflows.

class Task:
    """
    Individual task item for TaskList with status tracking.
    
    Args:
        title: str - Task description text
        status: TaskStatus - Current status ("ready", "running", "failed", "done")
        forId: Optional[str] - Associated message or step ID
        
    Returns:
        Task instance
    """
    def __init__(
        self,
        title: str,
        status: TaskStatus = "ready",
        forId: Optional[str] = None
    ): ...

class TaskStatus:
    """Task status enumeration for task state management."""
    READY = "ready"
    RUNNING = "running" 
    FAILED = "failed"
    DONE = "done"

class TaskList:
    """
    Dynamic task list with status tracking for complex workflows.
    
    Args:
        tasks: List[Task] - Initial list of tasks
        status: str - Overall status message (default: "Ready")
        
    Returns:
        TaskList instance
    """
    def __init__(
        self,
        tasks: List[Task],
        status: str = "Ready"
    ): ...
    
    def add_task(self, task: Task) -> None:
        """Add a new task to the list."""
        
    async def update(self) -> "TaskList":
        """Update the task list in the UI."""
        
    async def send(self) -> "TaskList":
        """Send the task list to the UI."""

Usage example for task management:

import chainlit as cl

@cl.on_message
async def workflow_demo(message: cl.Message):
    # Create task list for a complex workflow
    tasks = [
        cl.Task(title="Parse user input", status="ready"),
        cl.Task(title="Fetch external data", status="ready"),
        cl.Task(title="Process with AI model", status="ready"),
        cl.Task(title="Generate response", status="ready")
    ]
    
    task_list = cl.TaskList(tasks=tasks, status="Starting workflow...")
    await task_list.send()
    
    # Execute tasks with status updates
    for i, task in enumerate(tasks):
        task.status = "running"
        await task_list.update()
        
        # Simulate work
        await cl.sleep(2)
        
        # Complete task
        task.status = "done"
        await task_list.update()
    
    # Update overall status
    task_list.status = "Workflow completed!"
    await task_list.update()
    
    await cl.Message("All tasks completed successfully!").send()

Core Types

from typing import Union, Optional, List, Dict, Any
from enum import Enum

# Display and sizing options
ElementDisplay = Union["inline", "side", "page"]
ElementSize = Union["small", "medium", "large"] 

# Task status enumeration
TaskStatus = Union["ready", "running", "failed", "done"]

# Base element interface
class ElementBased:
    name: str
    display: ElementDisplay
    size: Optional[ElementSize]
    
# Action payload type
ActionPayload = Dict[str, Any]

Install with Tessl CLI

npx tessl i tessl/pypi-chainlit

docs

advanced.md

authentication.md

callbacks.md

index.md

input-widgets.md

integrations.md

messaging.md

ui-elements.md

user-management.md

tile.json