gradio icon indicating copy to clipboard operation
gradio copied to clipboard

Ability to update headers and types in `gr.Update` for a data frame

Open ankrgyl opened this issue 2 years ago • 2 comments

  • [x] I have searched to see if a similar issue already exists.

Is your feature request related to a problem? Please describe.

I'm working on a gradio demo that runs queries over a dataset and returns results in a data frame. The schema of the result (fields and types) changes, based on the query. Furthermore, the data contains rich media types (using the markdown type), so I can't simply update via a pandas DataFrame.

Describe the solution you'd like

Currently, gr.Update() does not allow you provide the headers or fields in gr.Update(). I'd like to be able to pass them in.

Additional context
Add any other context or screenshots about the feature request here.

ankrgyl avatar Sep 28 '22 16:09 ankrgyl

Since you can return a dict from the predict function containing header and data in order to populate a Dataframe, I think you should be able to set this dict as the value in order to update the headers via an Update method:

def update_fn(args):
  return gr.Update(value={"headers": ["some", "new", "headers"], "data": [...]})

Can you try this and see if it works? I could be totally wrong but I feel like this should work.

pngwn avatar Sep 28 '22 20:09 pngwn

It unfortunately did not work for me. This is roughly what I'm attempting to do:

https://www.loom.com/share/8c57c20875c148d9a18857d9d03fcef1

import gradio as gr

initial_table = [
    ["![HF](https://huggingface.co/front/assets/huggingface_logo-noborder.svg)"],
    [
        "![Impira](https://assets-global.website-files.com/5e3898dff507782a6580d710/605900c97eb21442df5b7f28_Logo_lock_up_150x63-website.gif)"
    ],
]


def run_query(query, data):
    data = data.to_dict("records")
    for row in data:
        row["foo"] = 1

    return {"headers": list(data[0].keys()), "data": data}


with gr.Blocks() as demo:
    file_dataset = gr.Dataframe(
        value=initial_table,
        datatype=["markdown"],
        headers=["file"],
        interactive=False,
    )

    query = gr.Textbox(
        label="Query",
        lines=1,
        max_lines=1,
        interactive=True,
    )

    query.submit(fn=run_query, inputs=[query, file_dataset], outputs=[file_dataset])


if __name__ == "__main__":
    demo.launch(enable_queue=False)

It's very over-simplified here for demonstration purposes, but the idea is to run a query over a set of files and update the results.

ankrgyl avatar Sep 29 '22 17:09 ankrgyl

@freddyaboulton ok if I look into this issue?

abidlabs avatar Jul 31 '23 12:07 abidlabs

Hi @ankrgyl sorry for the very late response, but coming back to this issue, this doesn't look like a gradio issue, but rather the way that the dataframe was being attempted to be updated. Following @pngwn's suggestion, you can actually just return the updated dataframe with the new headers and it will work.

I've updated the code below to fix the run_query() method accordingly:

import gradio as gr

initial_table = [
    ["![HF](https://huggingface.co/front/assets/huggingface_logo-noborder.svg)"],
    [
        "![Impira](https://assets-global.website-files.com/5e3898dff507782a6580d710/605900c97eb21442df5b7f28_Logo_lock_up_150x63-website.gif)"
    ],
]


def run_query(query, data):
    for index, row in data.iterrows():
        data.at[index, 'foo'] = "1"
    return data


with gr.Blocks() as demo:
    file_dataset = gr.Dataframe(
        value=initial_table,
        datatype=["markdown", "markdown"],
        headers=["file"],
        interactive=False,
    )

    query = gr.Textbox(
        label="Query",
        lines=1,
        max_lines=1,
        interactive=True,
    )

    query.submit(fn=run_query, inputs=[query, file_dataset], outputs=[file_dataset])


if __name__ == "__main__":
    demo.launch()

abidlabs avatar Jul 31 '23 14:07 abidlabs