# Table of Contents
- [Chat Profiles - Chainlit](#chat-profiles-chainlit)
- [Ask User - Chainlit](#ask-user-chainlit)
- [Chat Settings - Chainlit](#chat-settings-chainlit)
- [MCP Servers - Chainlit](#mcp-servers-chainlit)
- [Multi-Modality - Chainlit](#multi-modality-chainlit)
- [Streaming - Chainlit](#streaming-chainlit)
- [Testing & Debugging - Chainlit](#testing-debugging-chainlit)
- [Action - Chainlit](#action-chainlit)
- [AskUserAction - Chainlit](#askuseraction-chainlit)
- [AskFileMessage - Chainlit](#askfilemessage-chainlit)
- [AskUserMessage - Chainlit](#askusermessage-chainlit)
- [cache - Chainlit](#cache-chainlit)
- [author_rename and Message author - Chainlit](#author-rename-and-message-author-chainlit)
- [Chat Profiles - Chainlit](#chat-profiles-chainlit)
- [Chat Settings - Chainlit](#chat-settings-chainlit)
- [Audio - Chainlit](#audio-chainlit)
- [Custom Data Layer - Chainlit](#custom-data-layer-chainlit)
- [Dataframe - Chainlit](#dataframe-chainlit)
- [Image - Chainlit](#image-chainlit)
- [Custom - Chainlit](#custom-chainlit)
- [File - Chainlit](#file-chainlit)
- [PDF viewer - Chainlit](#pdf-viewer-chainlit)
- [Plotly - Chainlit](#plotly-chainlit)
- [Pyplot - Chainlit](#pyplot-chainlit)
- [Text - Chainlit](#text-chainlit)
- [TaskList - Chainlit](#tasklist-chainlit)
- [Select - Chainlit](#select-chainlit)
- [Video - Chainlit](#video-chainlit)
- [Slider - Chainlit](#slider-chainlit)
- [Tags - Chainlit](#tags-chainlit)
- [Switch - Chainlit](#switch-chainlit)
- [TextInput - Chainlit](#textinput-chainlit)
- [Langchain Callback Handler - Chainlit](#langchain-callback-handler-chainlit)
- [LlamaIndex Callback Handler - Chainlit](#llamaindex-callback-handler-chainlit)
- [on_audio_chunk - Chainlit](#on-audio-chunk-chainlit)
- [on_audio_end - Chainlit](#on-audio-end-chainlit)
- [on_chat_resume - Chainlit](#on-chat-resume-chainlit)
- [on_chat_end - Chainlit](#on-chat-end-chainlit)
- [on_chat_start - Chainlit](#on-chat-start-chainlit)
- [on_logout - Chainlit](#on-logout-chainlit)
- [on_message - Chainlit](#on-message-chainlit)
- [make_async - Chainlit](#make-async-chainlit)
- [Message - Chainlit](#message-chainlit)
- [Step Class - Chainlit](#step-class-chainlit)
- [Step Decorator - Chainlit](#step-decorator-chainlit)
- [Window Messaging - Chainlit](#window-messaging-chainlit)
- [Header - Chainlit](#header-chainlit)
- [Overview - Chainlit](#overview-chainlit)
- [Password - Chainlit](#password-chainlit)
---
# Chat Profiles - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
Chat Profiles
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Chat Profiles are useful if you want to let your users choose from a list of predefined configured assistants. For example, you can define a chat profile for a support chat, a sales chat, or a chat for a specific product.
[Chat Profiles API\
-----------------\
\
Learn how to define chat profiles.](/api-reference/chat-profiles)
Example of Chat Profiles
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/chat-profiles.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/chat-profiles)
[Multi-Modality](/advanced-features/multi-modal)
[Chat Settings](/advanced-features/chat-settings)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Ask User - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
Ask User
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The ask APIs prompt the user for input. Depending on the API, the user input can be a string, a file, or pick an action.
Until the user provides an input, both the UI and your code will be blocked.
Ask File example
[](#available-ask-apis)
Available Ask APIs
----------------------------------------------
[Text Input\
----------\
\
Ask the user for a string input.](/api-reference/ask/ask-for-input)
[File\
----\
\
Ask the user to upload a file.](/api-reference/ask/ask-for-file)
[Action\
------\
\
Ask the user to pick an action.](/api-reference/ask/ask-for-action)
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/ask-user.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/ask-user)
[MCP Servers](/advanced-features/mcp)
[Multi-Modality](/advanced-features/multi-modal)
On this page
* [Available Ask APIs](#available-ask-apis)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Chat Settings - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
Chat Settings
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Chat settings are useful to let each user configure their chat experience given a set of options.
[](#how-it-works)
How it works
----------------------------------
Check the chat settings [API reference](/api-reference/chat-settings)
to learn how to configure it.
[](#preview)
Preview
------------------------
If chat settings are set, a new button will appear in the chat bar.
Clicking on this button will open the settings panel. All settings are editable by the user. Once settings are updated, an event is sent to the Chainlit server so the application can react to the update.
Chat Settings in Chainlit
[](#example)
Example
------------------------
Check out this example from the cookbook that uses this feature: [https://github.com/Chainlit/cookbook/tree/main/image-gen](https://github.com/Chainlit/cookbook/tree/main/image-gen)
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/chat-settings.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/chat-settings)
[Chat Profiles](/advanced-features/chat-profiles)
[Testing & Debugging](/advanced-features/test-debug)
On this page
* [How it works](#how-it-works)
* [Preview](#preview)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# MCP Servers - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
MCP Servers
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
[](#overview)
Overview
--------------------------
MCP provides a mechanism for Chainlit applications to connect to either server-sent events (SSE) based services or command-line (stdio) based tools. Once connected, your application can discover available tools, execute them, and integrate their responses into your application’s flow.
[Chainlit MCP Cookbook\
---------------------\
\
End to end cookbook example showcasing MCP tool calling with Claude.](https://github.com/Chainlit/cookbook/tree/main/mcp)
Connect to an MCP server
###
[](#contact-us-for-enterprise-ready-mcp)
Contact us for Enterprise Ready MCP
We’re working with companies to create their MCP stacks, enabling AI agents to consume their data and context in standardized ways. Fill out this [form](https://docs.google.com/forms/d/e/1FAIpQLSdObSIeIFt4nHppZ6r2rIoEe-jZRo4CqxbmRKKgb-ZsSPONnQ/viewform?usp=dialog)
.
[](#connections-types)
Connections Types
--------------------------------------------
Chainlit supports two types of MCP connections:
1. **SSE (Server-Sent Events)**: Connect to a remote service via HTTP
2. **stdio**: Execute a local command and communicate via standard I/O
> ⚠️ **Security Warning**: The stdio connection type spawns actual subprocesses on the Chainlit server. Only use this with trusted commands in controlled environments. Ensure proper validation of user inputs to prevent command injection vulnerabilities.
**Command Availability Warning**: When using the stdio connection type with commands like `npx` or `uvx`, these commands must be available on the Chainlit server where the application is running. The subprocess is executed on the server, not on the client machine.
###
[](#server-side-configuration-config-toml)
Server-Side Configuration (`config.toml`)
You can control which MCP connection types are enabled globally and restrict allowed stdio commands by modifying your project’s `config.toml` file (usually located at the root of your project or `.chainlit/config.toml`).
Under the `[features.mcp]` section, you can configure SSE and stdio separately:
[features]
# ... other feature flags
[features.mcp.sse]
# Enable or disable the SSE connection type globally
enabled = true
[features.mcp.stdio]
# Enable or disable the stdio connection type globally
enabled = true
# Define an allowlist of executables for the stdio type.
# Only the base names of executables listed here can be used.
# This is a crucial security measure for stdio connections.
# Example: allows running `npx ...` and `uvx ...` but blocks others.
allowed_executables = [ "npx", "uvx" ]
[](#setup)
Setup
--------------------
###
[](#1-register-connection-handlers)
1\. Register Connection Handlers
To use MCP in your Chainlit application, you need to implement the `on_mcp_connect` handler. The `on_mcp_disconnect` handler is optional but recommended for proper cleanup.
import chainlit as cl
from mcp import ClientSession
@cl.on_mcp_connect
async def on_mcp_connect(connection, session: ClientSession):
"""Called when an MCP connection is established"""
# Your connection initialization code here
# This handler is required for MCP to work
@cl.on_mcp_disconnect
async def on_mcp_disconnect(name: str, session: ClientSession):
"""Called when an MCP connection is terminated"""
# Your cleanup code here
# This handler is optional
###
[](#2-client-configuration)
2\. Client Configuration
The client needs to provide the connection details through the Chainlit interface. This includes:
* Connection name (unique identifier)
* Client type (`sse` or `stdio`)
* For SSE: URL endpoint
* For stdio: Full command (e.g., `npx your-tool-package` or `uvx your-tool-package`)
Adding an MCP
[](#working-with-mcp-connections)
Working with MCP Connections
------------------------------------------------------------------
###
[](#retrieving-available-tools)
Retrieving Available Tools
Upon connection, you can discover the available tools provided by the MCP service:
@cl.on_mcp_connect
async def on_mcp(connection, session: ClientSession):
# List available tools
result = await session.list_tools()
# Process tool metadata
tools = [{\
"name": t.name,\
"description": t.description,\
"input_schema": t.inputSchema,\
} for t in result.tools]
# Store tools for later use
mcp_tools = cl.user_session.get("mcp_tools", {})
mcp_tools[connection.name] = tools
cl.user_session.set("mcp_tools", mcp_tools)
###
[](#executing-tools)
Executing Tools
You can execute tools using the MCP session:
@cl.step(type="tool")
async def call_tool(tool_use):
tool_name = tool_use.name
tool_input = tool_use.input
# Find appropriate MCP connection for this tool
mcp_name = find_mcp_for_tool(tool_name)
# Get the MCP session
mcp_session, _ = cl.context.session.mcp_sessions.get(mcp_name)
# Call the tool
result = await mcp_session.call_tool(tool_name, tool_input)
return result
[](#integrating-with-llms)
Integrating with LLMs
----------------------------------------------------
MCP tools can be seamlessly integrated with LLMs that support tool calling:
async def call_model_with_tools():
# Get tools from all MCP connections
mcp_tools = cl.user_session.get("mcp_tools", {})
all_tools = [tool for connection_tools in mcp_tools.values() for tool in connection_tools]
# Call your LLM with the tools
response = await your_llm_client.call(
messages=messages,
tools=all_tools
)
# Handle tool calls if needed
if response.has_tool_calls():
# Process tool calls
pass
return response
[](#session-management)
Session Management
----------------------------------------------
MCP connections are managed at the session level. Each WebSocket session can have multiple named MCP connections. The connections are cleaned up when:
1. The user explicitly disconnects
2. The same connection name is reused (old connection is replaced)
3. The WebSocket session ends
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/mcp.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/mcp)
[Streaming](/advanced-features/streaming)
[Ask User](/advanced-features/ask-user)
On this page
* [Overview](#overview)
* [Contact us for Enterprise Ready MCP](#contact-us-for-enterprise-ready-mcp)
* [Connections Types](#connections-types)
* [Server-Side Configuration (config.toml)](#server-side-configuration-config-toml)
* [Setup](#setup)
* [1\. Register Connection Handlers](#1-register-connection-handlers)
* [2\. Client Configuration](#2-client-configuration)
* [Working with MCP Connections](#working-with-mcp-connections)
* [Retrieving Available Tools](#retrieving-available-tools)
* [Executing Tools](#executing-tools)
* [Integrating with LLMs](#integrating-with-llms)
* [Session Management](#session-management)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Multi-Modality - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
Multi-Modality
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The term ‘Multi-Modal’ refers to the ability to support more than just text, encompassing images, videos, audio and files.
[](#voice-assistant)
Voice Assistant
----------------------------------------
Chainlit let’s you access the user’s microphone audio stream and process it in real-time. This can be used to create voice assistants, transcribe audio, or even process audio in real-time.
The user will only be able to use the microphone if you implemented the [@cl.on\_audio\_chunk](/api-reference/lifecycle-hooks/on-audio-chunk)
decorator.
[OpenAI Realtime\
---------------\
\
Cookbook example showcasing how to use Chainlit with realtime audio APIs.](https://github.com/Chainlit/cookbook/tree/main/realtime-assistant)
[Text To Speech -> Speech to Text\
--------------------------------\
\
Cookbook example showcasing speech to text -> answer generation -> text to speech.](https://github.com/Chainlit/cookbook/blob/main/openai-whisper/app.py)
OpenAI Realtime Example
[](#spontaneous-file-uploads)
Spontaneous File Uploads
----------------------------------------------------------
Within the Chainlit application, users have the flexibility to attach any file to their messages. This can be achieved either by utilizing the drag and drop feature or by clicking on the `attach` button located in the chat bar.
Attach files to a message
As a developer, you have the capability to access these attached files through the [cl.on\_message](/api-reference/lifecycle-hooks/on-message)
decorated function.
import chainlit as cl
@cl.on_message
async def on_message(msg: cl.Message):
if not msg.elements:
await cl.Message(content="No file attached").send()
return
# Processing images exclusively
images = [file for file in msg.elements if "image" in file.mime]
# Read the first image
with open(images[0].path, "r") as f:
pass
await cl.Message(content=f"Received {len(images)} image(s)").send()
###
[](#disabling-spontaneous-file-uploads)
Disabling Spontaneous File Uploads
If you wish to disable this feature (which would prevent users from attaching files to their messages), you can do so by setting `features.spontaneous_file_upload.enabled=false` in your Chainlit [config](/backend/config/features)
file.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/multi-modal.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/multi-modal)
[Ask User](/advanced-features/ask-user)
[Chat Profiles](/advanced-features/chat-profiles)
On this page
* [Voice Assistant](#voice-assistant)
* [Spontaneous File Uploads](#spontaneous-file-uploads)
* [Disabling Spontaneous File Uploads](#disabling-spontaneous-file-uploads)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Streaming - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
Streaming
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Chainlit supports streaming for both [Message](/concepts/message)
and [Step](/concepts/step)
. Here is an example with `openai`.
Streaming OpenAI response
from openai import AsyncOpenAI
import chainlit as cl
client = AsyncOpenAI(api_key="YOUR_OPENAI_API_KEY")
settings = {
"model": "gpt-3.5-turbo",
"temperature": 0.7,
"max_tokens": 500,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
}
@cl.on_chat_start
def start_chat():
cl.user_session.set(
"message_history",
[{"role": "system", "content": "You are a helpful assistant."}],
)
@cl.on_message
async def main(message: cl.Message):
message_history = cl.user_session.get("message_history")
message_history.append({"role": "user", "content": message.content})
msg = cl.Message(content="")
stream = await client.chat.completions.create(
messages=message_history, stream=True, **settings
)
async for part in stream:
if token := part.choices[0].delta.content or "":
await msg.stream_token(token)
message_history.append({"role": "assistant", "content": msg.content})
await msg.update()
[](#integrations)
Integrations
----------------------------------
Streaming is also supported at a higher level for some integrations.
For example, to use streaming with Langchain just pass `streaming=True` when instantiating the LLM:
llm = OpenAI(temperature=0, streaming=True)
Also make sure to pass a [callback handler](/api-reference/integrations/langchain)
to your chain or agent run.
See [here](/api-reference/integrations/langchain#final-answer-streaming)
for final answer streaming.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/streaming.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/streaming)
[Command](/concepts/command)
[MCP Servers](/advanced-features/mcp)
On this page
* [Integrations](#integrations)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Testing & Debugging - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Advanced Features
Testing & Debugging
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
To test or debug your application files and decorated functions, you will need to provide the Chainlit context to your test suite.
In your main application script or test files add:
if __name__ == "__main__":
from chainlit.cli import run_chainlit
run_chainlit(__file__)
Then run the script from your IDE in debug mode.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/advanced-features/test-debug.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /advanced-features/test-debug)
[Chat Settings](/advanced-features/chat-settings)
[Overview](/data-persistence/overview)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Action - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Chat
Action
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Action` class is designed to create and manage actions to be sent and displayed in the chatbot user interface. Actions consist of buttons that the user can interact with, and these interactions trigger specific functionalities within your app.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
Name of the action, this should match the action callback.
[](#param-payload)
payload
Dict
The payload associated with the action.
[](#param-icon)
icon
str
The lucide icon name for the action button. See [https://lucide.dev/icons/](https://lucide.dev/icons/)
.
[](#param-label)
label
str
The label of the action. This is what the user will see. If no label and no icon is provided, the name is display as a fallback.
[](#param-tooltip)
tooltip
str
The description of the action. This is what the user will see when they hover the action.
[](#usage)
Usage
--------------------
import chainlit as cl
@cl.action_callback("action_button")
async def on_action(action):
await cl.Message(content=f"Executed {action.name}").send()
# Optionally remove the action button from the chatbot user interface
await action.remove()
@cl.on_chat_start
async def start():
# Sending an action button within a chatbot message
actions = [\
cl.Action(name="action_button", payload={"value": "example_value"}, label="Click me!")\
]
await cl.Message(content="Interact with this action button:", actions=actions).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/action.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/action)
[Step Class](/api-reference/step-class)
[Chat Profiles](/api-reference/chat-profiles)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# AskUserAction - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Ask User
AskUserAction
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Ask for the user to take an action before continuing. If the user does not answer in time (see timeout), a `TimeoutError` will be raised or `None` will be returned depending on `raise_on_timeout` parameter. If a project ID is configured, the messages will be uploaded to the cloud storage.
###
[](#attributes)
Attributes
[](#param-content)
content
str
The content of the message.
[](#param-actions)
actions
List\[Action\]
The list of [Action](/api-reference/action)
to prompt the user.
[](#param-author)
author
str
The author of the message, defaults to the chatbot name defined in your config.
[](#param-timeout)
timeout
int
default:90
The number of seconds to wait for an answer before raising a TimeoutError.
[](#param-raise-on-timeout)
raise\_on\_timeout
bool
default:"False"
Whether to raise a socketio TimeoutError if the user does not answer in time.
###
[](#returns)
Returns
[](#param-response)
response
AskActionResponse | None
required
The response of the user.
###
[](#example)
Example
import chainlit as cl
@cl.on_chat_start
async def main():
res = await cl.AskActionMessage(
content="Pick an action!",
actions=[\
cl.Action(name="continue", payload={"value": "continue"}, label="✅ Continue"),\
cl.Action(name="cancel", payload={"value": "cancel"}, label="❌ Cancel"),\
],
).send()
if res and res.get("payload").get("value") == "continue":
await cl.Message(
content="Continue!",
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/ask/ask-for-action.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/ask/ask-for-action)
[AskFileMessage](/api-reference/ask/ask-for-file)
[Langchain Callback Handler](/api-reference/integrations/langchain)
On this page
* [Attributes](#attributes)
* [Returns](#returns)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# AskFileMessage - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Ask User
AskFileMessage
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Ask the user to upload a file before continuing. If the user does not answer in time (see timeout), a TimeoutError will be raised or None will be returned depending on raise\_on\_timeout. If a project ID is configured, the messages will be uploaded to the cloud storage.
###
[](#attributes)
Attributes
[](#param-content)
content
str
Text displayed above the upload button.
[](#param-accept)
accept
Union\[List\[str\], Dict\[str, List\[str\]\]\]
List of mime type to accept like `["text/csv", "application/pdf"]` or a dict like `{"text/plain": [".txt", ".py"]}`. More infos here [https://react-dropzone.org/#!/Accepting%20specific%20file%20types](https://react-dropzone.org/#!/Accepting%20specific%20file%20types)
.
[](#param-max-size-mb)
max\_size\_mb
int
Maximum file size in MB. Defaults to 2.
[](#param-max-files)
max\_files
int
Maximum number of files to upload. Defaults to 1. Maximum value is 10.
[](#param-timeout)
timeout
int
The number of seconds to wait for an answer before raising a TimeoutError.
[](#param-raise-on-timeout)
raise\_on\_timeout
bool
Whether to raise a socketio TimeoutError if the user does not answer in time.
###
[](#returns)
Returns
[](#param-response)
response
List\[AskFileResponse\]
required
The files uploaded by the user.
###
[](#example)
Example
Ask for a text file
import chainlit as cl
@cl.on_chat_start
async def start():
files = None
# Wait for the user to upload a file
while files == None:
files = await cl.AskFileMessage(
content="Please upload a text file to begin!", accept=["text/plain"]
).send()
text_file = files[0]
with open(text_file.path, "r", encoding="utf-8") as f:
text = f.read()
# Let the user know that the system is ready
await cl.Message(
content=f"`{text_file.name}` uploaded, it contains {len(text)} characters!"
).send()
You can also pass a dict to the `accept` parameter to precise the file extension for each mime type:
Ask for a python file
import chainlit as cl
file = await cl.AskFileMessage(
content="Please upload a python file to begin!", accept={"text/plain": [".py"]}
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/ask/ask-for-file.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/ask/ask-for-file)
[AskUserMessage](/api-reference/ask/ask-for-input)
[AskUserAction](/api-reference/ask/ask-for-action)
On this page
* [Attributes](#attributes)
* [Returns](#returns)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# AskUserMessage - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Ask User
AskUserMessage
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Ask for the user input before continuing. If the user does not answer in time (see timeout), a TimeoutError will be raised or None will be returned depending on raise\_on\_timeout. If a project ID is configured, the messages will be uploaded to the cloud storage.
###
[](#attributes)
Attributes
[](#param-content)
content
str
The content of the message.
[](#param-author)
author
str
The author of the message, defaults to the chatbot name defined in your config.
[](#param-timeout)
timeout
int
The number of seconds to wait for an answer before raising a TimeoutError.
[](#param-raise-on-timeout)
raise\_on\_timeout
bool
Whether to raise a socketio TimeoutError if the user does not answer in time.
###
[](#returns)
Returns
[](#param-response)
response
Step
required
The response of the user.
###
[](#usage)
Usage
import chainlit as cl
@cl.on_chat_start
async def main():
res = await cl.AskUserMessage(content="What is your name?", timeout=10).send()
if res:
await cl.Message(
content=f"Your name is: {res['output']}",
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/ask/ask-for-input.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/ask/ask-for-input)
[TaskList](/api-reference/elements/tasklist)
[AskFileMessage](/api-reference/ask/ask-for-file)
On this page
* [Attributes](#attributes)
* [Returns](#returns)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# cache - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Misceallaneous
cache
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `cache` decorator is a tool for caching results of resource-intensive calculations or loading processes. It can be conveniently combined with the [file watcher](/backend/command-line)
to prevent resource reloading each time the application restarts. This not only saves time, but also enhances overall efficiency.
[](#parameters)
Parameters
------------------------------
[](#param-func)
func
Callable
The target function whose results need to be cached.
[](#returns)
Returns
------------------------
[](#param-cached-value)
cached\_value
Any
required
The computed value that is stored in the cache after its initial calculation.
[](#usage)
Usage
--------------------
import time
import chainlit as cl
@cl.cache
def to_cache():
time.sleep(5) # Simulate a time-consuming process
return "Hello!"
value = to_cache()
@cl.on_message
async def main(message: cl.Message):
await cl.Message(
content=value,
).send()
In this example, the `to_cache` function simulates a time-consuming process that returns a value. By using the `cl.cache` decorator, the result of the function is cached after its first execution. Future calls to the `to_cache` function return the cached value without running the time-consuming process again.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/cache.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/cache)
[make\_async](/api-reference/make-async)
[Custom Data Layer](/api-reference/data-persistence/custom-data-layer)
On this page
* [Parameters](#parameters)
* [Returns](#returns)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# author_rename and Message author - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Misceallaneous
author\_rename and Message author
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
This documentation covers two methods for setting or renaming the author of a message to display more friendly author names in the UI: the `author_rename` decorator and the Message author specification at message creation.
[](#method-1%3A-author-rename)
Method 1: author\_rename
-----------------------------------------------------------
Useful for renaming the author of a message dynamically during the message handling process.
[](#parameters)
Parameters
------------------------------
[](#param-orig-author)
orig\_author
str
required
The original author name.
[](#returns)
Returns
------------------------
[](#param-author)
author
str
required
The renamed author
[](#usage)
Usage
--------------------
from langchain import OpenAI, LLMMathChain
import chainlit as cl
@cl.author_rename
def rename(orig_author: str):
rename_dict = {"LLMMathChain": "Albert Einstein", "Chatbot": "Assistant"}
return rename_dict.get(orig_author, orig_author)
@cl.on_message
async def main(message: cl.Message):
llm = OpenAI(temperature=0)
llm_math = LLMMathChain.from_llm(llm=llm)
res = await llm_math.acall(message.content, callbacks=[cl.AsyncLangchainCallbackHandler()])
await cl.Message(content="Hello").send()
[](#method-2%3A-message-author)
Method 2: Message author
------------------------------------------------------------
Allows for naming the author of a message at the moment of the message creation.
###
[](#usage-2)
Usage
You can specify the author directly when creating a new message object:
from langchain import OpenAI, LLMMathChain
import chainlit as cl
@cl.on_message
async def main(message: cl.Message):
llm = OpenAI(temperature=0)
llm_math = LLMMathChain.from_llm(llm=llm)
res = await llm_math.acall(message.content, callbacks=[cl.AsyncLangchainCallbackHandler()])
# Specify the author at message creation
response_message = cl.Message(content="Hello", author="NewChatBotName")
await response_message.send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/author-rename.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/author-rename)
[LlamaIndex Callback Handler](/api-reference/integrations/llamaindex)
[make\_async](/api-reference/make-async)
On this page
* [Method 1: author\_rename](#method-1%3A-author-rename)
* [Parameters](#parameters)
* [Returns](#returns)
* [Usage](#usage)
* [Method 2: Message author](#method-2%3A-message-author)
* [Usage](#usage-2)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Chat Profiles - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Chat
Chat Profiles
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Decorator to define the list of chat profiles.
If authentication is enabled, you can access the user details to create the list of chat profiles conditionally.
The icon is optional.
[](#parameters)
Parameters
------------------------------
[](#param-current-user)
current\_user
User
The message coming from the UI.
[](#usage)
Usage
--------------------
Simple example
import chainlit as cl
@cl.set_chat_profiles
async def chat_profile():
return [\
cl.ChatProfile(\
name="GPT-3.5",\
markdown_description="The underlying LLM model is **GPT-3.5**.",\
icon="https://picsum.photos/200",\
),\
cl.ChatProfile(\
name="GPT-4",\
markdown_description="The underlying LLM model is **GPT-4**.",\
icon="https://picsum.photos/250",\
),\
]
@cl.on_chat_start
async def on_chat_start():
chat_profile = cl.user_session.get("chat_profile")
await cl.Message(
content=f"starting chat using the {chat_profile} chat profile"
).send()
With authentication
from typing import Optional
import chainlit as cl
@cl.set_chat_profiles
async def chat_profile(current_user: cl.User):
if current_user.metadata["role"] != "ADMIN":
return None
return [\
cl.ChatProfile(\
name="GPT-3.5",\
markdown_description="The underlying LLM model is **GPT-3.5**, a *175B parameter model* trained on 410GB of text data.",\
),\
cl.ChatProfile(\
name="GPT-4",\
markdown_description="The underlying LLM model is **GPT-4**, a *1.5T parameter model* trained on 3.5TB of text data.",\
icon="https://picsum.photos/250",\
),\
cl.ChatProfile(\
name="GPT-5",\
markdown_description="The underlying LLM model is **GPT-5**.",\
icon="https://picsum.photos/200",\
),\
]
@cl.password_auth_callback
def auth_callback(username: str, password: str) -> Optional[cl.User]:
if (username, password) == ("admin", "admin"):
return cl.User(identifier="admin", metadata={"role": "ADMIN"})
else:
return None
@cl.on_chat_start
async def on_chat_start():
user = cl.user_session.get("user")
chat_profile = cl.user_session.get("chat_profile")
await cl.Message(
content=f"starting chat with {user.identifier} using the {chat_profile} chat profile"
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/chat-profiles.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/chat-profiles)
[Action](/api-reference/action)
[Chat Settings](/api-reference/chat-settings)
On this page
* [Parameters](#parameters)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Chat Settings - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Chat
Chat Settings
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `ChatSettings` class is designed to create and send a dynamic form to the UI. This form can be updated by the user.
[](#attributes)
Attributes
------------------------------
[](#param-inputs)
inputs
List\[InputWidget\]
The fields of the form
[](#usage)
Usage
--------------------
import chainlit as cl
from chainlit.input_widget import Select, Switch, Slider
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[\
Select(\
id="Model",\
label="OpenAI - Model",\
values=["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4", "gpt-4-32k"],\
initial_index=0,\
),\
Switch(id="Streaming", label="OpenAI - Stream Tokens", initial=True),\
Slider(\
id="Temperature",\
label="OpenAI - Temperature",\
initial=1,\
min=0,\
max=2,\
step=0.1,\
),\
Slider(\
id="SAI_Steps",\
label="Stability AI - Steps",\
initial=30,\
min=10,\
max=150,\
step=1,\
description="Amount of inference steps performed on image generation.",\
),\
Slider(\
id="SAI_Cfg_Scale",\
label="Stability AI - Cfg_Scale",\
initial=7,\
min=1,\
max=35,\
step=0.1,\
description="Influences how strongly your generation is guided to match your prompt.",\
),\
Slider(\
id="SAI_Width",\
label="Stability AI - Image Width",\
initial=512,\
min=256,\
max=2048,\
step=64,\
tooltip="Measured in pixels",\
),\
Slider(\
id="SAI_Height",\
label="Stability AI - Image Height",\
initial=512,\
min=256,\
max=2048,\
step=64,\
tooltip="Measured in pixels",\
),\
]
).send()
@cl.on_settings_update
async def setup_agent(settings):
print("on_settings_update", settings)
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/chat-settings.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/chat-settings)
[Chat Profiles](/api-reference/chat-profiles)
[Custom](/api-reference/elements/custom)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Audio - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Audio
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Audio` class allows you to display an audio player for a specific audio file in the chatbot user interface.
You must provide either an url or a path or content bytes.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the audio file to be displayed in the UI. This is shown to users.
[](#param-display)
display
ElementDisplay
Determines where the element should be displayed in the UI. Choices are “side” (default), “inline”, or “page”.
[](#param-url)
url
str
The remote URL of the audio.
[](#param-path)
path
str
The local file path of the audio.
[](#param-content)
content
bytes
The file content of the audio in bytes format.
[](#param-auto-play)
auto\_play
bool
Whether the audio should start playing automatically.
[](#example)
Example
------------------------
import chainlit as cl
@cl.on_chat_start
async def main():
elements = [\
cl.Audio(name="example.mp3", path="./example.mp3", display="inline"),\
]
await cl.Message(
content="Here is an audio file",
elements=elements,
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/audio.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/audio)
[PDF viewer](/api-reference/elements/pdf)
[Video](/api-reference/elements/video)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Custom Data Layer - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Data persistence
Custom Data Layer
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `BaseDataLayer` class serves as an abstract foundation for data persistence operations within the Chainlit framework. This class outlines methods for managing users, feedback, elements, steps, and threads in a chatbot application.
[](#methods)
Methods
------------------------
[](#param-async-get-user-self-identifier-str)
async get\_user(self, identifier: str)
Coroutine
Fetches a user by their identifier. Return type is optionally a `PersistedUser`.
[](#param-async-create-user-self-user-user)
async create\_user(self, user: User)
Coroutine
Creates a new user based on the `User` instance provided. Return type is optionally a `PersistedUser`.
[](#param-async-upsert-feedback-self-feedback-feedback)
async upsert\_feedback(self, feedback: Feedback)
Coroutine
Inserts or updates feedback. Accepts a `Feedback` instance and returns a string as an identifier of the persisted feedback.
[](#param-async-delete-feedback-self-feedback-id-str)
async delete\_feedback(self, feedback\_id: str)
Coroutine
Deletes a feedback by `feedback_id`. Return `True` if it was successful.
[](#param-async-create-element-self-element-dict-element-dict)
async create\_element(self, element\_dict: ElementDict)
Coroutine
Adds a new element to the data layer. Accepts `ElementDict` as an argument.
[](#param-async-get-element-self-thread-id-str-element-id-str)
async get\_element(self, thread\_id: str, element\_id: str)
Coroutine
Retrieves an element by `thread_id` and `element_id`. Return type is optionally an `ElementDict`.
[](#param-async-delete-element-self-element-id-str)
async delete\_element(self, element\_id: str)
Coroutine
Deletes an element given its identifier `element_id`.
[](#param-async-create-step-self-step-dict-step-dict)
async create\_step(self, step\_dict: StepDict)
Coroutine
Creates a new step in the data layer. Accepts `StepDict` as an argument.
[](#param-async-update-step-self-step-dict-step-dict)
async update\_step(self, step\_dict: StepDict)
Coroutine
Updates an existing step. Accepts `StepDict` as an argument.
[](#param-async-delete-step-self-step-id-str)
async delete\_step(self, step\_id: str)
Coroutine
Deletes a step given its identifier `step_id`.
[](#param-async-get-thread-author-self-thread-id-str)
async get\_thread\_author(self, thread\_id: str)
Coroutine
Fetches the author of a given thread by `thread_id`. Returns a string representing the author identifier.
[](#param-async-delete-thread-self-thread-id-str)
async delete\_thread(self, thread\_id: str)
Coroutine
Deletes a thread given its identifier `thread_id`.
[](#param-async-list-threads-self-pagination-pagination-filters-thread-filter)
async list\_threads(self, pagination: Pagination, filters: ThreadFilter)
Coroutine
Lists threads based on `pagination` and `filters` arguments. Returns a `PaginatedResponse[ThreadDict]`.
[](#param-async-get-thread-self-thread-id-str)
async get\_thread(self, thread\_id: str)
Coroutine
Retrieves a thread by its identifier `thread_id`. Return type is optionally a `ThreadDict`.
[](#param-async-update-thread-self-thread-id-str-name-optional-str-none-user-id-optional-str-none-metadata-optional-dict-none-tags-optional-list-str-none)
async update\_thread(self, thread\_id: str, name: Optional\[str\] = None, user\_id: Optional\[str\] = None, metadata: Optional\[Dict\] = None, tags: Optional\[List\[str\]\] = None)
Coroutine
Updates a thread’s details like name, user\_id, metadata, and tags. Arguments are mostly optional.
[](#param-async-delete-user-session-self-id-str)
async delete\_user\_session(self, id: str)
Coroutine
Deletes a user session given its identifier `id`. Returns a boolean value indicating success.
[](#decorators)
Decorators
------------------------------
[](#param-queue-until-user-message)
queue\_until\_user\_message()
Decorator
Queues certain methods to execute only after the first user message is received, especially useful for `WebsocketSessions`.
[](#example)
Example
------------------------
Due to the abstract nature of `BaseDataLayer`, direct instantiation and usage are not practical without subclassing and implementing the abstract methods.
You can refer to the [guide for custom data layer implementation](/data-layers/overview)
.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/data-persistence/custom-data-layer.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/data-persistence/custom-data-layer)
[cache](/api-reference/cache)
[Window Messaging](/api-reference/window-message)
On this page
* [Methods](#methods)
* [Decorators](#decorators)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Dataframe - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Dataframe
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Dataframe` class is designed to send a pandas dataframe to the chatbot user interface.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the dataframe to be displayed in the UI.
[](#param-display)
display
ElementDisplay
Determines how the dataframe element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#param-data)
data
pd.DataFrame
The pandas dataframe instance.
[](#example)
Example
------------------------
import pandas as pd
import chainlit as cl
@cl.on_chat_start
async def start():
# Create a sample DataFrame with more than 10 rows to test pagination functionality
data = {
"Name": [\
"Alice",\
"David",\
"Charlie",\
"Bob",\
"Eva",\
"Grace",\
"Hannah",\
"Jack",\
"Frank",\
"Kara",\
"Liam",\
"Ivy",\
"Mia",\
"Noah",\
"Olivia",\
],
"Age": [25, 40, 35, 30, 45, 55, 60, 70, 50, 75, 80, 65, 85, 90, 95],
"City": [\
"New York",\
"Houston",\
"Chicago",\
"Los Angeles",\
"Phoenix",\
"San Antonio",\
"San Diego",\
"San Jose",\
"Philadelphia",\
"Austin",\
"Fort Worth",\
"Dallas",\
"Jacksonville",\
"Columbus",\
"Charlotte",\
],
"Salary": [\
70000,\
100000,\
90000,\
80000,\
110000,\
130000,\
140000,\
160000,\
120000,\
170000,\
180000,\
150000,\
190000,\
200000,\
210000,\
],
}
df = pd.DataFrame(data)
elements = [cl.Dataframe(data=df, display="inline", name="Dataframe")]
await cl.Message(content="This message has a Dataframe", elements=elements).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/dataframe.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/dataframe)
[Image](/api-reference/elements/image)
[File](/api-reference/elements/file)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Image - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Image
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Image` class is designed to create and handle image elements to be sent and displayed in the chatbot user interface.
You must provide either an url or a path or content bytes.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the image to be displayed in the UI.
[](#param-display)
display
ElementDisplay
Determines how the image element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#param-size)
size
ElementSize
Determines the size of the image. Only works with display=“inline”. Choices are “small”, “medium” (default), or “large”.
[](#param-url)
url
str
The remote URL of the image source.
[](#param-path)
path
str
The local file path of the image.
[](#param-content)
content
bytes
The file content of the image in bytes format.
[](#example)
Example
------------------------
import chainlit as cl
@cl.on_chat_start
async def start():
image = cl.Image(path="./cat.jpeg", name="image1", display="inline")
# Attach the image to the message
await cl.Message(
content="This message has an image!",
elements=[image],
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/image.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/image)
[Text](/api-reference/elements/text)
[Dataframe](/api-reference/elements/dataframe)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Custom - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Custom
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `CustomElement` class allows you to render a custom `.jsx` snippet. The `.jsx` file should be placed in `public/elements/ELEMENT_NAME.jsx`.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the custom Element. It should match the name of your JSX file (without the `.jsx` extension).
[](#param-props)
props
Dict
The props to pass to the JSX.
[](#param-display)
display
ElementDisplay
default:"inline"
Determines how the text element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#how-to-write-the-jsx-file)
How to Write the JSX file
------------------------------------------------------------
If you are not familiar with UI development, you can pass these instructions to an LLM to ask it to generate the `.jsx` for you!
To implement the `jsx` file for your Chainlit custom element, follow these instructions.
###
[](#component-definition)
Component definition
Only write JSX code, no TSX. Each `.jsx` file should export default one component like:
export default function MyComponent() {
return
Hello World
}
The component `props` are globally injected (not as a function argument). **NEVER** pass them as function argument.
###
[](#use-tailwind-for-styling)
Use Tailwind for Styling
Under the hood, the code will be rendered in a shadcn + tailwind environment. The theme is relying on CSS variables.
Here is an example rendering a `div` with a primary color background and round border:
export default function TailwindExample() {
return
}
###
[](#only-use-allowed-imports)
Only Use Allowed Imports
Only use available packages for imports. Here is the full list:
* `react`
* `sonner`
* `zod`
* `recoil`
* `react-hook-form`
* `lucide-react`
* `@/components/ui/accordion`
* `@/components/ui/aspect-ratio`
* `@/components/ui/avatar`
* `@/components/ui/badge`
* `@/components/ui/button`
* `@/components/ui/card`
* `@/components/ui/carousel`
* `@/components/ui/checkbox`
* `@/components/ui/command`
* `@/components/ui/dialog`
* `@/components/ui/dropdown-menu`
* `@/components/ui/form`
* `@/components/ui/hover-card`
* `@/components/ui/input`
* `@/components/ui/label`
* `@/components/ui/pagination`
* `@/components/ui/popover`
* `@/components/ui/progress`
* `@/components/ui/scroll-area`
* `@/components/ui/separator`
* `@/components/ui/select`
* `@/components/ui/sheet`
* `@/components/ui/skeleton`
* `@/components/ui/switch`
* `@/components/ui/table`
* `@/components/ui/textarea`
* `@/components/ui/tooltip`
The `@/components/ui` imports are from Shadcn.
###
[](#available-apis)
Available APIs
Chainlit exposes the following APIs globally to make the custom element interactive.
interface APIs {
// Update the element props. This will re-render the element.
updateElement: (nextProps: Record) => Promise<{success: boolean}>;
// Delete the element entirely.
deleteElement: () => Promise<{success: boolean}>;
// Call an action defined in the Chainlit app
callAction: (action: {name: string, payload: Record}) =>Promise<{success: boolean}>;
// Send a user message
sendUserMessage: (message: string) => void;
}
###
[](#example-of-a-counter-element)
Example of a Counter Element
import { Button } from "@/components/ui/button"
import { X, Plus } from 'lucide-react';
export default function Counter() {
return (
Count: {props.count}
);
}
[](#full-example)
Full Example
----------------------------------
Let’s build a custom element to render the status of a Linear ticket.
First, we write a small Chainlit application faking fetching data from linear:
app.py
import chainlit as cl
async def get_ticket():
"""Pretending to fetch data from linear"""
return {
"title": "Fix Authentication Bug",
"status": "in-progress",
"assignee": "Sarah Chen",
"deadline": "2025-01-15",
"tags": ["security", "high-priority", "backend"]
}
@cl.on_message
async def on_message(msg: cl.Message):
# Let's pretend the user is asking about a linear ticket.
# Usually an LLM with tool calling would be used to decide to render the component or not.
props = await get_ticket()
ticket_element = cl.CustomElement(name="LinearTicket", props=props)
# Store the element if we want to update it server side at a later stage.
cl.user_session.set("ticket_el", ticket_element)
await cl.Message(content="Here is the ticket information!", elements=[ticket_element]).send()
Second we implement the custom element we reference in the Python code:
public/elements/LinearTicket.jsx
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Progress } from "@/components/ui/progress"
import { Clock, User, Tag } from "lucide-react"
export default function TicketStatusCard() {
const getProgressValue = (status) => {
const progress = {
'open': 25,
'in-progress': 50,
'resolved': 75,
'closed': 100
}
return progress[status] || 0
}
return (
)
}
Finally, we start the application with `chainlit run app.py` and send a first message in the UI.
The LinearTicket custom element rendered.
[](#advanced)
Advanced
--------------------------
###
[](#update-props-from-python)
Update Props from Python
To update a custom element props from the python code, you can store the element instance in the user session and call `.update()` on it.
import chainlit as cl
@cl.on_chat_start
async def start():
element = cl.CustomElement(name="Foo", props={"foo": "bar"})
cl.user_session.set("element", element)
@cl.on_message
async def on_message():
element = cl.user_session.get("element")
element.props["foo"] = "baz"
await element.update()
###
[](#call-a-function-from-python)
Call a Function from Python
If you need to call a function directly from the python code, you can use `cl.CopilotFunction`.
call\_func.py
import chainlit as cl
@cl.on_chat_start
async def start():
element = cl.CustomElement(name="CallFn")
await cl.Message(content="Hello", elements=[element]).send()
@cl.on_message
async def on_msg(msg: cl.Message):
fn = cl.CopilotFunction(name="test", args={"content": msg.content})
res = await fn.acall()
CallFn.jsx
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { callFnState } from '@chainlit/react-client';
export default function CallFnExample() {
const callFn = useRecoilValue(callFnState);
useEffect(() => {
if (callFn?.name === "test") {
// Replace the console log with your actual function
console.log("Function called with", callFn.args.content)
callFn.callback()
}
}, [callFn]);
return null
}
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/custom.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/custom)
[Chat Settings](/api-reference/chat-settings)
[Text](/api-reference/elements/text)
On this page
* [Attributes](#attributes)
* [How to Write the JSX file](#how-to-write-the-jsx-file)
* [Component definition](#component-definition)
* [Use Tailwind for Styling](#use-tailwind-for-styling)
* [Only Use Allowed Imports](#only-use-allowed-imports)
* [Available APIs](#available-apis)
* [Example of a Counter Element](#example-of-a-counter-element)
* [Full Example](#full-example)
* [Advanced](#advanced)
* [Update Props from Python](#update-props-from-python)
* [Call a Function from Python](#call-a-function-from-python)
Assistant
Responses are generated using AI and may contain mistakes.
---
# File - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
File
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `File` class allows you to display a button that lets users download the content of the file.
You must provide either an url or a path or content bytes.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the file. This will be shown to users.
[](#param-url)
url
str
The remote URL of the file image source.
[](#param-path)
path
str
The local file path of the file image.
[](#param-content)
content
bytes
The file content of the file image in bytes format.
[](#example)
Example
------------------------
import chainlit as cl
@cl.on_chat_start
async def start():
elements = [\
cl.File(\
name="hello.py",\
path="./hello.py",\
display="inline",\
),\
]
await cl.Message(
content="This message has a file element", elements=elements
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/file.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/file)
[Dataframe](/api-reference/elements/dataframe)
[PDF viewer](/api-reference/elements/pdf)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# PDF viewer - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
PDF viewer
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Pdf` class allows you to display a PDF hosted remotely or locally in the chatbot UI. This class either takes a URL of a PDF hosted online, or the path of a local PDF.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the PDF to be displayed in the UI.
[](#param-display)
display
ElementDisplay
Determines how the PDF element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#param-url)
url
str
The remote URL of the PDF file. Must provide url for a remote PDF (or either path or content for a local PDF).
[](#param-path)
path
str
The local file path of the PDF. Must provide either path or content for a local PDF (or url for a remote PDF).
[](#param-content)
content
bytes
The file content of the PDF in bytes format. Must provide either path or content for a local PDF (or url for a remote PDF).
[](#param-page)
page
int
The default rendered page. Must be an integer greater than 0 and less than or equal to the total number of pages in the PDF. The default value is 1.
[](#example)
Example
------------------------
###
[](#inline)
Inline
import chainlit as cl
@cl.on_chat_start
async def main():
# Sending a pdf with the local file path
elements = [\
cl.Pdf(name="pdf1", display="inline", path="./pdf1.pdf", page=1)\
]
cl.Message(content="Look at this local pdf!", elements=elements).send()
###
[](#side-and-page)
Side and Page
You must have the name of the pdf in the content of the message for the link to be created.
import chainlit as cl
@cl.on_chat_start
async def main():
# Sending a pdf with the local file path
elements = [\
cl.Pdf(name="pdf1", display="side", path="./pdf1.pdf", page=1)\
]
# Reminder: The name of the pdf must be in the content of the message
await cl.Message(content="Look at this local pdf1!", elements=elements).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/pdf.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/pdf)
[File](/api-reference/elements/file)
[Audio](/api-reference/elements/audio)
On this page
* [Attributes](#attributes)
* [Example](#example)
* [Inline](#inline)
* [Side and Page](#side-and-page)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Plotly - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Plotly
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Plotly` class allows you to display a Plotly chart in the chatbot UI. This class takes a Plotly figure.
The advantage of the `Plotly` element over the `Pyplot` element is that it’s interactive (the user can zoom on the chart for example).
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the chart to be displayed in the UI.
[](#param-display)
display
ElementDisplay
Determines how the chart element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#param-size)
size
ElementSize
Determines the size of the chart. Only works with display=“inline”. Choices are “small”, “medium” (default), or “large”.
[](#param-figure)
figure
str
The `plotly.graph_objects.Figure` instance that you want to display.
###
[](#example)
Example
import plotly.graph_objects as go
import chainlit as cl
@cl.on_chat_start
async def start():
fig = go.Figure(
data=[go.Bar(y=[2, 1, 3])],
layout_title_text="An example figure",
)
elements = [cl.Plotly(name="chart", figure=fig, display="inline")]
await cl.Message(content="This message has a chart", elements=elements).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/plotly.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/plotly)
[Video](/api-reference/elements/video)
[Pyplot](/api-reference/elements/pyplot)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Pyplot - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Pyplot
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Pyplot` class allows you to display a Matplotlib pyplot chart in the chatbot UI. This class takes a pyplot figure.
The difference of between this element and the `Plotly` element is that the user is shown a static image of the chart when using `Pyplot`.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the chart to be displayed in the UI.
[](#param-display)
display
ElementDisplay
Determines how the chart element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#param-size)
size
ElementSize
Determines the size of the chart. Only works with display=“inline”. Choices are “small”, “medium” (default), or “large”.
[](#param-figure)
figure
str
The `matplotlib.figure.Figure` instance that you want to display.
[](#example)
Example
------------------------
import matplotlib.pyplot as plt
import chainlit as cl
@cl.on_chat_start
async def main():
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
elements = [\
cl.Pyplot(name="plot", figure=fig, display="inline"),\
]
await cl.Message(
content="Here is a simple plot",
elements=elements,
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/pyplot.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/pyplot)
[Plotly](/api-reference/elements/plotly)
[TaskList](/api-reference/elements/tasklist)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Text - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Text
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Text` class allows you to display a text element in the chatbot UI. This class takes a string and creates a text element that can be sent to the UI. It supports the markdown syntax for formatting text.
You must provide either an url or a path or content bytes.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the text element to be displayed in the UI.
[](#param-content)
content
Union\[str, bytes\]
The text string or bytes that should be displayed as the content of the text element.
[](#param-url)
url
str
The remote URL of the text source.
[](#param-path)
path
str
The local file path of the text file.
[](#param-display)
display
ElementDisplay
Determines how the text element should be displayed in the UI. Choices are “side”, “inline”, or “page”.
[](#param-language)
language
str
Language of the code if the text is a piece of code. See [https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock—supported-languages](https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages)
for a list of supported languages.
[](#example)
Example
------------------------
import chainlit as cl
@cl.on_chat_start
async def start():
text_content = "Hello, this is a text element."
elements = [\
cl.Text(name="simple_text", content=text_content, display="inline")\
]
await cl.Message(
content="Check out this text element!",
elements=elements,
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/text.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/text)
[Custom](/api-reference/elements/custom)
[Image](/api-reference/elements/image)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# TaskList - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
TaskList
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `TaskList` class allows you to display a task list next to the chatbot UI.
[](#attributes)
Attributes
------------------------------
[](#param-status)
status
str
The status of the TaskList. We suggest using something short like “Ready”, “Running…”, “Failed”, “Done”.
[](#param-tasks)
tasks
Task
The list of tasks to be displayed in the UI.
[](#usage)
Usage
--------------------
The TaskList element is slightly different from other elements in that it is not attached to a Message or Step but can be sent directly to the chat interface.
import chainlit as cl
@cl.on_chat_start
async def main():
# Create the TaskList
task_list = cl.TaskList()
task_list.status = "Running..."
# Create a task and put it in the running state
task1 = cl.Task(title="Processing data", status=cl.TaskStatus.RUNNING)
await task_list.add_task(task1)
# Create another task that is in the ready state
task2 = cl.Task(title="Performing calculations")
await task_list.add_task(task2)
# Optional: link a message to each task to allow task navigation in the chat history
message = await cl.Message(content="Started processing data").send()
task1.forId = message.id
# Update the task list in the interface
await task_list.send()
# Perform some action on your end
await cl.sleep(1)
# Update the task statuses
task1.status = cl.TaskStatus.DONE
task2.status = cl.TaskStatus.FAILED
task_list.status = "Failed"
await task_list.send()
Task List in action
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/tasklist.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/tasklist)
[Pyplot](/api-reference/elements/pyplot)
[AskUserMessage](/api-reference/ask/ask-for-input)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Select - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Input Widgets
Select
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
###
[](#attributes)
Attributes
[](#param-id)
id
str
The identifier used to retrieve the widget value from the settings.
[](#param-label)
label
str
The label of the input widget.
[](#param-values)
values
List\[str\]
Labels for the select options.
[](#param-items)
items
Dict\[str, str\]
Labels with corresponding values for the select options.
[](#param-initial-value)
initial\_value
int
The initial value of the input widget.
[](#param-initial-index)
initial\_index
int
Index of the initial value of the input widget. Can only be used in combination with ‘values’.
[](#param-tooltip)
tooltip
str
The tooltip text shown when hovering over the tooltip icon next to the label.
[](#param-description)
description
str
The text displayed underneath the input widget.
###
[](#usage)
Usage
Code Example
import chainlit as cl
from chainlit.input_widget import Select
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[\
Select(\
id="Model",\
label="OpenAI - Model",\
values=["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4", "gpt-4-32k"],\
initial_index=0,\
)\
]
).send()
value = settings["Model"]
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/input-widgets/select.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/input-widgets/select)
[Window Messaging](/api-reference/window-message)
[Slider](/api-reference/input-widgets/slider)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Video - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Elements
Video
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Video` class allows you to display an video player for a specific video file in the chatbot user interface.
You must provide either an url or a path or content bytes.
[](#attributes)
Attributes
------------------------------
[](#param-name)
name
str
The name of the video file to be displayed in the UI. This is shown to users.
[](#param-display)
display
ElementDisplay
Determines where the element should be displayed in the UI. Choices are “side” (default), “inline”, or “page”.
[](#param-url)
url
str
The remote URL of the video.
[](#param-path)
path
str
The local file path of the video.
[](#param-content)
content
bytes
The file content of the video in bytes format.
[](#example)
Example
------------------------
import chainlit as cl
@cl.on_chat_start
async def main():
elements = [\
cl.Video(name="example.mp4", path="./example.mp4", display="inline"),\
]
await cl.Message(
content="Here is an video file",
elements=elements,
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/elements/video.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/elements/video)
[Audio](/api-reference/elements/audio)
[Plotly](/api-reference/elements/plotly)
On this page
* [Attributes](#attributes)
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Slider - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Input Widgets
Slider
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
###
[](#attributes)
Attributes
[](#param-id)
id
str
The identifier used to retrieve the widget value from the settings.
[](#param-label)
label
str
The label of the input widget.
[](#param-initial)
initial
int
The initial value of the input widget.
[](#param-min)
min
int
The minimum permitted slider value. Defaults to 0.
[](#param-max)
max
int
The maximum permitted slider value. Defaults to 10.
[](#param-step)
step
int
The stepping interval of the slider. Defaults to 1.
[](#param-tooltip)
tooltip
str
The tooltip text shown when hovering over the tooltip icon next to the label.
[](#param-description)
description
str
The text displayed underneath the input widget.
###
[](#usage)
Usage
Code Example
import chainlit as cl
from chainlit.input_widget import Slider
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[\
Slider(\
id="Temperature",\
label="OpenAI - Temperature",\
initial=1,\
min=0,\
max=2,\
step=0.1,\
),\
]
).send()
value = settings["Temperature"]
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/input-widgets/slider.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/input-widgets/slider)
[Select](/api-reference/input-widgets/select)
[Switch](/api-reference/input-widgets/switch)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Tags - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Input Widgets
Tags
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
###
[](#attributes)
Attributes
[](#param-id)
id
str
The identifier used to retrieve the widget value from the settings.
[](#param-label)
label
str
The label of the input widget.
[](#param-initial)
initial
List\[str\]
The initial values of the input widget.
[](#param-tooltip)
tooltip
str
The tooltip text shown when hovering over the tooltip icon next to the label.
[](#param-description)
description
str
The text displayed underneath the input widget.
###
[](#usage)
Usage
Code Example
import chainlit as cl
from chainlit.input_widget import Tags
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[\
Tags(id="StopSequence", label="OpenAI - StopSequence", initial=["Answer:"]),\
]
).send()
value = settings["StopSequence"]
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/input-widgets/tags.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/input-widgets/tags)
[Switch](/api-reference/input-widgets/switch)
[TextInput](/api-reference/input-widgets/textinput)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Switch - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Input Widgets
Switch
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
###
[](#attributes)
Attributes
[](#param-id)
id
str
The identifier used to retrieve the widget value from the settings.
[](#param-label)
label
str
The label of the input widget.
[](#param-initial)
initial
int
The initial value of the input widget.
[](#param-tooltip)
tooltip
str
The tooltip text shown when hovering over the tooltip icon next to the label.
[](#param-description)
description
str
The text displayed underneath the input widget.
###
[](#usage)
Usage
Code Example
import chainlit as cl
from chainlit.input_widget import Switch
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[\
Switch(id="Streaming", label="OpenAI - Stream Tokens", initial=True),\
]
).send()
value = settings["Streaming"]
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/input-widgets/switch.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/input-widgets/switch)
[Slider](/api-reference/input-widgets/slider)
[Tags](/api-reference/input-widgets/tags)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# TextInput - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Input Widgets
TextInput
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
###
[](#attributes)
Attributes
[](#param-id)
id
str
The identifier used to retrieve the widget value from the settings.
[](#param-label)
label
str
The label of the input widget.
[](#param-initial)
initial
str
The initial value of the input widget.
[](#param-placeholder)
placeholder
str
The placeholder value of the input widget.
[](#param-tooltip)
tooltip
str
The tooltip text shown when hovering over the tooltip icon next to the label.
[](#param-description)
description
str
The text displayed underneath the input widget.
###
[](#usage)
Usage
Code Example
import chainlit as cl
from chainlit.input_widget import TextInput
@cl.on_chat_start
async def start():
settings = await cl.ChatSettings(
[\
TextInput(id="AgentName", label="Agent Name", initial="AI"),\
]
).send()
value = settings["AgentName"]
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/input-widgets/textinput.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/input-widgets/textinput)
[Tags](/api-reference/input-widgets/tags)
On this page
* [Attributes](#attributes)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Langchain Callback Handler - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Integrations
Langchain Callback Handler
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The following code example demonstrates how to pass a callback handler:
llm = OpenAI(temperature=0)
llm_math = LLMMathChain.from_llm(llm=llm)
@cl.on_message
async def main(message: cl.Message):
res = await llm_math.acall(message.content, callbacks=[cl.LangchainCallbackHandler()])
await cl.Message(content="Hello").send()
[](#final-answer-streaming)
Final Answer streaming
------------------------------------------------------
If streaming is enabled at the LLM level, Langchain will only stream the intermediate steps. You can enable final answer streaming by passing `stream_final_answer=True` to the callback handler.
# Optionally, you can also pass the prefix tokens that will be used to identify the final answer
answer_prefix_tokens=["FINAL", "ANSWER"]
cl.LangchainCallbackHandler(
stream_final_answer=True,
answer_prefix_tokens=answer_prefix_tokens,
)
Final answer streaming will only work with prompts that have a consistent final answer pattern. It will also not work with `AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION`
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/integrations/langchain.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/integrations/langchain)
[AskUserAction](/api-reference/ask/ask-for-action)
[LlamaIndex Callback Handler](/api-reference/integrations/llamaindex)
On this page
* [Final Answer streaming](#final-answer-streaming)
Assistant
Responses are generated using AI and may contain mistakes.
---
# LlamaIndex Callback Handler - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Integrations
LlamaIndex Callback Handler
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Callback Handler to enable Chainlit to display intermediate steps in the UI.
###
[](#usage)
Usage
Code Example
from llama_index.core.callbacks import CallbackManager
from llama_index.core.service_context import ServiceContext
import chainlit as cl
@cl.on_chat_start
async def start():
service_context = ServiceContext.from_defaults(callback_manager=CallbackManager([cl.LlamaIndexCallbackHandler()]))
# use the service context to create the predictor
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/integrations/llamaindex.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/integrations/llamaindex)
[Langchain Callback Handler](/api-reference/integrations/langchain)
[author\_rename and Message author](/api-reference/author-rename)
On this page
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_audio_chunk - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_audio\_chunk
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Hook to react to an incoming audio chunk from the user’s microphone.
[](#usage)
Usage
--------------------
from io import BytesIO
import chainlit as cl
@cl.on_audio_chunk
async def on_audio_chunk(chunk: cl.InputAudioChunk):
pass
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-audio-chunk.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-audio-chunk)
[on\_logout](/api-reference/lifecycle-hooks/on-logout)
[on\_audio\_end](/api-reference/lifecycle-hooks/on-audio-end)
On this page
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_audio_end - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_audio\_end
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Hook to react to the end of an audio recording coming from the user’s microphone.
[](#usage)
Usage
--------------------
from io import BytesIO
import chainlit as cl
@cl.on_audio_end
async def on_audio_end():
pass
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-audio-end.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-audio-end)
[on\_audio\_chunk](/api-reference/lifecycle-hooks/on-audio-chunk)
[Message](/api-reference/message)
On this page
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_chat_resume - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_chat\_resume
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Decorator to enable users to continue a conversation. Requires both [data persistence](/data-persistence/overview)
and [authentication](/authentication)
to be enabled.
This decorator will automatically:
* Send the persisted messages and elements to the UI.
* Restore the user session.
Only JSON serializable fields of the user session will be saved and restored.
[](#usage)
Usage
--------------------
At minimum, you will need to use the `@cl.on_chat_resume` decorator to resume conversations.
@cl.on_chat_resume
async def on_chat_resume(thread):
pass
However, if you are using a Langchain agent for instance, you will need to reinstantiate and set it in the user session yourself.
[Resume Langchain Chat Example\
-----------------------------\
\
Practical example of how to resume a chat with context.](https://github.com/Chainlit/cookbook/tree/main/resume-chat)
[](#parameters)
Parameters
------------------------------
[](#param-thread)
thread
ThreadDict
The persisted chat to resume.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-chat-resume.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-chat-resume)
[on\_chat\_end](/api-reference/lifecycle-hooks/on-chat-end)
[on\_message](/api-reference/lifecycle-hooks/on-message)
On this page
* [Usage](#usage)
* [Parameters](#parameters)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_chat_end - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_chat\_end
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Hook to react to the user websocket disconnection event.
[](#usage)
Usage
--------------------
import chainlit as cl
@cl.on_chat_start
def start():
print("hello", cl.user_session.get("id"))
@cl.on_chat_end
def end():
print("goodbye", cl.user_session.get("id"))
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-chat-end.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-chat-end)
[on\_chat\_start](/api-reference/lifecycle-hooks/on-chat-start)
[on\_chat\_resume](/api-reference/lifecycle-hooks/on-chat-resume)
On this page
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_chat_start - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_chat\_start
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Hook to react to the user websocket connection event.
[](#usage)
Usage
--------------------
Code Example
from chainlit import AskUserMessage, Message, on_chat_start
@on_chat_start
async def main():
res = await AskUserMessage(content="What is your name?", timeout=30).send()
if res:
await Message(
content=f"Your name is: {res['content']}.\nChainlit installation is working!\nYou can now start building your own chainlit apps!",
).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-chat-start.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-chat-start)
[on\_chat\_end](/api-reference/lifecycle-hooks/on-chat-end)
On this page
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_logout - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_logout
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Decorator to react to a user logging out. Useful to clear cookies or other user data through the HTTP response.
[](#parameters)
Parameters
------------------------------
[](#param-request)
request
fastapi.Request
The request object.
[](#param-response)
response
fastapi.Response
The response object.
[](#usage)
Usage
--------------------
from fastapi import Request, Response
import chainlit as cl
@cl.on_logout
def main(request: Request, response: Response):
response.delete_cookie("my_cookie")
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-logout.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-logout)
[on\_message](/api-reference/lifecycle-hooks/on-message)
[on\_audio\_chunk](/api-reference/lifecycle-hooks/on-audio-chunk)
On this page
* [Parameters](#parameters)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# on_message - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Life Cycle Hooks
on\_message
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Decorator to react to messages coming from the UI. The decorated function is called every time a new message is received.
[](#parameters)
Parameters
------------------------------
[](#param-message)
message
cl.Message
The message coming from the UI.
[](#usage)
Usage
--------------------
import chainlit as cl
@cl.on_message
def main(message: cl.Message):
content = message.content
# do something
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/lifecycle-hooks/on-message.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/lifecycle-hooks/on-message)
[on\_chat\_resume](/api-reference/lifecycle-hooks/on-chat-resume)
[on\_logout](/api-reference/lifecycle-hooks/on-logout)
On this page
* [Parameters](#parameters)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# make_async - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Misceallaneous
make\_async
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `make_async` function takes a synchronous function (for instance a LangChain agent) and returns an asynchronous function that will run the original function in a separate thread. This is useful to run long running synchronous tasks without blocking the event loop.
[](#parameters)
Parameters
------------------------------
[](#param-func)
func
Callable
The synchronous function to run in a separate thread.
[](#returns)
Returns
------------------------
[](#param-async-function)
async\_function
Coroutine
required
The asynchronous function that will run the synchronous function in a separate thread.
[](#usage)
Usage
--------------------
import time
import chainlit as cl
def sync_func():
time.sleep(5)
return "Hello!"
@cl.on_message
async def main(message: cl.Message):
answer = await cl.make_async(sync_func)()
await cl.Message(
content=answer,
).send()
LangChain agent
import chainlit as cl
res = await cl.make_async(agent)(input_str, callbacks=[cl.LangchainCallbackHandler()])
await cl.Message(content=res["text"]).send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/make-async.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/make-async)
[author\_rename and Message author](/api-reference/author-rename)
[cache](/api-reference/cache)
On this page
* [Parameters](#parameters)
* [Returns](#returns)
* [Usage](#usage)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Message - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Chat
Message
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Message` class is designed to send, stream, update or remove messages.
[](#parameters)
Parameters
------------------------------
[](#param-content)
content
str
The content of the message.
[](#param-author)
author
str
The author of the message, defaults to the chatbot name defined in your config file.
[](#param-elements)
elements
Element\[\]
Elements to attach to the message.
[](#param-actions)
actions
Action\[\]
Actions to attach to the message.
[](#param-language)
language
str
Language of the code if the content is code. See [https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock—supported-languages](https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages)
for a list of supported languages.
[](#send-a-message)
Send a message
--------------------------------------
Send a new message to the UI.
import chainlit as cl
@cl.on_message
async def main(message: cl.Message):
await cl.Message(
content=f"Received: {message.content}",
).send()
[](#stream-a-message)
Stream a message
------------------------------------------
Send a message token by token to the UI.
import chainlit as cl
token_list = ["the", "quick", "brown", "fox"]
@cl.on_chat_start
async def main():
msg = cl.Message(content="")
for token in token_list:
await msg.stream_token(token)
await msg.send()
[](#update-a-message)
Update a message
------------------------------------------
Update a message that already has been sent.
import chainlit as cl
@cl.on_chat_start
async def main():
msg = cl.Message(content="Hello!")
await msg.send()
await cl.sleep(2)
msg.content = "Hello again!"
await msg.update()
[](#remove-a-message)
Remove a message
------------------------------------------
Remove a message from the UI.
import chainlit as cl
@cl.on_chat_start
async def main():
msg = cl.Message(content="Message 1")
await msg.send()
await cl.sleep(2)
await msg.remove()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/message.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/message)
[on\_audio\_end](/api-reference/lifecycle-hooks/on-audio-end)
[Step Decorator](/api-reference/step-decorator)
On this page
* [Parameters](#parameters)
* [Send a message](#send-a-message)
* [Stream a message](#stream-a-message)
* [Update a message](#update-a-message)
* [Remove a message](#remove-a-message)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Step Class - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Chat
Step Class
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `Step` class is a Python Context Manager that can be used to create steps in your chainlit app. The step is created when the context manager is entered and is updated to the client when the context manager is exited.
[](#parameters)
Parameters
------------------------------
[](#param-name)
name
str
The name of the step. Default to the name of the decorated function.
[](#param-type)
type
Enum
default:"undefined"
The type of the step, useful for monitoring and debugging.
[](#param-elements)
elements
List\[Element\]
Elements to attach to the step.
[](#param-language)
language
str
Language of the output. See [https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock—supported-languages](https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages)
for a list of supported languages.
[](#param-show-input)
show\_input
Union\[bool, str\]
default:"False"
By default only the output of the step is shown. Set this to `True` to also show the input. You can also set this to a language like `json` or `python` to syntax highlight the input.
[](#send-a-step)
Send a Step
--------------------------------
import chainlit as cl
@cl.on_message
async def main():
async with cl.Step(name="Test") as step:
# Step is sent as soon as the context manager is entered
step.input = "hello"
step.output = "world"
# Step is updated when the context manager is exited
[](#stream-the-output)
Stream the Output
--------------------------------------------
from openai import AsyncOpenAI
import chainlit as cl
client = AsyncOpenAI()
@cl.on_message
async def main(msg: cl.Message):
async with cl.Step(name="gpt4", type="llm") as step:
step.input = msg.content
stream = await client.chat.completions.create(
messages=[{"role": "user", "content": msg.content}],
stream=True,
model="gpt-4",
temperature=0,
)
async for part in stream:
delta = part.choices[0].delta
if delta.content:
# Stream the output of the step
await step.stream_token(delta.content)
[](#nest-steps)
Nest Steps
------------------------------
To nest steps, simply create a step inside another step.
import chainlit as cl
@cl.on_chat_start
async def main():
async with cl.Step(name="Parent step") as parent_step:
parent_step.input = "Parent step input"
async with cl.Step(name="Child step") as child_step:
child_step.input = "Child step input"
child_step.output = "Child step output"
parent_step.output = "Parent step output"
[](#update-a-step)
Update a Step
------------------------------------
import chainlit as cl
@cl.on_chat_start
async def main():
async with cl.Step(name="Parent step") as step:
step.input = "Parent step input"
step.output = "Parent step output"
await cl.sleep(2)
step.output = "Parent step output updated"
await step.update()
[](#remove-a-step)
Remove a Step
------------------------------------
import chainlit as cl
@cl.on_chat_start
async def main():
async with cl.Step(name="Parent step") as step:
step.input = "Parent step input"
step.output = "Parent step output"
await cl.sleep(2)
await step.remove()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/step-class.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/step-class)
[Step Decorator](/api-reference/step-decorator)
[Action](/api-reference/action)
On this page
* [Parameters](#parameters)
* [Send a Step](#send-a-step)
* [Stream the Output](#stream-the-output)
* [Nest Steps](#nest-steps)
* [Update a Step](#update-a-step)
* [Remove a Step](#remove-a-step)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Step Decorator - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Chat
Step Decorator
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The step decorator will log steps based on the decorated function. By default, the arguments of the function will be used as the input of the step and the return value will be used as the output.
Under the hood, the step decorator is using the [cl.Step](/api-reference/step-class)
class.
[](#parameters)
Parameters
------------------------------
[](#param-name)
name
str
The name of the step. Default to the name of the decorated function.
[](#param-type)
type
str
default:"undefined"
The type of the step, useful for monitoring and debugging.
[](#param-language)
language
str
Language of the output. See [https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock—supported-languages](https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages)
for a list of supported languages.
[](#param-show-input)
show\_input
Union\[bool, str\]
default:"False"
By default only the output of the step is shown. Set this to `True` to also show the input. You can also set this to a language like `json` or `python` to syntax highlight the input.
[](#access-the-current-step)
Access the Current step
--------------------------------------------------------
You can access the current step object using `cl.context.current_step` and override values.
import chainlit as cl
@cl.step
async def my_step():
current_step = cl.context.current_step
# Override the input of the step
current_step.input = "My custom input"
# Override the output of the step
current_step.output = "My custom output"
[](#stream-the-output)
Stream the Output
--------------------------------------------
from openai import AsyncOpenAI
import chainlit as cl
client = AsyncOpenAI(api_key="YOUR_API_KEY")
@cl.step(type="llm")
async def gpt4():
settings = {
"model": "gpt-4",
"temperature": 0,
}
stream = await client.chat.completions.create(
messages=message_history, stream=True, **settings
)
current_step = cl.context.current_step
async for part in stream:
delta = part.choices[0].delta
if delta.content:
# Stream the output of the step
await current_step.stream_token(delta.content)
[](#nest-steps)
Nest Steps
------------------------------
If another step decorated function is called inside the decorated function, the child step will be nested under the parent step.
import chainlit as cl
@cl.step
async def parent_step():
await child_step()
return "Parent step output"
@cl.step
async def child_step():
return "Child step output"
@cl.on_chat_start
async def main():
await parent_step()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/step-decorator.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/step-decorator)
[Message](/api-reference/message)
[Step Class](/api-reference/step-class)
On this page
* [Parameters](#parameters)
* [Access the Current step](#access-the-current-step)
* [Stream the Output](#stream-the-output)
* [Nest Steps](#nest-steps)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Window Messaging - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Misceallaneous
Window Messaging
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
[](#on-window-message)
on\_window\_message
==============================================
Decorator to react to messages coming from the Web App’s parent window. The decorated function is called every time a new window message is received.
[](#parameters)
Parameters
------------------------------
[](#param-message)
message
str
The message coming from the Web App’s parent window.
[](#usage)
Usage
--------------------
import chainlit as cl
@cl.on_window_message
def main(message: str):
# do something
[](#send-window-message)
send\_window\_message
==================================================
Function to send messages to the Web App’s parent window.
[](#parameters-2)
Parameters
--------------------------------
[](#param-message-1)
message
str
The message to send to the Web App’s parent window.
[](#usage-2)
Usage
----------------------
@cl.on_message
async def message():
await cl.send_window_message("Server: Hello from Chainlit")
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/api-reference/window-message.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /api-reference/window-message)
[Custom Data Layer](/api-reference/data-persistence/custom-data-layer)
[Select](/api-reference/input-widgets/select)
On this page
* [on\_window\_message](#on-window-message)
* [Parameters](#parameters)
* [Usage](#usage)
* [send\_window\_message](#send-window-message)
* [Parameters](#parameters-2)
* [Usage](#usage-2)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Header - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Authentication
Header
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Header auth is a simple way to authenticate users using a header. It is typically used to delegate authentication to a reverse proxy.
The `header_auth_callback` function is called with the headers of the request. It should return a `User` object if the user is authenticated, or `None` if the user is not authenticated. The callback function (defined by the user) is responsible for managing the authentication logic.
[](#example)
Example
------------------------
from typing import Optional
import chainlit as cl
@cl.header_auth_callback
def header_auth_callback(headers: Dict) -> Optional[cl.User]:
# Verify the signature of a token in the header (ex: jwt token)
# or check that the value is matching a row from your database
if headers.get("test-header") == "test-value":
return cl.User(identifier="admin", metadata={"role": "admin", "provider": "header"})
else:
return None
Using this code, you will not be able to access the app unless the header `test-header` is set to `test-value` when sending any request to the app.
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/authentication/header.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /authentication/header)
[Password](/authentication/password)
[OAuth](/authentication/oauth)
On this page
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Overview - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Authentication
Overview
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
Chainlit applications are public by default. To enable authentication and make your app private, you need to:
1. Define a `CHAINLIT_AUTH_SECRET` environment variable. This is a secret string that is used to sign the authentication tokens. You can change it at any time, but it will log out all users. You can easily generate one using `chainlit create-secret`.
2. Add one or more authentication callbacks to your app:
[Password Auth\
-------------\
\
Authenticate users with login/password.](/authentication/password)
[OAuth\
-----\
\
Authenticate users with your own OAuth app (like Google).](/authentication/oauth)
[Header\
------\
\
Authenticate users based on a custom header.](/authentication/header)
Each callback take a different input and optionally return a `cl.User` object. If the callback returns `None`, the authentication is considered as failed.
Make sure each user has a unique identifier to prevent them from sharing their data.
[](#get-the-current-authenticated-user)
Get the current authenticated user
------------------------------------------------------------------------------
You can access the current authenticated user through the [User Session](/concepts/user-session)
.
@cl.on_chat_start
async def on_chat_start():
app_user = cl.user_session.get("user")
await cl.Message(f"Hello {app_user.identifier}").send()
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/authentication/overview.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /authentication/overview)
[Enterprise](/llmops/enterprise)
[Password](/authentication/password)
On this page
* [Get the current authenticated user](#get-the-current-authenticated-user)
Assistant
Responses are generated using AI and may contain mistakes.
---
# Password - Chainlit
[Chainlit home page](https://github.com/Chainlit/chainlit)
Search...
Search...
Navigation
Authentication
Password
[Documentation](/get-started/overview)
[Examples](/examples/cookbook)
[API Reference](/api-reference/lifecycle-hooks/on-chat-start)
The `@cl.password_auth_callback` receives the username and password from the login form. Returning an `cl.User` object will authenticate the user while returning `None` will fail the authentication.
You can verify the credentials against any service that you’d like (your own DB, a private google sheet etc.).
The usual security best practices applies here, hash password before storing them.
[](#example)
Example
------------------------
from typing import Optional
import chainlit as cl
@cl.password_auth_callback
def auth_callback(username: str, password: str):
# Fetch the user matching username from your database
# and compare the hashed password with the value stored in the database
if (username, password) == ("admin", "admin"):
return cl.User(
identifier="admin", metadata={"role": "admin", "provider": "credentials"}
)
else:
return None
Was this page helpful?
YesNo
[Suggest edits](https://github.com/chainlit/docs/edit/main/authentication/password.mdx)
[Raise issue](https://github.com/chainlit/docs/issues/new?title=Issue on docs&body=Path: /authentication/password)
[Overview](/authentication/overview)
[Header](/authentication/header)
On this page
* [Example](#example)
Assistant
Responses are generated using AI and may contain mistakes.
---