Integration Ideas
Here are some ways to integrate the streamlit_secure_context component into your own Streamlit applications:
- Data Annotation: Embed the component in a labeling UI to preview model inferences on user-uploaded data before finalizing annotations.
- Interactive Dashboards: Offload client-side inference to reduce server load, enabling live model predictions in real-time dashboards.
- Privacy-First Forms: Incorporate secure inference in forms that process sensitive inputs (e.g., images, documents) entirely in the browser.
- Model Comparison: Render multiple iframes side-by-side to compare outputs of different models or versions without server-side conflict.
- Edge Deployments: Package your app as a Progressive Web App (PWA) and run models on-device for offline or low-latency scenarios.
- Custom Workflows: Extend the Web Worker to support ONNX, TFLite, or other web-compatible runtimes for custom inference pipelines.
Use these ideas to build richer, more performant, and privacy-conscious Streamlit applications with client-side ML.
streamlit-secure-context
This repository provides a secure machine learning inference component for Streamlit, leveraging modern browser security features (HTTPS enforcement, Cross-Origin Isolation, and CSP) and a worker-based inference pipeline inside a sandboxed iframe.
Table of Contents
- Prerequisites
- Installation
- Building the Frontend
- Installing the Component
- Usage Example
- Directory Structure
- Code Breakdown
- Python Wrapper (
streamlit_secure_context/__init__.py) - Scripts
- Next Steps
- Changelog
Prerequisites
- Node.js & npm
- Python 3.7+
- Streamlit 0.63+
- (Multipage) file watching disabled by default via
.streamlit/config.toml
- (Multipage) file watching disabled by default via
Installation
git clone <repo_url>
cd streamlit-secure-context
scripts/bootstrap.sh # Build frontend and install the component
Building the Frontend
cd frontend
npm install
npm run build
cd ..
Installing the Component
pip install .
Usage Example
import streamlit as st
from streamlit_secure_context import streamlit_secure_context
# Basic usage with optional timeout
result = streamlit_secure_context(
model_path="https://storage.googleapis.com/tfjs-models/tfjs/iris_v1/model.json",
security_config={
"coop": "same-origin",
"coep": "require-corp",
"csp": {
"default-src": ["'self'"],
"script-src": ["'self'", "'wasm-unsafe-eval'"],
"worker-src": ["'self'", "blob:"],
},
"sandbox": ["allow-scripts", "allow-same-origin"],
"requireHTTPS": True,
},
inference_params={"input": [[5.1, 3.5, 1.4, 0.2]], "shape": [1, 4]},
key="example1",
height=600, # optional: component height in px
width=800, # optional: component width in px
timeout=30, # optional: seconds to wait for component initialization
)
st.write("Inference result:", result)
Testing
Unit tests are provided for the Python wrapper. To run them:
pip install pytest
pytest
Directory Structure
streamlit-secure-context/
├── frontend/ # React code & build config
│ ├── public/ # Static assets for iframe & worker
│ └── src/ # React component source (TypeScript)
├── scripts/ # Helper scripts
│ └── bootstrap.sh # Build & install automation
├── streamlit_secure_context/ # Python wrapper package
│ └── __init__.py
├── setup.py # Package setup
└── README.md # This file
Code Breakdown
Python Wrapper (streamlit_secure_context/__init__.py)
Declares the Streamlit component and exposes streamlit_secure_context() for use in Python apps. Switches between local build and CDN modes based on _RELEASE flag.
React Frontend (frontend/src)
Defines StreamlitSecureContext:
- Configures CSP via a dynamic
<meta>tag - Enforces COOP/COEP and verifies cross-origin isolation
- Creates a sandboxed iframe to host the inference logic
- Communicates with the iframe via
window.postMessage
Iframe Loader (frontend/public/model_iframe.html)
Loads inside an isolated iframe with COOP/COEP headers. Parses URL parameters for modelPath, instantiates a Web Worker (worker.js), and relays messages between the parent and the worker.
Web Worker (frontend/public/worker.js)
Placeholder for inference logic. Responds to INIT (model loading) and INFER (dummy result) messages. Replace with real ML model loading and inference code.
Scripts
./scripts/bootstrap.sh
Automates building the frontend and installing the Python package.
Next Steps
- Customize CSP and sandbox flags for your deployment.
- Integrate your actual ML model (ONNX/TFLite/TFJS) as shown in the worker guides.
- Consider CI/CD automation to publish releases automatically.
Happy building! 🎉
Secure Deployment
- HTTPS everywhere: Configure your Streamlit server to use TLS certificates (see docs for
server.sslCertandserver.keyoptions). - Host all assets internally: The frontend is configured to bundle TFJS, ONNX Runtime Web, and TFLite scripts locally. Run
npm installinfrontend/and let thepostinstallscript copy these assets intofrontend/public. - Client-only PHI processing: Use in-browser inputs within the secure component (e.g.,
<input type="file">) so that raw PHI never leaves the user’s browser. - Device security: Ensure end-user devices have disk encryption, updated browsers, and adhere to your organizational security policies.
Demo
After installation and build (see above), run one of the Iris inference demos:
# Simple, one-click inference on hard-coded measurements
streamlit run examples/pages/simple_iris_inference.py
# Interactive inference with feature sliders
streamlit run examples/pages/interactive_iris_inference.py
Open http://localhost:8501 in your browser and click Run Inference to execute the model entirely in a sandboxed iframe + Web Worker.
This demo demonstrates secure, client-side TFJS inference of the Iris dataset:
- Click Run Inference to execute the model entirely in-browser (sandboxed iframe + Web Worker).
- View the returned 3-vector of species probabilities via
st.write().
Capturing Screenshots & Videos
You can capture screenshots and videos of each page individually using Playwright:
# Install Playwright & browser
pip install playwright
playwright install chromium
# Capture Image Processing demo
python3 scripts/capture_demo_screenshots.py \
examples/pages/image_demo.py --port 8501 \
--output examples/screenshots/image_demo.png \
--video-output examples/videos/image_demo.webm
# Capture Interactive Iris demo
python3 scripts/capture_demo_screenshots.py \
examples/pages/interactive_demo.py --port 8502 \
--output examples/screenshots/iris_interactive.png \
--video-output examples/videos/iris_interactive.webm
# Capture Simple Iris demo
python3 scripts/capture_demo_screenshots.py \
examples/pages/simple_demo.py --port 8503 \
--output examples/screenshots/iris_simple.png \
--video-output examples/videos/iris_simple.webm
Screenshots will be saved under examples/screenshots/, and recordings under examples/videos/.
How It Works
When you run the demo with streamlit run examples/app.py, here's what happens:
1. Streamlit one-liner
Your Python code invokes streamlit_secure_context(...), which loads the low-level component.
2. Bootstrapping a sandboxed iframe
A dynamic <meta> tag injects your CSP rules.
COOP (same-origin) and COEP (require-corp) headers enforce cross-origin isolation.
The iframe uses sandbox="allow-scripts allow-same-origin" to tightly control capabilities.
3. Spawning a Web Worker
Inside the iframe (model_iframe.html), the component creates a Worker.
The parent frame postMessage({ type: 'INIT', modelPath }) to initialize the model loader.
4. Model loading & inference off-thread
The Worker loads one of:
- TFJS GraphModel via
tf.loadGraphModel(modelPath) - TFLite via
@tensorflow/tfjs-tflite - ONNX Runtime Web via
onnxruntime-web
After the Worker signalsINIT_DONE, the component sends{ type: 'INFER', params }.
The Worker runs inference (predictorexecuteAsync) andpostMessage({ type: 'RESULT', result }).
5. Round-trip back to Python
The React component receives the RESULT message.
It calls Streamlit.setComponentValue(result), returning the tensor data to Python.
Your Streamlit app simply does st.write("Inference result:", result) to display it.
Tips:
- Open DevTools → Application → Frames → <iframe> to confirm sandbox/isolation.
- Add
console.loginworker.jsormodel_iframe.htmlto debug message passing. - Swap in a real model path and update
inference_params(add ashapekey) for genuine ML output.
Changelog
See CHANGELOG.md for detailed release notes.
Proof of Initialization Scripts
Two helper scripts under verify when the component is ready:
- proof_init.py: Blocks on with a timeout, printing elapsed time and result.
- proof_playwright.py: Uses Playwright to launch the demo, click "Run Inference", logs console/postMessage data, and confirms the subheader.
Usage:
Proof of Initialization Scripts
We provide two helper scripts under scripts/ to automate verifying component load:
scripts/proof_init.py: Blocks until the component returns or times out, printing elapsed time and result.scripts/proof_playwright.py: Uses Playwright to launch the demo, click Run Inference, logs console/postMessage data, and confirms the 'Result' subheader appears.
Usage:
python scripts/proof_init.py
python scripts/proof_playwright.py
For the Playwright script, ensure you have:
pip install playwright
playwright install chromium
Metadata
Release files for streamlit-secure-context 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| streamlit_secure_context-0.1.6.tar.gz | 10.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| streamlit_secure_context-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.3 kB
Release files / streamlit_secure_context-0.1.6.tar.gz
| Download URL | streamlit_secure_context-0.1.6.tar.gz |
|---|---|
| Size | 10.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5511f84ae9ae8a05f90252f6d06c97f7375252b72d12572dccfbdc04f766e32f
|
|
BLAKE2b-256 checksum How to use checksums |
2955afab1e10def4e7ff666fff1d13a618e9a2c676a24093fff0b0bbbc2af85d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.0
|
Release files / streamlit_secure_context-0.1.6-py3-none-any.whl
| Download URL | streamlit_secure_context-0.1.6-py3-none-any.whl |
|---|---|
| Size | 8.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ae8dcc109a342f7004b8d2bf09a7d98f9ee054990b92f5a633271056387105b9
|
|
BLAKE2b-256 checksum How to use checksums |
996b335f604804f25fc1f13bdeafd4a5560e74386755223dd10f0061f4256c29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.0
|
Security for streamlit-secure-context 0.1.6
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.