Skip to content

Conversation

@lukasmasuch
Copy link
Collaborator

@lukasmasuch lukasmasuch commented Jan 7, 2026

Describe your changes

Add a new experimental App class that provides an ASGI-compatible entry point for Streamlit apps. This enables custom HTTP routes, middleware configuration, lifecycle hooks, and integration with popular Python web frameworks, aligning Streamlit with the broader async web ecosystem. See the spec for more details: #13449

The App instance is exposed via from streamlit.starlette import App but will likely be moved into the st namespace once we move this out of experimental.

This PR also includes the discovery logic for detecting if the main script contains an App call -> which triggers a special asgi execution mode.

GitHub Issue Link (if applicable)

Testing Plan

  • Added unit 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.

@lukasmasuch
Copy link
Collaborator Author

@cursor review

@streamlit streamlit deleted a comment from github-actions bot Jan 9, 2026
@github-actions github-actions bot added the do-not-merge PR is blocked from merging label Jan 9, 2026
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no bugs!

@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

Summary

This PR introduces the experimental App class (streamlit.starlette.App), enabling Streamlit applications to run as standard ASGI apps. This allows for integration with uvicorn, custom middleware, and other ASGI frameworks like FastAPI. The PR also includes:

  • AST-based discovery logic in the CLI (discover_asgi_app) to automatically detect and run st.App instances.
  • A new starlette_routes module implementing Streamlit's core endpoints using Starlette.
  • Refactoring of bootstrap.py to support the ASGI execution mode.
  • Comprehensive unit tests and a basic E2E test.

Code Quality

The code quality is excellent.

  • Modularity: The new App class is well-isolated and properly interacts with the existing Runtime. The separation between the App definition, route handling, and server logic is clear.
  • Typing: Type hints are used consistently throughout the new files.
  • Readability: The code is well-documented with docstrings explaining the purpose of the new classes and functions.
  • Safety: The discover_asgi_app uses ast.parse instead of executing code, which is the correct and safe approach for static analysis.

Test Coverage

Test coverage is robust:

  • Unit Tests: lib/tests/streamlit/web/server/starlette/starlette_app_test.py covers the App lifecycle, configuration, route validation, and integration with the TestClient. lib/tests/streamlit/web/server/app_discovery_test.py covers the AST parsing logic thoroughly, including edge cases.
  • E2E Tests: e2e_playwright/asgi_app.py provides a smoke test ensuring the app runs without console errors in the browser.

Backwards Compatibility

The changes are backwards compatible:

  • The new functionality is experimental and opt-in (via st.App).
  • The standard streamlit run command continues to work as expected for existing scripts.
  • The discover_asgi_app mechanism falls back to the traditional execution mode if no App instance is found.

Security & Risk

  • XSRF & CORS: The new starlette_routes.py correctly implements XSRF protection and CORS header generation, mirroring the behavior of the Tornado implementation.
  • Path Traversal: The component routes use build_safe_abspath to prevent directory traversal attacks.
  • Input Validation: The App class validates user-provided routes to prevent conflicts with reserved Streamlit paths.

Recommendations

  1. File Upload Memory Usage: In lib/streamlit/web/server/starlette/starlette_routes.py, the _upload_put handler reads the entire file content into memory (await upload.read()). While this matches the MemoryUploadedFileManager backend, ensure this aligns with the intended memory usage profile for the ASGI mode, especially for large file uploads (up to server.maxUploadSize).
  2. Documentation: Since this is an experimental feature, ensure it is marked as such in the public documentation when released. The code docstrings already include appropriate warnings.

Verdict

APPROVED: The PR implements a significant new feature with high code quality, strong test coverage, and careful attention to existing patterns and security requirements.

@lukasmasuch lukasmasuch removed the do-not-merge PR is blocked from merging label Jan 9, 2026
@streamlit streamlit deleted a comment from github-actions bot Jan 9, 2026
@lukasmasuch lukasmasuch enabled auto-merge (squash) January 9, 2026 20:58
@lukasmasuch lukasmasuch disabled auto-merge January 9, 2026 21:09
@lukasmasuch lukasmasuch merged commit b1c05fc into develop Jan 9, 2026
43 checks passed
@lukasmasuch lukasmasuch deleted the feature/configurable-asgi-app branch January 9, 2026 21:39
@nicornk
Copy link

nicornk commented Jan 10, 2026

Nice work @lukasmasuch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:feature PR contains new feature or enhancement implementation impact:users PR changes affect end users security-assessment-completed Security assessment has been completed for PR starlette-tests If applied to PR, will run all e2e tests with the Starlette implementation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants