# How to access Gradio components created dynamically in a global function

**URL:** <https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234>\
**Category:** Beginners\
**Created:** [January 31, 2025, 2:57am UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234 "2025-01-31T02:57:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![LearnToGrow](https://avatars.discourse-cdn.com/v4/letter/l/5fc32e/32.png) [@LearnToGrow](https://discuss.huggingface.co/u/LearnToGrow)\
**Post date:** [January 31, 2025, 2:57am UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234/1 "2025-01-31T02:57:09Z")

</div>

My goal:

1. drop a list of files.
2. Read files and extract columns.
3. Dynamically generate dropdown componenets so the user can select the source and target columns.
4. I need to return (globally) all the selections, so I can use them with process\_files() function.  
I think (3) it should be solved using `gr.State([])` but I am not sure how to update it.  
here is my code:

## Function to process files

```auto
import gradio as gr
import pandas as pd

def process_files(files, selections):
    results = []

    for file, selection in zip(files, selections):
        file_name = file.name
        source_col, target_col, source_lang, target_lang = selection
        try:
            if file_name.endswith(".csv"):
                df = pd.read_csv(file.name)
            elif file_name.endswith(".xlsx"):
                df = pd.read_excel(file.name, engine="openpyxl")
            else:
                continue # Skip unsupported files

            # Extract selected columns
            extracted_data = df[[source_col, target_col]]

            results.append(
                f"✅ Processed {file_name} ({source_lang} → {target_lang})")
        except Exception as e:
            results.append(f"Error processing {file_name}: {str(e)}")

    return "\n".join(results)

```

## Gradio Interface

```auto
with gr.Blocks() as demo:
    gr.Markdown("## Upload Multiple Files and Select Columns")

    file_input = gr.File(file_types=[
                         ".csv", ".xlsx"], label="Drop your files here", interactive=True, file_count="multiple")

    all_selections = gr.State([])

    @gr.render(inputs=[file_input], triggers=[file_input.change])
    def generate_column_selectors(files):
        if not files:
            return "## No Files Uploaded", [] # Reset selections

        with gr.Column():
            for file in files:
                try:
                    if file.name.endswith(".csv"):
                        df = pd.read_csv(file.name)
                    elif file.name.endswith(".xlsx"):
                        df = pd.read_excel(file.name, engine="openpyxl")
                    else:
                        continue 

                    with gr.Row():
                        gr.Markdown(f" **{file.name}**") # Display filename
                        source_col = gr.Dropdown(
                            df.columns.tolist(), label="Source Column", interactive=True)
                        target_col = gr.Dropdown(
                            df.columns.tolist(), label="Target Column", interactive=True)
                        source_lang = gr.Textbox(
                            label="Source Language", placeholder="e.g., English", interactive=True)
                        target_lang = gr.Textbox(
                            label="Target Language", placeholder="e.g., French", interactive=True)

                    all_selections.append(
                        (source_col, target_col, source_lang, target_lang)) # this does not work.

                except Exception as e:
                    gr.Markdown(f"Error processing {file.name}: {str(e)}")
    submit_button = gr.Button("Submit & Process", interactive=True)
    output_text = gr.Markdown()

    submit_button.click(process_files, inputs=[
                        file_input, all_selections], outputs=[output_text])

demo.launch()

```

---

<div class="post-metadata">

**Author:** ![Alanturner2](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/alanturner2/32/37542_2.png) [@Alanturner2](https://discuss.huggingface.co/u/Alanturner2)\
**Post date:** [January 31, 2025, 7:31am UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234/2 "2025-01-31T07:31:41Z")

</div>

```auto
import gradio as gr
import pandas as pd

def process_files(files, selections):
    results = []

    for file, selection in zip(files, selections):
        file_name = file.name
        source_col, target_col, source_lang, target_lang = selection
        try:
            if file_name.endswith(".csv"):
                df = pd.read_csv(file.name)
            elif file_name.endswith(".xlsx"):
                df = pd.read_excel(file.name, engine="openpyxl")
            else:
                continue # Skip unsupported files

            # Extract selected columns
            extracted_data = df[[source_col, target_col]]

            results.append(
                f"✅ Processed {file_name} ({source_lang} → {target_lang})")
        except Exception as e:
            results.append(f"Error processing {file_name}: {str(e)}")

    return "\n".join(results)

with gr.Blocks() as demo:
    gr.Markdown("## Upload Multiple Files and Select Columns")

    file_input = gr.File(file_types=[".csv", ".xlsx"], label="Drop your files here", interactive=True, file_count="multiple")

    all_selections = gr.State([])

    @gr.render(inputs=[file_input], triggers=[file_input.change])
    def generate_column_selectors(files):
        if not files:
            return "## No Files Uploaded", [] # Reset selections

        selections = []
        with gr.Column():
            for file in files:
                try:
                    if file.name.endswith(".csv"):
                        df = pd.read_csv(file.name)
                    elif file.name.endswith(".xlsx"):
                        df = pd.read_excel(file.name, engine="openpyxl")
                    else:
                        continue 

                    with gr.Row():
                        gr.Markdown(f" **{file.name}**") # Display filename
                        source_col = gr.Dropdown(df.columns.tolist(), label="Source Column", interactive=True)
                        target_col = gr.Dropdown(df.columns.tolist(), label="Target Column", interactive=True)
                        source_lang = gr.Textbox(label="Source Language", placeholder="e.g., English", interactive=True)
                        target_lang = gr.Textbox(label="Target Language", placeholder="e.g., French", interactive=True)

                    selections.append((source_col, target_col, source_lang, target_lang))

                except Exception as e:
                    gr.Markdown(f"Error processing {file.name}: {str(e)}")

        # Update the global state with the new selections
        all_selections.value = selections

    submit_button = gr.Button("Submit & Process", interactive=True)
    output_text = gr.Markdown()

    submit_button.click(process_files, inputs=[file_input, all_selections], outputs=[output_text])

demo.launch()

```

---

<div class="post-metadata">

**Author:** ![LearnToGrow](https://avatars.discourse-cdn.com/v4/letter/l/5fc32e/32.png) [@LearnToGrow](https://discuss.huggingface.co/u/LearnToGrow)\
**Post date:** [January 31, 2025, 2:31pm UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234/3 "2025-01-31T14:31:22Z")

</div>

@Alanturner2 Did you test it. It does not work. ChatGPT proposes this solution but it is not workable. It looks like that the elements in the gr.state are not pickable!!

File “/usr/lib/python3.10/copy.py”, line 231, in \_deepcopy\_dict  
y[deepcopy(key, memo)] = deepcopy(value, memo)  
File “/usr/lib/python3.10/copy.py”, line 161, in deepcopy  
rv = reductor(4)  
TypeError: cannot pickle ‘\_thread.lock’ object

---

<div class="post-metadata">

**Author:** ![John6666](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/john6666/32/27664_2.png) [@John6666](https://discuss.huggingface.co/u/John6666)\
**Post date:** [January 31, 2025, 4:29pm UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234/4 "2025-01-31T16:29:37Z")

</div>

like this? It’s not perfect yet.

```py
        with gr.Column():
            for file in files:
                try:
                    if file.name.endswith(".csv"):
                        df = pd.read_csv(file.name)
                    elif file.name.endswith(".xlsx"):
                        df = pd.read_excel(file.name, engine="openpyxl")
                    else:
                        continue 

                    with gr.Row():
                        gr.Markdown(f" **{file.name}**") # Display filename
                        source_col = gr.Dropdown(
                            df.columns.tolist(), label="Source Column", interactive=True)
                        target_col = gr.Dropdown(
                            df.columns.tolist(), label="Target Column", interactive=True)
                        source_lang = gr.Textbox(
                            label="Source Language", placeholder="e.g., English", interactive=True)
                        target_lang = gr.Textbox(
                            label="Target Language", placeholder="e.g., French", interactive=True)
                        
                    def append_sel(source_col, target_col, source_lang, target_lang, selections):
                        selections.append((source_col, target_col, source_lang, target_lang))
                        return selections

                    gr.on(triggers=[source_col.change, target_col.change, source_lang.change, target_lang.change],
                          fn=append_sel, inputs=[source_col, target_col, source_lang, target_lang, all_selections], outputs=[all_selections])

```

---

<div class="post-metadata">

**Author:** ![LearnToGrow](https://avatars.discourse-cdn.com/v4/letter/l/5fc32e/32.png) [@LearnToGrow](https://discuss.huggingface.co/u/LearnToGrow)\
**Post date:** [January 31, 2025, 9:23pm UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234/5 "2025-01-31T21:23:51Z")

</div>

thanks @John6666. it still not perfect as gr.on() is trigeered on the first change of any element. if I insert just one Character in source\_lang, it will trigger once and done.

---

<div class="post-metadata">

**Author:** ![LearnToGrow](https://avatars.discourse-cdn.com/v4/letter/l/5fc32e/32.png) [@LearnToGrow](https://discuss.huggingface.co/u/LearnToGrow)\
**Post date:** [February 1, 2025, 12:25am UTC](https://discuss.huggingface.co/t/how-to-access-gradio-components-created-dynamically-in-a-global-function/138234/6 "2025-02-01T00:25:43Z")

</div>

Finally! It is working! I still not fully understand the utility of gr.State() if it does not work in such scenario.

```auto
import gradio as gr
import pandas as pd

with gr.Blocks() as demo:
    gr.Markdown("## Upload Multiple Files and Select Columns")

    file_input = gr.File(file_types=[
                         ".csv", ".xlsx"], label="Drop your files here", interactive=True, file_count="multiple")

    @gr.render(inputs=[file_input], triggers=[file_input.change])
    def generate_column_selectors(files):
        selections = []
        with gr.Column():
            for file in files:
                try:
                    if file.name.endswith(".csv"):
                        df = pd.read_csv(file.name)
                    elif file.name.endswith(".xlsx"):
                        df = pd.read_excel(file.name, engine="openpyxl")
                    else:
                        continue

                    with gr.Row():
                        gr.Markdown(f" **{file.name}**")
                        source_col = gr.Dropdown(
                            df.columns.tolist(), label="Source Column", interactive=True)
                        target_col = gr.Dropdown(
                            df.columns.tolist(), label="Target Column", interactive=True)
                        source_lang = gr.Textbox(
                            label="Source Language", placeholder="e.g., English", interactive=True)
                        target_lang = gr.Textbox(
                            label="Target Language", placeholder="e.g., French", interactive=True)

                    selections.extend(
                        [source_col, target_col, source_lang, target_lang])

                except Exception as e:
                    gr.Markdown(f"Error processing {file.name}: {str(e)}")

            def process_files(*args):
                results = []
                args = [tuple(args[i:i + 4]) for i in range(0, len(args), 4)]
                out = ""
                for file, (source_col, target_col, source_lang, target_lang) in zip(files, args):
                    out = file + "::" + source_col + "::" + target_col + \
                        "::" + source_lang + "::" + target_lang
                    results.append(out)

                return "\n".join(results)

            submit_button.click(
                fn=process_files, inputs=selections, outputs=output_text)

    submit_button = gr.Button("Submit & Process", interactive=True)
    output_text = gr.Markdown()

demo.launch()

```
