Build production-ready conversational AI applications in minutes with rich UI components and LLM integrations
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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()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()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()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()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