Repository navigation
Allow running visual circuit files (.qsc) directly from Python #3232
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or requestunitary-hack-26unitaryHACK 2026 bounty issuesunitaryHACK 2026 bounty issues
Description
Problem
.qsc files are JSON-based circuit definition files (visual circuit format) that describe quantum circuits with gates, measurements, qubits, etc. Currently, to use a .qsc circuit from Python, you must:
- Create a qsharp.json manifest file
- Write a
.qswrapper file that imports the circuit (import JointMeasurement.JointMeasurement;) - Call
qdk.Context(project_root=...)to load the full project - Then
.eval(...)or.run(...)through the Q# wrapper
This is a lot of ceremony for what should be a simple operation — especially for users who build circuits visually in VS Code and just want to simulate them from Python.
Proposed API
Add a load_circuit method to qdk.Context that accepts a path to a .qsc file and returns a callable:
import qdk
ctx = qdk.Context()
circuit = ctx.load_circuit("path/to/JointMeasurement.qsc")
# Run the circuit
results = ctx.run(circuit, shots=100)
# Or get a circuit diagram
diagram = ctx.circuit(circuit)Signature
def load_circuit(self, path: str) -> Callable:
"""
Loads a .qsc circuit file into this context and returns a callable
representing the circuit operation.
:param path: Path to a .qsc file.
:return: A callable that can be passed to ctx.run(), ctx.circuit(), etc.
:raises QSharpError: If the file cannot be read or is not a valid .qsc circuit.
"""Behavior
- Reads and validates the
.qscJSON file - Registers the circuit in the interpreter (similar to how project loading handles
.qscfiles today) - Returns a callable that behaves like any other Q# callable in the context (passable to
run,compile,circuit, etc.) - The circuit's qubit requirements are inferred from the
.qscfile (the format already declares qubits)
Open Questions
- Naming: Should the callable's name be derived from the filename (e.g., JointMeasurement.qsc →
ctx.code.JointMeasurement)? Or only returned, not registered onctx.code? - Multiple circuits: A
.qscfile can contain multiple circuits in its"circuits"array. Shouldload_circuitload just the first one, or should it return multiple callables / accept an index? - Qubit allocation: Circuits in
.qscdeclare their qubit count. Should the returned callable auto-allocate qubits internally, or require the caller to pass qubits (like the current Q# wrapper pattern)?
Existing Code Pointers
For contributors looking to implement this:
.qscloading in project system: project.rs (already globs for*.qscfiles).qscpreprocessing in the frontend: preprocess.rs- Circuit format/schema: circuit.rs
- Python
Contextclass: _context.py - Existing test using
.qscin a project: test_project.py (the"circuit"memfs entry) - Sample project using
.qsc: circuit_integration
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestunitary-hack-26unitaryHACK 2026 bounty issuesunitaryHACK 2026 bounty issues
Activity
[-]Allow running visual circuit files (.qsc) directly from Python without project boilerplate[/-][+]Allow running visual circuit files (.qsc) directly from Python[/+]tzh476 commentedon Jun 11, 2026
Submitted PR #3291 for this UnitaryHACK issue. The PR body links this issue with
Fixes #3232, and I updated it to reflect the currentContext.import_circuit(...)/ProgramTypeimplementation and latest local validation.feat(python): load visual circuits directly in Context (microsoft#3291)
feat(python): load visual circuits directly in Context (#3291)