QueryChat
QueryChat(
data_source,
table_name,
*,
id=None,
greeting=None,
client=None,
tools=('update', 'query'),
data_description=None,
categorical_threshold=20,
extra_instructions=None,
prompt_template=None,
)Create a QueryChat instance.
QueryChat enables natural language interaction with your data through an LLM-powered chat interface. It can be used in Shiny applications, as a standalone chat client, or in an interactive console.
Examples
Basic Shiny app:
from querychat import QueryChat
qc = QueryChat(my_dataframe, "my_data")
qc.app()Standalone chat client:
from querychat import QueryChat
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
qc = QueryChat(df, "my_data")
# Get a chat client with all tools
client = qc.client()
response = client.chat("What's the average of column a?")
# Start an interactive console chat
qc.console()Privacy-focused mode: Only allow dashboard filtering, ensuring the LLM can’t see any raw data.
qc = QueryChat(df, "my_data", tools="update")
qc.app()Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data_source | IntoFrame | sqlalchemy.Engine |
Either a Narwhals-compatible data frame (e.g., Polars or Pandas) or a SQLAlchemy engine containing the table to query against. | required |
| table_name | str | If a data_source is a data frame, a name to use to refer to the table in SQL queries (usually the variable name of the data frame, but it doesn’t have to be). If a data_source is a SQLAlchemy engine, the table_name is the name of the table in the database to query against. | required |
| id | Optional[str] | An optional ID for the QueryChat module. If not provided, an ID will be generated based on the table_name. | None |
| greeting | Optional[str | Path] | A string in Markdown format, containing the initial message. If a pathlib.Path object is passed, querychat will read the contents of the path into a string with .read_text(). You can use querychat.greeting() to help generate a greeting from a querychat configuration. If no greeting is provided, one will be generated at the start of every new conversation. |
None |
| client | Optional[str | chatlas.Chat] |
A chatlas.Chat object or a string to be passed to chatlas.ChatAuto()’s provider_model parameter, describing the provider and model combination to use (e.g. "openai/gpt-4.1", “anthropic/claude-sonnet-4-5”, “google/gemini-2.5-flash”. etc). If client is not provided, querychat consults the QUERYCHAT_CLIENT environment variable. If that is not set, it defaults to "openai". |
None |
| tools | TOOL_GROUPS | tuple[TOOL_GROUPS, …] | None |
Which querychat tools to include in the chat client by default. Can be: - A single tool string: "update" or "query" - A tuple of tools: ("update", "query") - None or () to disable all tools Default is ("update", "query") (both tools enabled). Set to "update" to prevent the LLM from accessing data values, only allowing dashboard filtering without answering questions. The tools can be overridden per-client by passing a different tools parameter to the .client() method. |
('update', 'query') |
| data_description | Optional[str | Path] | Description of the data in plain text or Markdown. If a pathlib.Path object is passed, querychat will read the contents of the path into a string with .read_text(). |
None |
| categorical_threshold | int | Threshold for determining if a column is categorical based on number of unique values. | 20 |
| extra_instructions | Optional[str | Path] | Additional instructions for the chat model. If a pathlib.Path object is passed, querychat will read the contents of the path into a string with .read_text(). |
None |
| prompt_template | Optional[str | Path] | Path to or a string of a custom prompt file. If not provided, the default querychat template will be used. This should be a Markdown file that contains the system prompt template. The mustache template can use the following variables: - {db_engine}: The database engine used (e.g., “DuckDB”) - {schema}: The schema of the data source, generated by data_source.get_schema() - {data_description}: The optional data description provided - {extra_instructions}: Any additional instructions provided |
None |
Attributes
| Name | Description |
|---|---|
| data_source | Get the current data source. |
| system_prompt | Get the system prompt. |
Methods
| Name | Description |
|---|---|
| app | Quickly chat with a dataset. |
| cleanup | Clean up resources associated with the data source. |
| client | Create a chat client with registered tools. |
| console | Launch an interactive console chat with the data. |
| generate_greeting | Generate a welcome greeting for the chat. |
| server | Initialize Shiny server logic. |
| sidebar | Create a sidebar containing the querychat UI. |
| ui | Create the UI for the querychat component. |
app
QueryChat.app(bookmark_store='url')Quickly chat with a dataset.
Creates a Shiny app with a chat sidebar and data table view – providing a quick-and-easy way to start chatting with your data.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| bookmark_store | Literal['url', 'server', 'disable'] | The bookmarking store to use for the Shiny app. Options are: - "url": Store bookmarks in the URL (default). - "server": Store bookmarks on the server. - "disable": Disable bookmarking. |
'url' |
Returns
| Name | Type | Description |
|---|---|---|
App |
A Shiny App object that can be run with app.run() or served with shiny run. |
cleanup
QueryChat.cleanup()Clean up resources associated with the data source.
Call this method when you are done using the QueryChat object to close database connections and avoid resource leaks.
Returns
| Name | Type | Description |
|---|---|---|
| None |
client
QueryChat.client(tools=MISSING, update_dashboard=None, reset_dashboard=None)Create a chat client with registered tools.
This method creates a standalone chat client configured with the specified tools and callbacks. Each call returns an independent client instance with its own conversation state.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| tools | TOOL_GROUPS | tuple[TOOL_GROUPS, …] | None | MISSING_TYPE |
Which tools to include: "update", "query", or both. Can be: - A single tool string: "update" or "query" - A tuple of tools: ("update", "query") - None or () to skip adding any tools - If not provided (default), uses the tools specified during initialization |
MISSING |
| update_dashboard | Callable[[UpdateDashboardData], None] | None |
Optional callback function to call when the update_dashboard tool succeeds. Takes a dict with "query" and "title" keys. Only used if "update" is in tools. |
None |
| reset_dashboard | Callable[[], None] | None | Optional callback function to call when the tool_reset_dashboard is invoked. Takes no arguments. Only used if "update" is in tools. |
None |
Returns
| Name | Type | Description |
|---|---|---|
chatlas.Chat |
A configured chat client with tools registered based on the tools parameter. |
Examples
from querychat import QueryChat
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3]})
qc = QueryChat(df, "my_data")
# Create client with all tools (default)
client = qc.client()
response = client.chat("What's the average of column a?")
# Create client with only query tool (single string)
client = qc.client(tools="query")
# Create client with only query tool (tuple)
client = qc.client(tools=("query",))
# Create client with custom callbacks
from querychat import UpdateDashboardData
def my_update(data: UpdateDashboardData):
print(f"Query: {data['query']}, Title: {data['title']}")
client = qc.client(update_dashboard=my_update)console
QueryChat.console(new=False, tools='query', **kwargs)Launch an interactive console chat with the data.
This method provides a REPL (Read-Eval-Print Loop) interface for chatting with your data from the command line. The console session persists by default, so you can exit and return to continue your conversation.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| new | bool | If True, creates a new chat client and starts a fresh conversation. If False (default), continues the conversation from the previous console session. | False |
| tools | TOOL_GROUPS | tuple[TOOL_GROUPS, …] | None |
Which tools to include: “update”, “query”, or both. Can be: - A single tool string: "update" or "query" - A tuple of tools: ("update", "query") - None or () to skip adding any tools - If not provided (default), defaults to ("query",) only for privacy (prevents the LLM from accessing data values) Ignored if new=False and a console session already exists. |
'query' |
| **kwargs | Additional arguments passed to the client() method when creating a new client. |
{} |
Examples
from querychat import QueryChat
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
qc = QueryChat(df, "my_data")
# Start console (query tool only by default)
qc.console()
# Start fresh console with all tools (using tuple)
qc.console(new=True, tools=("update", "query"))
# Start fresh console with all tools (using single string for one tool)
qc.console(new=True, tools="query")
# Continue previous console session
qc.console() # picks up where you left offgenerate_greeting
QueryChat.generate_greeting(echo='none')Generate a welcome greeting for the chat.
By default, QueryChat() generates a greeting at the start of every new conversation, which is convenient for getting started and development, but also might add unnecessary latency and cost. Use this method to generate a greeting once and save it for reuse.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| echo | Literal['none', 'output'] | If echo = "output", prints the greeting to standard output. If echo = "none" (default), does not print anything. |
'none' |
Returns
| Name | Type | Description |
|---|---|---|
| The greeting string (in Markdown format). |
server
QueryChat.server(enable_bookmarking=False, id=None)Initialize Shiny server logic.
This method is intended for use in Shiny Code mode, where the user must explicitly call .server() within the Shiny server function. In Shiny Express mode, you can use querychat.express.QueryChat instead of querychat.QueryChat, which calls .server() automatically.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| enable_bookmarking | bool | Whether to enable bookmarking for the querychat module. | False |
| id | Optional[str] | Optional module ID for the QueryChat instance. If not provided, will use the ID provided at initialization. This must match the ID used in the .ui() or .sidebar() methods. |
None |
Examples
from shiny import App, render, ui
from seaborn import load_dataset
from querychat import QueryChat
titanic = load_dataset("titanic")
qc = QueryChat(titanic, "titanic")
def app_ui(request):
return ui.page_sidebar(
qc.sidebar(),
ui.card(
ui.card_header(ui.output_text("title")),
ui.output_data_frame("data_table"),
),
title="Titanic QueryChat App",
fillable=True,
)
def server(input, output, session):
qc_vals = qc.server(enable_bookmarking=True)
@render.data_frame
def data_table():
return qc_vals.df()
@render.text
def title():
return qc_vals.title() or "My Data"
app = App(app_ui, server, bookmark_store="url")Returns
| Name | Type | Description |
|---|---|---|
| ServerValues | A ServerValues dataclass containing session-specific reactive values and the chat client. See ServerValues documentation for details on the available attributes. |
ui
QueryChat.ui(id=None, **kwargs)Create the UI for the querychat component.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| id | Optional[str] | Optional ID for the QueryChat instance. If not provided, will use the ID provided at initialization. | None |
| **kwargs | Additional arguments to pass to shinychat.chat_ui(). |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| A UI component. |