moutils
Utility functions used in marimo.
[!NOTE] This is a community led effort and not actively prioritized by the core marimo team.
Installation
pip install moutils
or with uv:
uv add moutils
Widgets
| Widget | Description |
|---|---|
URLHash |
Get and set the URL hash |
URLPath |
Get and set the URL path |
URLInfo |
Read all URL components |
DOMQuery |
Query DOM elements with CSS selectors |
CookieManager |
Get, set, and monitor browser cookies |
StorageItem |
Read/write localStorage or sessionStorage |
Slot |
Render HTML with DOM event handlers |
CopyToClipboard |
Copy text to clipboard with a button |
ShellWidget |
Run terminal commands with live output |
ColorScheme |
Detect dark/light mode preference |
ViewportSize |
Detect window dimensions |
OnlineStatus |
Detect network connectivity |
PageVisibility |
Detect if the browser tab is active |
Geolocation |
Get the user's geographic coordinates |
CameraCapture |
Capture a still image from the webcam |
Notification |
Send browser notifications |
KeyboardShortcut |
Listen for global keyboard shortcuts |
thread_mapprocess_mapinterpreter_map |
Thread/Process/Interpreter mapping |
PrintPageButton |
Button to open the browser print dialog |
print_page() |
Programmatically trigger the browser print dialog |
ScreenshotButton |
Button to capture a DOM element as PNG |
screenshot() |
Programmatically screenshot a DOM element |
URLHash
Get and set the hash portion of the URL.
from moutils import URLHash
h = URLHash()
h.hash # e.g. "#section-1"
URLPath
Get and set the current URL path.
from moutils import URLPath
p = URLPath()
p.path # e.g. "/notebooks/demo"
URLInfo
Read all URL components (protocol, hostname, port, pathname, search, hash, etc.).
from moutils import URLInfo
info = URLInfo()
info.hostname # e.g. "localhost"
DOMQuery
Query DOM elements using CSS selectors.
from moutils import DOMQuery
q = DOMQuery(selector=".my-class")
q.result # list of matched element data
CookieManager
Get, set, and monitor browser cookies.
from moutils import CookieManager
cm = CookieManager()
cm.cookies # dict of current cookies
StorageItem
Read and write data in the browser's localStorage or sessionStorage.
from moutils import StorageItem
s = StorageItem(key="my-key", storage_type="local")
s.data # stored value
Slot
Render HTML content and handle DOM events (mouse, keyboard, form, drag, touch, pointer, scroll, clipboard, animation).
from moutils import Slot
s = Slot(children="<button>Click me</button>", on_dblclick=lambda e: print(e))
CopyToClipboard
Copy text to the clipboard with a button and success feedback.
from moutils import CopyToClipboard
c = CopyToClipboard(text="hello world")
ShellWidget
Run terminal commands in notebooks with real-time output streaming.
from moutils import shell
shell("ls -la")
shell("npm install", working_directory="./frontend")
ColorScheme
Detect the user's preferred color scheme (light or dark). Automatically updates when the preference changes.
from moutils import ColorScheme
cs = ColorScheme()
cs.scheme # "light" or "dark"
cs.prefers_dark # True or False
ViewportSize
Detect the browser window dimensions. Updates on resize (debounced).
from moutils import ViewportSize
vs = ViewportSize()
vs.width # e.g. 1920
vs.height # e.g. 1080
OnlineStatus
Detect whether the browser has network connectivity.
from moutils import OnlineStatus
os_ = OnlineStatus()
os_.online # True or False
PageVisibility
Detect whether the browser tab is currently active or hidden.
from moutils import PageVisibility
pv = PageVisibility()
pv.visible # True or False
pv.state # "visible" or "hidden"
Geolocation
Get the user's geographic coordinates. Opt-in — set enabled=True to request permission.
from moutils import Geolocation
geo = Geolocation(enabled=True)
geo.latitude # e.g. 37.7749
geo.longitude # e.g. -122.4194
geo.accuracy # meters
geo.error # error message, if any
CameraCapture
Capture a still image from the webcam. Opt-in — set enabled=True to request camera access.
from moutils import CameraCapture
cam = CameraCapture(enabled=True, width=640, height=480)
cam.image_data # base64 data URL of the captured image
Notification
Send browser notifications. Automatically requests permission when needed.
from moutils import Notification
n = Notification(title="Done!", body="Your computation finished.")
n.send = True # fires the notification
n.permission # "default", "granted", or "denied"
KeyboardShortcut
Listen for global keyboard shortcuts with modifier key support.
from moutils import KeyboardShortcut
ks = KeyboardShortcut(shortcut="ctrl+k")
ks.pressed # True when the shortcut is pressed
ks.event # dict with key event details
thread_map, process_map, interpreter_map
Equivalent to list(map(fn, *iterables)) driven by ThreadPoolExecutor,
ProcessPoolExecutor, or InterpreterPoolExecutor (python >= 3.14) from
concurrent.futures, respectively, with a Marimo progress bar or spinner.
A spinner is used if the length cannot be automatically determined.
Inspired by https://tqdm.github.io/docs/contrib.concurrent/.
from moutils.concurrent import thread_map, process_map, interpreter_map
def add_one(x):
return x + 1
results: list[int] = thread_map(add_one, range(1000))
# Can specify title, max_workers, etc.
results = process_map(add_one, range(1000), title="Process map", max_workers=2)
results = interpreter_map(add_one, range(1000)) # Only available for Python >=3.14
PrintPageButton
Button that opens the browser print dialog when clicked.
from moutils import PrintPageButton
btn = PrintPageButton()
print_page()
Programmatically trigger the browser print dialog.
import moutils
moutils.print_page()
ScreenshotButton
Button that captures a DOM element as a PNG and downloads it.
from moutils import ScreenshotButton
btn = ScreenshotButton(locator="#my-chart", filename="chart.png")
screenshot()
Programmatically screenshot a DOM element and download as PNG.
import moutils
moutils.screenshot(locator="#my-chart", filename="chart.png")
Database connections
moutils.db provides DB-API-compatible adapters for marimo SQL cells. Import a
connection and assign it to a notebook variable. marimo detects the variable as
a SQL engine.
| Connection | Description |
|---|---|
PostHogConnection |
Query a PostHog project via its HogQL API (clickhouse dialect) |
DatasetteConnection |
Query one database of a Datasette instance (sqlite dialect) |
D1Connection |
Query a Cloudflare D1 database through its REST API |
ElasticsearchConnection |
Query Elasticsearch through its SQL API |
OpenSearchConnection |
Query OpenSearch through its SQL plugin |
TimestreamConnection |
Query Amazon Timestream for LiveAnalytics |
DuneConnection |
Execute raw DuneSQL through dune-client |
QueryConnection |
Adapt any query(sql) callable that returns tabular data |
ConnectorXConnection |
Adapt connectorx.read_sql with inferred dialects |
PostHogConnection uses the base requests dependency. Install the optional
db dependency for DatasetteConnection:
pip install "moutils[db]"
PostHogConnection
Create the connection in a Python cell. Use a PostHog personal API key.
from moutils.db.posthog import PostHogConnection
posthog = PostHogConnection(
api_key="phx_...",
project_id=123,
page_size=10_000,
)
page_size is required because PostHog otherwise returns at most 100 rows. Use a
value from 1 through 50,000. Then run HogQL in a SQL cell:
SELECT event, count() FROM events GROUP BY event
DatasetteConnection
from moutils.db.datasette import DatasetteConnection
datasette = DatasetteConnection("https://datasette.io", "content", token="...")
Then run SQLite SQL in a SQL cell:
SELECT * FROM tables LIMIT 10
A connection uses one database. Use datasette.databases() to list the database
routes. Use datasette.for_database("everest") to connect to another database.
QueryConnection
Use QueryConnection when a client already has a function that accepts SQL and
returns records, a result tuple, or a pandas, Polars, or PyArrow table:
from moutils.db.query import QueryConnection
warehouse = QueryConnection(
lambda sql: client.query(sql),
dialect="postgres",
)
ConnectorXConnection
pip install connectorx pandas
from moutils.db.connectorx import ConnectorXConnection
warehouse = ConnectorXConnection("postgresql://user:pass@host/database")
The SQL dialect is inferred from recognized connection URL schemes. Pass
dialect= explicitly for federated or custom URLs. Extra keyword arguments are
forwarded to connectorx.read_sql. Install Polars separately when using
return_type="polars".
Cloudflare D1
from moutils.db.d1 import D1Connection
d1 = D1Connection(
account_id="...",
database_id="...",
api_token="...", # Prefer a token with only D1 Read permission.
)
Elasticsearch and OpenSearch
The adapters wrap configured official clients and follow SQL result cursors to retrieve every page:
pip install elasticsearch opensearch-py
from elasticsearch import Elasticsearch
from moutils.db.elasticsearch import ElasticsearchConnection
elastic = ElasticsearchConnection(Elasticsearch("https://localhost:9200"))
from opensearchpy import OpenSearch
from moutils.db.opensearch import OpenSearchConnection
opensearch = OpenSearchConnection(OpenSearch("https://localhost:9200"))
Amazon Timestream
pip install boto3
import boto3
from moutils.db.timestream import TimestreamConnection
timestream = TimestreamConnection(boto3.client("timestream-query"))
The adapter follows NextToken pages and decodes scalar and nested Timestream
values.
Dune
pip install dune-client
from dune_client.client import DuneClient
from moutils.db.dune import DuneConnection
dune = DuneConnection(DuneClient.from_env())
The adapter submits raw DuneSQL, waits for completion, and retrieves every result page.
These connections do not support bound parameters. Use static or trusted SQL. Do not insert untrusted values into SQL strings. Provider adapters that receive an existing client leave that client open by default.
Development
We use uv for development.
Specific notebook
uv run marimo edit notebooks/example.py
Workspace
uv run --active marimo edit --port 2718
Installing pre-commit
uv tool install pre-commit
pre-commit
Testing
To run all tests:
pytest -v tests/
Release files for moutils 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| moutils-0.5.0.tar.gz | 179.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| moutils-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:257.5 kB
Release files / moutils-0.5.0.tar.gz
| Download URL | moutils-0.5.0.tar.gz |
|---|---|
| Size | 179.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
09239b5680861ed3f979bbda083b6a344c53db71660e39ffe8455303add5d0a6
|
|
BLAKE2b-256 checksum How to use checksums |
c398dc86d455108f18a52116e283c0720c08e3146865a17da56586514f29ca15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / moutils-0.5.0-py3-none-any.whl
| Download URL | moutils-0.5.0-py3-none-any.whl |
|---|---|
| Size | 78.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fc4eaae09192533b12d48d857c8b66b217136d65cc6c1c83e3d1c3c1b919256a
|
|
BLAKE2b-256 checksum How to use checksums |
da953492d1925f9423ae266327015125b21bbf87ce2c9004db96ce3126cb41e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|