gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
33.39k stars 2.52k forks source link

Dataframe "New column" generating error when submitting #753

Closed fabivencrim closed 2 years ago

fabivencrim commented 2 years ago

Describe the bug

Hi,

I tried using the "New column" feature to populate custom data in the Dataframe component, but it seems to be giving me an error. When adding a new column and submitting, I get the following error :

ValueError: 3 columns passed, passed data had 4 columns

I tested this feature in the Colab example in the documentation and Gradio also flags an error when submitting.

Reproduction

import gradio as gr

def filter_records(records, gender):
    return records[records["gender"] == gender]

iface = gr.Interface(
    filter_records,
    [
        gr.inputs.Dataframe(
            headers=["name", "age", "gender"],
            datatype=["str", "number", "str"],
            row_count=5,
        ),
        gr.inputs.Dropdown(["M", "F", "O"]),
    ],
    "dataframe",
    description="Enter gender as 'M', 'F', or 'O' for other.",
)

iface.test_launch()

iface.launch()

Screenshot

image

Logs

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/gradio/routes.py", line 232, in predict
    app.interface.process, raw_input
  File "/usr/local/lib/python3.7/dist-packages/starlette/concurrency.py", line 39, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
  File "/usr/local/lib/python3.7/dist-packages/anyio/to_thread.py", line 29, in run_sync
    limiter=limiter)
  File "/usr/local/lib/python3.7/dist-packages/anyio/_backends/_asyncio.py", line 818, in run_sync_in_worker_thread
    return await future
  File "/usr/local/lib/python3.7/dist-packages/anyio/_backends/_asyncio.py", line 754, in run
    result = context.run(func, *args)
  File "/usr/local/lib/python3.7/dist-packages/gradio/interface.py", line 561, in process
    for i, input_component in enumerate(self.input_components)
  File "/usr/local/lib/python3.7/dist-packages/gradio/interface.py", line 561, in <listcomp>
    for i, input_component in enumerate(self.input_components)
  File "/usr/local/lib/python3.7/dist-packages/gradio/inputs.py", line 1470, in preprocess
    return pd.DataFrame(x, columns=self.headers)
  File "/usr/local/lib/python3.7/dist-packages/pandas/core/frame.py", line 700, in __init__
    dtype,
  File "/usr/local/lib/python3.7/dist-packages/pandas/core/internals/construction.py", line 483, in nested_data_to_arrays
    arrays, columns = to_arrays(data, columns, dtype=dtype)
  File "/usr/local/lib/python3.7/dist-packages/pandas/core/internals/construction.py", line 807, in to_arrays
    content, columns = _finalize_columns_and_data(arr, columns, dtype)
  File "/usr/local/lib/python3.7/dist-packages/pandas/core/internals/construction.py", line 909, in _finalize_columns_and_data
    raise ValueError(err) from err
ValueError: 3 columns passed, passed data had 4 columns

System Info

Gradio version : 2.8.1
OS : macOS Monterey 12.2.1
Browser : Google Chrome Version 98.0.4758.109

Severity

blocker

abidlabs commented 2 years ago

Thanks for creating the issue @fabivencrim. The reason this issue was happening was that headers and data types were provided, which meant that new columns could not be processed correctly. There was previously no mechanism to prevent users from creating new columns in the front end, but as that is not desired in this case, we have added a mechanism to do so in #1186

You can add the following parameter to do this: col_count=(3, "fixed") and the demo code has been updated:

import gradio as gr

def filter_records(records, gender):
    return records[records["gender"] == gender]

demo = gr.Interface(
    filter_records,
    [
        gr.Dataframe(
            headers=["name", "age", "gender"],
            datatype=["str", "number", "str"],
            row_count=5,
            col_count=(3, "fixed")
        ),
        gr.Dropdown(["M", "F", "O"]),
    ],
    "dataframe",
    description="Enter gender as 'M', 'F', or 'O' for other.",
)

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