[feature] Add support for relative static file serving URLs in media elements#14317
[feature] Add support for relative static file serving URLs in media elements#14317lukasmasuch merged 11 commits intodevelopfrom
Conversation
Enables using /app/static/ URLs for st.image, st.audio, st.video, st.chat_message(avatar), st.set_page_config(page_icon), and st.logo. Co-Authored-By: Claude Opus 4.6 <[email protected]>
✅ 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!
|
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for using Streamlit’s static file serving endpoint (/app/static/...) as a relative URL input to multiple “media” surfaces, so users don’t need to construct absolute URLs or pass local file paths.
Changes:
- Backend: introduce
url_util.is_relative_static_url()and use it to bypass MediaFileManager for/app/static/...inputs inimage_to_url,marshall_audio, andmarshall_video. - Frontend: update
DefaultStreamlitEndpoints.buildMediaURL()to construct a full server URL when the input starts with/app/static/. - Tests: add Python unit coverage, a frontend unit test for URL building, and a new Playwright E2E test app + suite.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/streamlit/url_util.py | Adds a helper + constant for detecting /app/static/ relative URLs. |
| lib/streamlit/elements/lib/image_utils.py | Passes /app/static/... through unchanged in image_to_url(). |
| lib/streamlit/elements/media.py | Treats /app/static/... as URL input for audio/video marshalling. |
| frontend/connection/src/DefaultStreamlitEndpoints.ts | Builds absolute URLs for /app/static/... in buildMediaURL(). |
| lib/tests/streamlit/url_util_test.py | Unit tests for is_relative_static_url(). |
| lib/tests/streamlit/elements/image_test.py | Unit test ensuring image_to_url() passes static URLs through. |
| lib/tests/streamlit/elements/media_test.py | Unit tests for audio/video accepting static URLs without MFM. |
| frontend/connection/src/DefaultStreamlitEndpoints.test.ts | Adds coverage for /app/static/... URL building. |
| e2e_playwright/st_static_media_urls.py | New E2E app exercising static URLs across elements. |
| e2e_playwright/st_static_media_urls_test.py | New E2E tests validating rendered elements reference /app/static/.... |
Move relative static URL tests from separate files into the existing config_static_serving test suite for better organization. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Ensures that local files at /app/static/ paths are still loaded via MediaFileManager when static serving is disabled, matching the behavior of image_to_url(). Co-Authored-By: Claude Opus 4.6 <[email protected]>
Document support for static file serving URLs in the image, audio, and video parameter descriptions. Other commands (logo, chat_message) reference st.image for supported types. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Reduces browser loads from 10 to 5 by combining all media element static URL tests into one aggregated scenario test. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Clarify url_util.py constant comment about trailing slash difference - Handle /app/static/ URLs in static connection mode (staticConfigUrl) - Add test for static connection mode in DefaultStreamlitEndpoints - Use expect().to_have_attribute() instead of get_attribute + assert in E2E tests - Add st.set_page_config(page_icon) test with /app/static/ URL Co-Authored-By: Claude Opus 4.6 <[email protected]>
Clarify the static URL pattern in image, audio, and video docstrings. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Align naming with server.py's STATIC_SERVING_ENDPOINT constant. Co-Authored-By: Claude Opus 4.6 <[email protected]>
SummaryThis PR adds support for relative static file serving URLs ( Key changes:
Reviewer ConsensusAll three reviewers (gemini-3.1-pro, gpt-5.3-codex-high, opus-4.6-thinking) unanimously approved this PR. There were no critical or blocking issues identified by any reviewer. The reviewers were in strong agreement across all major evaluation dimensions. Code QualityConsensus: High quality, no issues. All three reviewers agreed the code is clean, well-structured, and follows existing codebase patterns.
Test CoverageConsensus: Thorough and comprehensive. All reviewers agreed that test coverage is strong across all layers.
Minor improvement suggestion (opus-4.6-thinking): The E2E test could benefit from an explicit negative assertion (e.g., verifying no Backwards CompatibilityConsensus: Fully backwards compatible. All reviewers confirmed no breaking changes:
Security & RiskConsensus: Low risk, no concerns. All reviewers agreed there are no significant security issues:
External Test RecommendationConsensus: Yes, external testing recommended. All three reviewers recommended external tests.
AccessibilityConsensus: No concerns. All reviewers agreed there are no accessibility implications. Changes are backend URL routing and frontend URL construction logic with no new UI elements or visual changes. RecommendationsAll recommendations below are non-blocking and for future consideration:
VerdictAPPROVED: All three reviewers unanimously approved. The implementation is clean, well-tested, and fully backwards compatible. No security, accessibility, or breaking-change concerns were identified. The feature follows existing codebase patterns and has comprehensive test coverage across Python unit tests, frontend unit tests, and E2E tests. This is a consolidated AI review by 📋 Review by `gemini-3.1-pro`SummaryThis PR introduces support for relative static URLs ( Code QualityThe code changes are clean, well-structured, and follow the established patterns in the codebase. The addition of Test CoverageThe changes are thoroughly tested:
Backwards CompatibilityThis is a purely additive feature and does not introduce any breaking changes. Existing behavior for absolute URLs, local file paths, and Security & RiskNo significant security concerns were identified. The backend static file serving is handled by Tornado's External test recommendation
AccessibilityN/A - No UI changes were made that affect accessibility. RecommendationsNone. The implementation is solid and ready to be merged. VerdictAPPROVED: The changes are well-implemented, thoroughly tested, and introduce a useful feature without regressions. This is an automated AI review by 📋 Review by `gpt-5.3-codex-high`SummaryThis PR adds support for relative static URLs ( Code QualityThe implementation is coherent and follows existing Streamlit patterns:
No blocking code-quality issues found. Test CoverageCoverage is strong and layered:
Given the scope, tests are adequate for merge. Backwards CompatibilityNo breaking API changes identified:
Security & RiskNo new high-risk security behavior identified in this diff.
Primary residual risk is regression in externally hosted/proxied/embedded deployments where URL/base-path behavior can differ from local runs. External test recommendation
AccessibilityNo accessibility regressions identified from the frontend code changes in this PR:
Recommendations
VerdictAPPROVED: The implementation is well-scoped, test coverage is comprehensive for local behavior, and no blocking compatibility or security issues were found. This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR adds support for relative static file serving URLs ( Key changes:
Code QualityThe code is clean, well-structured, and follows existing patterns in the codebase. Strengths:
Minor observations:
Test CoverageTest coverage is thorough and well-structured across all layers. Python unit tests:
Frontend unit tests:
E2E tests:
Potential improvement: The E2E test doesn't include a negative assertion (e.g., verifying no error alerts appear beyond the success message). However, the presence of the success message at the bottom of the script implicitly confirms no errors interrupted execution, which is a reasonable approach. Backwards CompatibilityThis change is fully backwards compatible:
Security & RiskSecurity assessment: Low risk.
External test recommendation
AccessibilityNo accessibility concerns. The changes are backend URL routing and frontend URL construction logic. No new UI elements, interactive controls, or visual changes are introduced. The media elements ( Recommendations
VerdictAPPROVED: Clean, well-tested feature addition that follows existing patterns and introduces no backwards compatibility or security concerns. The implementation is consistent across backend and frontend, with comprehensive test coverage at all levels. This is an automated AI review by |
Adds E2E coverage for static URL media elements (image, audio, video, avatar, logo) when the app is externally hosted or iframe-embedded. Co-Authored-By: Claude Opus 4.6 <[email protected]>
| it.each([ | ||
| ["/app/static/my_image.png", "my_image.png"], | ||
| ["/app/static/images/subdir/file.mp4", "file with subdirectories"], | ||
| ])( | ||
| "builds URL correctly for /app/static/ paths (%s)", | ||
| (inputPath, _description) => { |
There was a problem hiding this comment.
nit: It looks like the 2nd param in the it.each each setup _description is never used. Either use it in the test or remove it for brevity.
Address PR review nit: simplify it.each to use plain string values instead of tuples with unused description parameter. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Describe your changes
Adds support for relative static URLs (
/app/static/) in media elements, allowing users to reference files from Streamlit's static file serving endpoint using relative paths instead of requiring absolute URLs or local file paths.is_relative_static_url()helper tourl_util.pyfor detecting/app/static/pathsimage_to_url()to pass through relative static URLs unchangedmarshall_audio()andmarshall_video()to recognize relative static URLsbuildMediaURL()to construct proper URLs for/app/static/pathsSupported commands:
st.image,st.audio,st.video,st.chat_message(avatar),st.set_page_config(page_icon),st.logoGitHub Issue Link (if applicable)
Testing Plan
Test files:
lib/tests/streamlit/url_util_test.py— Testsis_relative_static_url()with valid/invalid inputslib/tests/streamlit/elements/image_test.py— Testsimage_to_url()with static URLslib/tests/streamlit/elements/media_test.py— Testsmarshall_audio/videowith static URLsfrontend/connection/src/DefaultStreamlitEndpoints.test.ts— TestsbuildMediaURL()with static pathse2e_playwright/config_static_serving_test.py— E2E tests for all supported media elementsAgent metrics