
Product
Rust Support Now in Beta
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Keyboard hotkeys for Streamlit (Ctrl/Cmd/Alt/Shift combos) with edge-triggered events.
Streamlit Hotkeys lets you wire up fast, app-wide keyboard shortcuts in seconds. Bind Ctrl/Cmd/Alt/Shift + key
to actions and get edge-triggered events with a clean, Pythonic API (if hotkeys.pressed("save"):
or multiple on_pressed(...)
callbacks). It runs through a single invisible manager—no widget clutter, no flicker—and can scope reruns to the whole page or just a fragment. Reuse the same id
across combos (e.g., Cmd+K or Ctrl+K → palette
), block browser defaults like Ctrl/Cmd+S
, and use physical key codes for layout-independent bindings.
pip install streamlit-hotkeys
import streamlit as st
import streamlit_hotkeys as hotkeys
# Activate early (top of the script)
hotkeys.activate([
hotkeys.hk("palette", "k", meta=True), # Cmd+K (mac)
hotkeys.hk("palette", "k", ctrl=True), # Ctrl+K (win/linux)
hotkeys.hk("save", "s", ctrl=True, prevent_default=True), # Ctrl+S
])
st.title("Hotkeys quick demo")
if hotkeys.pressed("palette"):
st.write("Open palette")
if hotkeys.pressed("save"):
st.write("Saved!")
st.caption("Try Cmd/Ctrl+K and Ctrl+S")
pressed(id)
multiple times and each will see True
)on_pressed(id, ...)
handlers (deduped, run in order)ctrl
, alt
, shift
, meta
)id
across bindings (e.g., Cmd+K or Ctrl+K → palette
)prevent_default
to block browser shortcuts (e.g., Ctrl/Cmd+S)code="KeyK"
/ code="Digit1"
ignore_repeat
to suppress repeats while a key is heldhelp="..."
in hk(...)
and call hotkeys.legend()
key=
debug=True
to log matches in the browser consolehk(...)
— define a bindinghk(
id: str,
key: str | None = None, # e.g., "k", "Enter", "ArrowDown"
*,
code: str | None = None, # e.g., "KeyK" (if set, 'key' is ignored)
alt: bool | None = False, # True=require, False=forbid, None=ignore
ctrl: bool | None = False,
shift: bool | None = False,
meta: bool | None = False,
ignore_repeat: bool = True,
prevent_default: bool = False,
help: str | None = None, # optional text shown in legend
) -> dict
Defines one shortcut. You may reuse the same id
across multiple bindings (e.g., Cmd+K or Ctrl+K → palette
). Use code="KeyK"
for layout-independent physical keys.
activate(*bindings, key="global", debug=False) -> None
Registers bindings and renders the single invisible manager. Accepted forms:
hk(...)
dictshk(...)
dictsid -> spec
or id -> [spec, spec, ...]
Notes: call as early as possible on each page/fragment. The key
scopes events; if the manager lives inside a fragment, only that fragment reruns on a match. debug=True
logs matches in the browser console.
pressed(id, *, key="global") -> bool
Returns True
once per new key press (edge-triggered across reruns). Within the same rerun, you can call pressed(id)
multiple times in different places and each will see True
.
on_pressed(id, callback=None, *, key="global", args=(), kwargs=None)
Registers a callback to run once per key press. Multiple callbacks can be registered for the same id
(deduped across reruns). You can use decorator or direct form. Callbacks run before any subsequent pressed(...)
checks in the same rerun.
legend(*, key="global") -> None
Renders a grouped list of shortcuts for the given manager key. Bindings that share the same id
are merged; the first non-empty help
string per id
is shown.
if ... pressed(...)
import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Basic hotkeys")
hotkeys.activate([
hotkeys.hk("hello", "h"), # press H
hotkeys.hk("enter", "Enter"), # press Enter
])
if hotkeys.pressed("hello"):
st.write("Hello 👋")
if hotkeys.pressed("enter"):
st.write("You pressed Enter")
id
for Cmd+K / Ctrl+K)import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Cross-platform palette (Cmd/Ctrl+K)")
hotkeys.activate([
hotkeys.hk("palette", "k", meta=True), # macOS
hotkeys.hk("palette", "k", ctrl=True), # Windows/Linux
])
if hotkeys.pressed("palette"):
st.success("Open command palette")
import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Prevent default on Ctrl/Cmd+S")
hotkeys.activate([
hotkeys.hk("save", "s", ctrl=True, prevent_default=True), # Ctrl+S
hotkeys.hk("save", "s", meta=True, prevent_default=True), # Cmd+S
])
if hotkeys.pressed("save"):
st.success("Saved (browser Save dialog was blocked)")
import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Legend example")
hotkeys.activate({
"palette": [
{"key": "k", "meta": True, "help": "Open command palette"},
{"key": "k", "ctrl": True},
],
"save": {"key": "s", "ctrl": True, "prevent_default": True, "help": "Save document"},
}, key="global")
@st.dialog("Keyboard Shortcuts")
def _shortcuts():
hotkeys.legend() # grouped legend (uses help=...)
if hotkeys.pressed("palette"):
_shortcuts()
st.caption("Press Cmd/Ctrl+K to open the legend")
import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Fragment-local rerun")
st.write("Outside the fragment: no rerun on Ctrl+S")
@st.fragment
def editor_panel():
hotkeys.activate([hotkeys.hk("save", "s", ctrl=True)], key="editor")
st.text_area("Document", height=120, key="doc")
if hotkeys.pressed("save", key="editor"):
st.success("Saved inside fragment only")
editor_panel()
ignore_repeat=False
)import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Hold ArrowDown to increment")
hotkeys.activate([
hotkeys.hk("down", "ArrowDown", ignore_repeat=False),
])
st.session_state.setdefault("count", 0)
if hotkeys.pressed("down"):
st.session_state["count"] += 1
st.metric("Count", st.session_state["count"])
st.caption("Hold ArrowDown to spam events (ignore_repeat=False)")
import streamlit as st
import streamlit_hotkeys as hotkeys
st.title("Multiple callbacks")
hotkeys.activate([
hotkeys.hk("save", "s", ctrl=True, prevent_default=True),
])
def save_doc():
st.write("Saving...")
def toast_saved():
st.toast("Saved!")
# register both; each runs once per key press
hotkeys.on_pressed("save", save_doc)
hotkeys.on_pressed("save", toast_saved)
# you can still branch with pressed() afterwards
if hotkeys.pressed("save"):
st.info("Thank you for saving")
prevent_default=True
to keep the event for your app when allowed.A+S
) as a single combo.Inspired by streamlit-keypress by Sudarsan. This implementation adds a multi-binding manager, edge-triggered events, modifier handling, preventDefault
, KeyboardEvent.code
and many more features.
Issues and PRs are welcome.
MIT. See LICENSE
.
FAQs
Keyboard hotkeys for Streamlit (Ctrl/Cmd/Alt/Shift combos) with edge-triggered events.
We found that streamlit-hotkeys demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.