Search code examples
pythongradio

Gradio error: TypeError: gradio.data_classes.FileData() argument after ** must be a mapping, not list


I was trying to build my first interface in Gradio, when I got this error: "Gradio error: TypeError: gradio.data_classes.FileData() argument after ** must be a mapping, not list" (Full error is below the code block).

import gradio as gr
from time import sleep
import pandas as pd
import random

css = """
.custom-file-input {
    height: 50px;
}
"""

with gr.Blocks(css=css) as ui:
    gr.Markdown(value='#### File for analysis:')
    
    with gr.Row():
        file_input = gr.File(label="Excel or CSV file", elem_classes="custom-file-input", file_count=1)
        analyze_button = gr.Button("Analyze", scale=0)
    
    gr.Markdown(value='### Progress:')
    progress_output = gr.Markdown()
    
    status_text = gr.Textbox(interactive=False, show_label=False, visible=True)
    
    result_file = gr.File(label="Result", interactive=False)
    
    @analyze_button.click(inputs=file_input)
    def process_file(file):
    
        # Simulate file processing and progress updates
        progress = gr.Progress()
        progress(0, desc='0%')
        
        df = pd.read_excel(file.name)
        n_lines = df.shape[0]
        
        for i in range(n_lines):
            # sleep(0.01)  # Simulate some processing time
            df.iloc[i]['Target'] = random.choice(['MOROCCO', 'PRODUCT SKI', 'FINANCE', 'DOMESTIC'])
            progress((i + 1) / n_lines, desc=f'{int((i + 1) / n_lines * 100)}%')

        progress(1, desc='100%')
        
        output_file = "processed_file.xlsx"
        
        df.to_excel(output_file, index=False)
        

ui.launch()

I don't know what to try hoenestly, because it's a new library for me. I tried building a simple gradio interface that reads an excel file and prints out what's inside and it works flawlessly. So, I am guessing it has something to do with handling of output_file probably. Maybe not.

To reproduce: Put any excel file with a few lines of text in the gradio interface and press "Analyze" button to the right of it.

Ful error

Traceback (most recent call last):
  File "C:\Users\abaxt\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\gradio\queueing.py", line 532, in process_events
    response = await route_utils.call_process_api(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\abaxt\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\gradio\route_utils.py", line 276, in call_process_api
    output = await app.get_blocks().process_api(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\abaxt\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\gradio\blocks.py", line 1924, in process_api
    inputs = await self.preprocess_data(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\abaxt\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\gradio\blocks.py", line 1653, in preprocess_data
    inputs_cached = block.data_model(**inputs_cached)  # type: ignore
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: gradio.data_classes.FileData() argument after ** must be a mapping, not list

Solution

  • All problem is file_count=1

    Documentation for File shows allowed values:

    • file_count="single" (it is default value)
    • file_count="multiple"
    • file_count="directory"

    So you need

    file_input = gr.File(label="Excel or CSV file", elem_classes="custom-file-input", file_count="single")
    

    or you can even skip file_count="single" because it is default value

    file_input = gr.File(label="Excel or CSV file", elem_classes="custom-file-input")
    

    That's all.


    BTW:

    Later you need some small changes.

    In function you needs outputs to show progressbar:

    @analyze_button.click(inputs=file_input, outputs=progress_output)
    

    If you want to load csv then you have to run read_csv

    if file.name.endswith('csv'):
        df = pd.read_csv(file.name)
    else:
        df = pd.read_excel(file.name)