Skip to content

Allow running visual circuit files (.qsc) directly from Python #3232

Closed

Description

Image

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:

  1. Create a qsharp.json manifest file
  2. Write a .qs wrapper file that imports the circuit (import JointMeasurement.JointMeasurement;)
  3. Call qdk.Context(project_root=...) to load the full project
  4. 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 .qsc JSON file
  • Registers the circuit in the interpreter (similar to how project loading handles .qsc files 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 .qsc file (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 on ctx.code?
  • Multiple circuits: A .qsc file can contain multiple circuits in its "circuits" array. Should load_circuit load just the first one, or should it return multiple callables / accept an index?
  • Qubit allocation: Circuits in .qsc declare 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:

  • .qsc loading in project system: project.rs (already globs for *.qsc files)
  • .qsc preprocessing in the frontend: preprocess.rs
  • Circuit format/schema: circuit.rs
  • Python Context class: _context.py
  • Existing test using .qsc in a project: test_project.py (the "circuit" memfs entry)
  • Sample project using .qsc: circuit_integration

Activity

  1. changed the title [-]Allow running visual circuit files (.qsc) directly from Python without project boilerplate[/-] [+]Allow running visual circuit files (.qsc) directly from Python[/+] on May 19, 2026
  2. tzh476 commented on Jun 11, 2026

    @tzh476
    Contributor

    Submitted PR #3291 for this UnitaryHACK issue. The PR body links this issue with Fixes #3232, and I updated it to reflect the current Context.import_circuit(...) / ProgramType implementation and latest local validation.

  3. added a commit that references this issue on Jun 12, 2026
    c7368e2
  4. added a commit that references this issue on Jun 16, 2026
    233f69d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or requestunitary-hack-26unitaryHACK 2026 bounty issues

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions