Exclude download_button data from the list of arguments for computing…
diff --git a/e2e/scripts/st_download_button.py b/e2e/scripts/st_download_button.py
index a37de2fa0e73..73bf2c9451d8 100644
--- a/e2e/scripts/st_download_button.py
+++ b/e2e/scripts/st_download_button.py
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from random import random
+
 import streamlit as st
 
 st.download_button(
@@ -56,3 +58,8 @@
     file_name="hello.txt",
     type="primary",
 )
+
+random_str = str(random())
+clicked = st.download_button(label="Download random text", data=random_str)
+
+st.write(f"value: {clicked}")
diff --git a/e2e/specs/st_download_button.spec.js b/e2e/specs/st_download_button.spec.js
index 3abde0ea1e85..dbc81bb887c3 100644
--- a/e2e/specs/st_download_button.spec.js
+++ b/e2e/specs/st_download_button.spec.js
@@ -15,7 +15,7 @@
  */
 
 const path = require("path");
-const NO_OF_BUTTONS = 6
+const NO_OF_BUTTONS = 7
 
 describe("st.download_button", () => {
   beforeEach(() => {
@@ -75,4 +75,14 @@ describe("st.download_button", () => {
       "primary-download-button"
     );
   });
+
+  it("sets value correctly when user clicks", () => {
+    cy.get(".stMarkdown").contains("value: False");
+
+    cy.get(".stDownloadButton button")
+      .last()
+      .click();
+
+    cy.get(".stMarkdown").contains("value: True");
+  });
 });
diff --git a/lib/streamlit/elements/widgets/button.py b/lib/streamlit/elements/widgets/button.py
index b78aff5459e6..1629a5b65242 100644
--- a/lib/streamlit/elements/widgets/button.py
+++ b/lib/streamlit/elements/widgets/button.py
@@ -430,7 +430,6 @@ def _download_button(
             "download_button",
             user_key=key,
             label=label,
-            data=str(data),
             file_name=file_name,
             mime=mime,
             key=key,
diff --git a/lib/tests/streamlit/runtime/state/widgets_test.py b/lib/tests/streamlit/runtime/state/widgets_test.py
index d70bfb705bbc..cb1f4f3378bc 100644
--- a/lib/tests/streamlit/runtime/state/widgets_test.py
+++ b/lib/tests/streamlit/runtime/state/widgets_test.py
@@ -398,6 +398,11 @@ def test_widget_id_computation_no_form_widgets(self, widget_func, module_name):
         del expected_sig["form_id"]
         if widget_func == st.button:
             expected_sig["is_form_submitter"] = ANY
+        # we exclude `data` for `st.download_button` here and not
+        # in `signature_to_expected_kwargs`, because `data` param is also used for
+        # `st.data_editor`.
+        if widget_func == st.download_button:
+            del expected_sig["data"]
 
         patched_compute_widget_id.assert_called_with(ANY, **expected_sig)
 

<!--
⚠️ BEFORE CONTRIBUTING PLEASE READ OUR CONTRIBUTING GUIDELINES!
https://github.com/streamlit/streamlit/wiki/Contributing
-->

## Describe your changes
Exclude download_button data from the list of arguments for computing widget id.
Since if `data` is different on each rerun (e.g. generated randomly), widget_ids doesn't match, and it leads to a missing "True" value when button clicked on frontend.

## GitHub Issue Link (if applicable)  #7308 

## Testing Plan

- Explanation of why no additional tests are needed
- Unit Tests (JS and/or Python)
- E2E Tests
    -  e2e test added for regression verification
- Any manual testing needed?

---

Closes: #7308

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
