Skip to content

(py) Allow QueryChat class to be created with an empty chat client #205

@npelikan

Description

@npelikan

When using Querychat with Posit Connect managed Oauth credentials, all data/model connections must be created in the shiny server function, as connections using managed credentials need access to the http headers in the shiny session object. Currently, when creating the QueryChat class, the default behavior is to attempt to connect to OpenAI, resulting in an exception when the OPENAI_API_KEY envvar is not found.

There's an easy fix to this (set the OPENAI_API_KEY envvar with a dummy value), however it's not great developer experience. We should allow the QueryChat class to be created with NO chat client, and the chat client to be added on later.

Reprex:

from shiny import App, ui
import ibis
import querychat
from chatlas import ChatAnthropic
import pandas as pd


# Create a simple greeting and data description
greeting = "Welcome! Ask questions about the mtcars dataset."
data_desc = """
This dataset contains information about various car models including:
- mpg: Miles per gallon
- cyl: Number of cylinders
- hp: Horsepower
- wt: Weight
"""

# Instantiate QueryChat outside of server function
# the error will happen here -- it will not reproduce if you have OPENAI_API_KEY set in your env
qc = querychat.QueryChat(
    None,
    table_name="mtcars",
    greeting=greeting,
    data_description=data_desc
)

app_ui = ui.page_sidebar(
    ui.card(
        ui.card_header("Data"),
        ui.output_data_frame("data_table")
    ),
    sidebar= qc.sidebar(),
    title="Minimal QueryChat Example"
)

def server(input, output, session):
    # Posit Connect managed credential code would go here
    
    qc.client = ChatAnthropic()
    
    # Create an in-memory Ibis connection with mtcars data
    conn = ibis.connect("duckdb://")
    
    mtcars_data = pd.DataFrame({
        'mpg': [21.0, 21.0, 22.8, 21.4],
        'cyl': [6, 6, 4, 6],
        'hp': [110, 110, 93, 110],
        'wt': [2.620, 2.875, 2.320, 3.215]
    })
    
    mtcars_table = conn.create_table("mtcars", mtcars_data)
    
    # Get QueryChat's reactive values
    qc_vals = qc.server(data_source=mtcars_table)
    
    @output
    @render.data_frame
    def data_table():
        return qc_vals.df().to_pandas()

app = App(app_ui, server)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions