-
Notifications
You must be signed in to change notification settings - Fork 4k
[WIP] Allow dynamic changes to st.data_editor with num_rows="fixed" when key is provided (phase 1)
#13672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Implement Phase 1: Support cell edit persistence in num_rows="fixed" mode when a key is provided. The schema hash approach keeps widget ID stable when only data values change (not structure), preserving editing state across reruns even with computed columns. Changes: - Add _compute_schema_hash() to capture structural identity - Use schema_hash as main widget identity component when key provided - Add E2E tests for session state feedback loop scenarios Fixes #7749 Co-Authored-By: Claude <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
✅ PR preview is ready!
|
st.data_editor with num_rows="fixed" when key is provided (phase 1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements Phase 1 of the dynamic data editor feature to fix issue #7749, where cell edits in st.data_editor would reset when underlying data was programmatically modified (e.g., when computing columns in a session state feedback loop). The solution uses a schema hash as the primary widget identity component when a user provides a key, keeping the widget ID stable when only cell values change rather than the dataframe structure.
Changes:
- Introduced schema-based widget identity for
st.data_editorwhen a key is provided - Added E2E tests verifying edit persistence in session state feedback loop scenarios
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
lib/streamlit/elements/widgets/data_editor.py |
Adds _compute_schema_hash() function to compute dataframe structure hash and updates widget ID computation to use schema hash when key is provided |
e2e_playwright/st_data_editor_state_persistence.py |
Test app demonstrating the fix with both a session state feedback loop scenario and a baseline simple edit scenario |
e2e_playwright/st_data_editor_state_persistence_test.py |
E2E tests verifying that edits persist when data values change but structure remains stable |
| # Build schema components list | ||
| components: list[str] = [f"col:{col}" for col in df.columns] | ||
| components.extend(f"type:{field.name}:{field.type}" for field in arrow_schema) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The schema hash computation includes column names twice: once from df.columns (line 496) and again from arrow_schema fields (line 497), since each field in the arrow_schema has a name property. This duplication is redundant and could lead to unexpected behavior. Consider using only the arrow_schema to capture both column names and types in a single iteration, or clearly document why both are needed.
| # Build schema components list | |
| components: list[str] = [f"col:{col}" for col in df.columns] | |
| components.extend(f"type:{field.name}:{field.type}" for field in arrow_schema) | |
| # Build schema components list from the Arrow schema so that | |
| # each column's name and type are captured in a single pass. | |
| components: list[str] = [ | |
| f"col:{field.name}:type:{field.type}" for field in arrow_schema | |
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Consolidated the schema hash computation to use only the Arrow schema, capturing both column names and types in a single pass. This eliminates the redundancy.
Add schema_hash to expected kwargs in test_widget_id_computation_data_editor since it's now passed to compute_and_register_element_id. Co-Authored-By: Claude <noreply@anthropic.com>
- Gate key_as_main_identity={"schema_hash"} to only apply when
num_rows=="fixed", avoiding unintended behavior changes for
dynamic/add/delete modes where row count can change legitimately
- Explicitly set num_rows="fixed" in E2E tests to be resilient
against potential default value changes
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix schema hash computation to use only Arrow schema, avoiding redundant column name capture (suggestion from Copilot) - Add 8 unit tests for _compute_schema_hash function covering hash stability and change scenarios - Add negative assertion to E2E test verifying computed column is correctly updated (Out[0] = 25 when In[0] = 5) Co-Authored-By: Claude <noreply@anthropic.com>
📉 Frontend coverage change detectedThe frontend unit test (vitest) coverage has decreased by 0.0600%
💡 Consider adding more unit tests to maintain or improve coverage. |
Add dataHash parameter to useWidgetState hook to detect when the underlying data content changes. When dataHash changes, the editing state is reset to ensure users see the latest data values instead of stale edits. Co-Authored-By: Claude <noreply@anthropic.com>
st.data_editor with num_rows="fixed" when key is provided (phase 1)st.data_editor with num_rows="fixed" when key is provided (phase 1)
Describe your changes
Implements Phase 1 of the dynamic data editor feature to fix issue #7749 where cell edits would "disappear" when underlying data was modified programmatically (e.g., computing columns).
Core approach: When a user provides a
key, we now use a schema hash as the main widget identity component instead of the full data. This keeps the widget ID stable when only cell values change (not structure), allowing the editing state to persist across reruns.Changes:
_compute_schema_hash()to capture dataframe structure (columns, types, index type, row count) without data valueskey_as_main_identity={"schema_hash"}when key is providedTesting Plan
E2E Tests:
test_data_editor_preserves_edit_in_session_state_feedback_loop: Edit cell with computed column update, verify edit persiststest_data_editor_simple_edit_persists: Baseline test without computed columnManual Testing: The fix enables the pattern in issue #7749 where a data_editor with key used in session state feedback loop now preserves edits when computed columns are updated.