Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@sfc-gh-lwilby
Copy link
Collaborator

Describe your changes

While working on width for st.image I discovered that since we only cache the inner element proto (e.g. Image.proto, Code.proto), when an element with width/height added in the new style on Element.proto is cached it does not replay with the correct width/height.

This PR caches the layout_config as well so that it can be replayed as well.

GitHub Issue Link (if applicable)

Testing Plan

  • Unit Tests (JS and/or Python) ✅
  • E2E Tests ✅

Contribution License Agreement

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

@github-actions
Copy link
Contributor

github-actions bot commented Aug 12, 2025

✅ PR preview is ready!

Name Link
📦 Wheel file https://core-previews.s3-us-west-2.amazonaws.com/pr-12183/streamlit-1.48.0-py3-none-any.whl
🕹️ Preview app pr-12183.streamlit.app (☁️ Deploy here if not accessible)

@sfc-gh-lwilby sfc-gh-lwilby added security-assessment-completed Security assessment has been completed for PR change:bugfix PR contains bug fix implementation impact:users PR changes affect end users labels Aug 12, 2025
@snyk-io
Copy link
Contributor

snyk-io bot commented Aug 12, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

@sfc-gh-lwilby sfc-gh-lwilby marked this pull request as ready for review August 12, 2025 17:34

@st.cache_data
def cache_code_with_layout():
st.code(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I debated covering more elements (especially since this is how this gap slipped by originally), but I think it would be excessive. I chose st.code because it has height and width.

expect(image_element).to_have_attribute("src", image_src or "")


def test_cached_code_replay(app: Page, assert_snapshot: ImageCompareFunction):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this with st.code because 1) It has both height and width 2) It doesn't have width/height on it's inner proto like st.video and st.audio.

@sfc-gh-lwilby sfc-gh-lwilby requested a review from Copilot August 12, 2025 18:32
Copy link
Contributor

Copilot AI left a 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 fixes a caching issue where layout configurations (width/height) for Streamlit elements were not being preserved during cache replay. Previously, only the inner element proto was cached, causing cached elements to lose their layout styling when replayed.

Key changes:

  • Enhanced the caching system to store and replay layout configuration data alongside element protobuf data
  • Updated cache replay functionality to apply layout configurations during element reconstruction
  • Added comprehensive test coverage for both @st.cache_data and @st.cache_resource decorators

Reviewed Changes

Copilot reviewed 7 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
cached_message_replay.py Added layout_config field to ElementMsgData and updated replay logic to apply layout configurations
__init__.py Updated save_element_message function signature to accept layout_config parameter
delta_generator.py Modified _enqueue method to pass layout_config to caching system
cache_data_api_test.py Added unit tests for layout config preservation during cache replay for @st.cache_data
cache_resource_api_test.py Added unit tests for layout config preservation during cache replay for @st.cache_resource
st_cache_data.py Added cached code element with width/height for e2e testing
st_cache_data_test.py Added e2e test verifying visual consistency of cached elements with layout configs

actual_height = element.height_config.pixel_height
expected_msg = f"Expected {description.lower()} height {expected_height}, got {actual_height}"
assert actual_height == expected_height, expected_msg

Copy link

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _assert_layout_config helper method is duplicated between cache_data_api_test.py and cache_resource_api_test.py with identical implementation. Consider extracting this to a shared test utility module to avoid code duplication.

Suggested change

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

@sfc-gh-lwilby sfc-gh-lwilby Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might do this. I didn't already because we don't already have a test_utils file for this area and I wasn't sure it completely necessary for just these two tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think we could refactor it to shared parameterized replay tests. But also fine to leave it as is.

Comment on lines +104 to +115
code_element = app.get_by_test_id("stCode").first
expect(code_element).to_be_visible()

# Test dimensions with snapshots since the width/height is set on the element container.
assert_snapshot(code_element, name="st_cache_data-st_code_before_caching")

click_checkbox(app, "Show code")
expect(code_element).not_to_be_attached()

click_checkbox(app, "Show code")
expect(code_element).to_be_visible()
assert_snapshot(code_element, name="st_cache_data-st_code_after_caching")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since this test is just about ensuring that width & height are correct, I think we can just do a to_have_css("width", expected_width) here instead of snapshot testing (which is more expansive and easier to miss when updating lots of snapshots).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stCode element doesn't have the CSS styles, it's on the Element Container. Maybe adding some test utility to get the associated element container is a good idea to reduce some snapshot testing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option would be to get the bounding box, e.g.:

def assert_vega_chart_height(vega_chart: Locator, expected_height: int):
vega_graphics_doc = vega_chart.locator("[role='graphics-document']")
bbox = vega_graphics_doc.bounding_box()
assert bbox is not None
assert round(bbox["height"]) == expected_height
def assert_vega_chart_width(vega_chart: Locator, expected_width: int):

Copy link
Collaborator

@lukasmasuch lukasmasuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@sfc-gh-lwilby sfc-gh-lwilby merged commit 506bd8b into develop Aug 13, 2025
43 of 45 checks passed
@sfc-gh-lwilby sfc-gh-lwilby deleted the fix/layout-config-cache-replay branch August 13, 2025 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:bugfix PR contains bug fix implementation impact:users PR changes affect end users security-assessment-completed Security assessment has been completed for PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants