molvis
Python package for MolVis molecular visualization and agent control. A single
mv.Molvis() class works from both plain Python scripts (opens a
browser tab) and Jupyter notebooks (mounts the page bundle inline in
the cell, isolated by Shadow DOM — no iframe). Both hosts drive the
same page bundle over a local WebSocket.
Installation
pip install molcrafts-molvis
Quick start
Plain Python script
import molvis as mv
import molpy as mp
viewer = mv.Molvis() # starts a local WebSocket + opens a browser tab
viewer.draw_frame(frame)
viewer.snapshot() # PNG screenshot
Jupyter notebook
import molvis as mv
scene = mv.Molvis(name="protein")
scene.draw_frame(frame)
scene # mounts the viewer inline in the cell
Both modes use the same command API (draw_frame, set_style,
snapshot, selection, palettes, …) and the same event channel.
Agent control and visual feedback
MolVis can act as the review surface for an agent. The agent drives the scene through structured RPC calls; the user reviews the rendered result and selects the atoms or bonds that express their feedback.
viewer.set_view_mode("select")
# Ask the user to select the region that needs another pass.
event = viewer.wait_for("selection_changed", timeout=120)
selected = viewer.get_selected() # complete standalone molecular subset
feedback = {
"frame": viewer.current_frame,
"atom_ids": event["atom_ids"],
"bond_ids": event["bond_ids"],
"selection": selected,
"snapshot": viewer.snapshot(),
}
# Pass `feedback` to the agent and retain it in the host's audit record.
The viewer makes each agent action visible and returns user intent as molecular data rather than screen coordinates. For durable auditing, the host should log RPC requests/responses together with frame number, selection IDs, and optional snapshots.
Bidirectional events
Frontend interactions (selection, mode, frame navigation, …) flow back into Python. Selection is a shared state — canvas clicks are observable from Python without polling.
viewer = mv.Molvis()
# Subscribe to a frontend event (callback runs on the WS thread)
handle = viewer.on("selection_changed",
lambda ev: print("sel:", ev["atom_ids"]))
handle.remove() # unsubscribe
# Block until a specific event fires
ev = viewer.wait_for("selection_changed", timeout=30)
# Cached state, updated live by incoming events — no RPC roundtrip
print(viewer.selection) # Selection(atom_ids=(...), bond_ids=(...))
print(viewer.current_mode) # "view" | "select" | "edit" | ...
print(viewer.current_frame)
# Force a fresh snapshot from the canvas
viewer.refresh_state()
Transport
mv.Molvis() auto-creates a WebSocketTransport. Outside Jupyter it
opens the page in the default browser; inside Jupyter the cell mounts
the bundle inline. For advanced setups (CDN-hosted page, explicit port,
CORS …) pass your own transport:
viewer = mv.Molvis(transport=mv.WebSocketTransport(
page_base_url="https://molvis.dev/app", # host page on a CDN
port=8765, # fixed port instead of OS-assigned
open_browser=False,
))
Token authentication is automatic: the page URL carries a one-time token that the frontend must echo back in its hello handshake.
Scene registry
a = mv.Molvis() # default scene
b = mv.Molvis()
assert a is b # same instance
protein = mv.Molvis(name="protein")
ligand = mv.Molvis(name="ligand")
mv.Molvis.list_scenes()
mv.Molvis.get_scene("protein")
protein.close() # stop transport + drop from registry
Drawing API
scene = mv.Molvis()
scene.set_style(style="ball-and-stick") # one global representation
scene.draw_frame(frame)
scene.draw_box(box)
scene.draw_atoms(atoms)
scene.new_frame()
scene.set_style(style="spacefill", atom_radius=0.5)
scene.set_style(style="skeletal", outline=True)
scene.draw_frame(frame) # data only; global style is unchanged
scene.set_theme("tab10") # "tab10" | "ovito"
scene.clear()
Query commands (block until the frontend responds)
png_bytes = scene.snapshot()
frame = scene.export_frame()
selected = scene.get_selected() # mp.Frame with just the selection
scene.select_atom_by_id([0, 2])
Error handling
Fire-and-forget commands (e.g. draw_frame) log errors asynchronously.
Query commands raise MolvisRPCError:
try:
scene.export_frame()
except mv.MolvisRPCError as exc:
print(exc.code, exc)
Development
# one-shot: build page → copy into python/src/molvis/dist/
npm run build:page
# watch: rebuild straight into python/src/molvis/dist/ on TS changes
# (refresh the browser / notebook to pick up new hashes)
npm run dev:python
cd python && python -m pytest tests/ -v
The package ships a single dist/ tree (index.html + js/ / css/ /
wasm/). There is no nested dist/static/.
Packaging
npm run build:page
cd python && python -m build --wheel
Metadata
Release files for molcrafts-molvis 0.3.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 | Provenance | |
|---|---|---|---|---|
| molcrafts_molvis-0.3.0.tar.gz | 5.3 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| molcrafts_molvis-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.6 MB
Release files / molcrafts_molvis-0.3.0.tar.gz
| Download URL | molcrafts_molvis-0.3.0.tar.gz |
|---|---|
| Size | 5.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0fccd2cfedeb4447b09f74ca8c836e2e8be20b04aae4dfb79d49f247a29258ce
|
|
BLAKE2b-256 checksum How to use checksums |
41d11a1e7e9114bac6a842157505da2a640bcbbccce3af620a1209fa62bfcfa9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logRelease files / molcrafts_molvis-0.3.0-py3-none-any.whl
| Download URL | molcrafts_molvis-0.3.0-py3-none-any.whl |
|---|---|
| Size | 5.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0514e09a2d9ef0d96fdbb1f36cff66a485512b9cd10c8bcfaca13ad2b6b01aa4
|
|
BLAKE2b-256 checksum How to use checksums |
9055281f0e7c8b9e54606a741a8ef0fa925a44bc7b5c303d043e6170a96b5dd4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logSecurity for molcrafts-molvis 0.3.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for molcrafts_molvis-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logA 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.