Snowflake-Labs/streamlit-page-analytics
Python
Captured source
source ↗Snowflake-Labs/streamlit-page-analytics
Description: Capture user interactions in your streamlit apps to logs
Language: Python
License: Apache-2.0
Stars: 3
Forks: 1
Open issues: 4
Created: 2025-08-25T22:08:31Z
Pushed: 2026-04-13T09:28:36Z
Default branch: main
Fork: no
Archived: no
README:
Streamlit Page Analytics
A Python library for building page analytics in Streamlit applications through logging.
The solution instruments all st. with a wrapper function which emits logs, these logs can then be processed to derive analytics information.
This solution is inspired from jrieke/streamlit-analytics idea.
Events are emitted as JSON objects (one object per log record) via Python’s logging API, using the configured logger and log level (default INFO).
Log format
Each line is a single JSON object produced from a UserEvent (or equivalent) after enrichment:
| Field | Meaning | |-------|---------| | session_id | From StreamlitPageAnalytics (constructor or set_session_id) | | user_id | From StreamlitPageAnalytics (constructor or set_user_id) | | page_name | Present when page tracking is active and set | | action | Event type (string); see table below | | widget | Present when the event targets a widget (id, type, label, values, etc.); omitted when empty | | extra | Additional payload (form field snapshots, notices, etc.); omitted when empty |
Empty or null values are typically omitted from the JSON (clean_values).
`action` values (see UserEventAction in code): start_tracking, form_instrumentation_notice, click, change, submit, other.
Installation
Use the releases to download assets:
Local
To run it locally, Download the wheel(.whl) file and install or install from git:
pip install \ git+https://github.com/Snowflake-Labs/streamlit-page-analytics@latest
Streamlit in Snowflake (SiS)
Download the streamlit_page_analytics-.zip file and copy it to a Snowflake Internal Stage for use in SiS and run the following command:
ALTER STREAMLIT SET
IMPORTS = ('@/');Usage
import streamlit as st
from streamlit_page_analytics import StreamlitPageAnalytics
with StreamlitPageAnalytics.track(
name="my-app", session_id=f"{session_id}", user_id=f"{user_id}"
):
st.title("My Awesome App")
st.button('my awesome button')or
import streamlit as st
from streamlit_page_analytics import StreamlitPageAnalytics
page_analytics = StreamlitPageAnalytics(
name="my-app", session_id=f"{session_id}", user_id=f"{user_id}"
)
page_analytics.start_tracking()
st.title("My Awesome App")
st.button('my awesome button')
page_analytics.stop_tracking()Page Tracking
Track page visits in multi-page Streamlit applications by passing a page_name to start_tracking(). A start_tracking event is logged only when the user navigates to a different page, avoiding duplicate logs on page reruns.
import streamlit as st
from streamlit_page_analytics import StreamlitPageAnalytics
page_analytics = StreamlitPageAnalytics(
name="my-app", session_id=f"{session_id}", user_id=f"{user_id}"
)
# Pass the current page name - logs only when page changes
page_analytics.start_tracking(page_name="Home")
st.title("Home Page")
st.button("Click me")
page_analytics.stop_tracking()When the user navigates between pages:
start_tracking(page_name="Home")- Logs (first visit)start_tracking(page_name="Home")- No log (same page, e.g., rerun)start_tracking(page_name="Settings")- Logs (different page)start_tracking(page_name="Home")- Logs (navigated back)
If page_name is not provided or is empty, no page tracking event is logged.
Forms (st.form)
Streamlit does not allow on_change / on_click on widgets inside a form except on st.form_submit_button. This library therefore does not attach per-widget analytics callbacks to inputs inside st.form(). Instead:
- One-time notice (`form_instrumentation_notice`) — The first time a tracked widget is created inside a form in a session, the library logs a single event through the same `log_event` path as every other analytics event, so `session_id`, `user_id`, and optional `page_name` match the rest of the stream. The human-readable explanation is in `extra.message`. There is usually no `widget` on this object after serialization (same as other events with no element).
- Submit (`submit`) — When the user presses `st.form_submit_button`, a `submit` event is logged. The submit button appears under `widget`. Registered field values at submit time are in top-level `extra`: `extra.form_id` and `extra.form_fields` (each entry: id, type, label, value). Masking options apply to text inputs and text areas in that snapshot the same way as elsewhere.
- If you pass your own
on_changeoron_clickon a widget inside a form, Streamlit may reject it or it conflicts with form rules; this package does not forward those developer callbacks for form widgets. Use callbacks onst.form_submit_buttonif you need custom logic on submit.
Masking Text Input Values
For privacy-sensitive applications, you can mask the values of text_input and text_area widgets in the logs by setting mask_text_input_values=True. When enabled, the actual input values will be replaced with "[REDACTED]" in the log output.
import streamlit as st
from streamlit_page_analytics import StreamlitPageAnalytics
with StreamlitPageAnalytics.track(
name="my-app",
session_id=f"{session_id}",
user_id=f"{user_id}",
mask_text_input_values=True, # Enable masking for text inputs
):
st.text_input("Password") # Value will be logged as "[REDACTED]"
st.text_area("Notes") # Value will be logged as "[REDACTED]"
st.selectbox("Option", ["A", "B"]) # Not affected, logs actual valueCurrent Status
The following Streamlit widgets are currently supported:
st.button- Click eventsst.form_submit_button- Submit events; combined snapshot of tracked form fields inextra.form_fieldswhen used insidest.form()st.checkbox- Change eventsst.radio- Change eventsst.selectbox- Change eventsst.multiselect- Change eventsst.slider- Change eventsst.select_slider- Change eventsst.text_input- Change eventsst.number_input- Change eventsst.text_area- Change events
-…
Excerpt shown — open the source for the full document.
Notability
notability 3.0/10Low-star routine repo