Add python widget for Bloch Sphere - #3595
Conversation
Bill Ticehurst (billti)
left a comment
There was a problem hiding this comment.
To minimize the impact of KaTeX on the Python package:
KaTeX CSS and fonts are isolated in a Bloch-specific stylesheet, so existing widgets continue loading the original lightweight stylesheet.
The production build retains only the four .woff2 font faces used by the Bloch sphere’s matrices and math expressions, reducing the Bloch stylesheet from approximately 383 KB to 109 KB raw (264 KB to 60 KB compressed).
The index.js file for the widget however is 600kb larger after this PR (which is already too large as we still need to move the molecule visualizer out of it). This loads in every cell that just wants to show a histogram or a circuit or whatever.
As discussed, we should figure out how to make this a separate entry point so it only gets loaded when the user wants to see a Bloch sphere (which will prbably be pretty rarely). I can give you some guidance if needed.
| }; | ||
|
|
||
| onChange(); | ||
| model.on("change:initial_gates", onChange); |
There was a problem hiding this comment.
This listener rerenders the wrapper when Python changes initial_gates, but the underlying BlochSphere reads initialGates only inside its mount-only useEffect([]). Since Preact preserves the mounted component when rendering it again, the updated prop is not applied.
I reproduced this with the wheel built from this PR:
from IPython.display import display
from qsharp_widgets import BlochSphere
widget = BlochSphere("X")
display(widget)The widget's gate-program text field initially shows X. Then run:
widget.initial_gates = "H"
print("initial_gates:", widget.initial_gates)
print("gates:", widget.gates)Observed:
initial_gates: H
gates: X
The rendered gate-program field also remains X, rather than changing to H.
Could the core component respond to subsequent initialGates prop changes, or should initial_gates not be exposed as a synchronized mutable trait?
Domingo Morales Lizama (domorale)
left a comment
There was a problem hiding this comment.
I built and tested the PR locally with the repository's Rust 1.95 toolchain. I left two inline comments:
- The generated widget wheel embeds KaTeX assets but appears not to include KaTeX's MIT license notice.
- Updating the synchronized
initial_gatestrait after display does not update the mounted Bloch Sphere; I included a minimal notebook reproducer and screenshot.
The widget otherwise built successfully and worked as expected in JupyterLab.
I've separated the bloch sphere into its own entry point with bloch.tsx, and removed it from index.tsx. |
| import markdownIt from "markdown-it"; | ||
| import { render as prender } from "preact"; | ||
|
|
||
| import { BlochSphere } from "../../npm/qsharp/ux/bloch/bloch.js"; |
There was a problem hiding this comment.
You should never import from the relative path the source like this. Import from qsharp-lang/ux just like it did in index.tsx.
Adds python support for the Bloch Sphere visualizer by making it a python widget, which is then added under the qsharp_widgets package, and additionally made available under the QDK python package.
Example python usage:
Additional fields added to the python bloch widget:
To minimize the impact of KaTeX on the Python package: