quapp-common 0.0.12.dev15__tar.gz → 0.0.13.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. {quapp_common-0.0.12.dev15/quapp_common.egg-info → quapp_common-0.0.13.dev1}/PKG-INFO +44 -10
  2. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/README.md +43 -9
  3. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/pyproject.toml +1 -1
  4. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/circuit_adapter.py +18 -4
  5. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/dispatcher.py +6 -3
  6. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1/quapp_common.egg-info}/PKG-INFO +44 -10
  7. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/LICENSE +0 -0
  8. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/__init__.py +0 -0
  9. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/async_tasks/__init__.py +0 -0
  10. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/async_tasks/async_invocation_task.py +0 -0
  11. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/async_tasks/async_task.py +0 -0
  12. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/async_tasks/export_circuit_task.py +0 -0
  13. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/async_tasks/post_processing_task.py +0 -0
  14. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/__init__.py +0 -0
  15. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/backend/__init__.py +0 -0
  16. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/backend/invocation.py +0 -0
  17. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/backend/job_fetcher.py +0 -0
  18. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/backend/job_fetching.py +0 -0
  19. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/backend/job_manager.py +0 -0
  20. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/bridge.py +0 -0
  21. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/callback/__init__.py +0 -0
  22. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/callback/update_job_metadata.py +0 -0
  23. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/device/__init__.py +0 -0
  24. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/device/device_selection.py +0 -0
  25. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/component/result_serializer.py +0 -0
  26. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/config/__init__.py +0 -0
  27. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/config/logging_config.py +0 -0
  28. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/config/thread_config.py +0 -0
  29. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/__init__.py +0 -0
  30. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/async_task/__init__.py +0 -0
  31. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/async_task/circuit_export/__init__.py +0 -0
  32. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/async_task/circuit_export/backend_holder.py +0 -0
  33. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/async_task/circuit_export/circuit_holder.py +0 -0
  34. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/backend/__init__.py +0 -0
  35. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/backend/backend_information.py +0 -0
  36. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/callback/__init__.py +0 -0
  37. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/callback/callback_url.py +0 -0
  38. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/device/__init__.py +0 -0
  39. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/device/circuit_running_option.py +0 -0
  40. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/promise/__init__.py +0 -0
  41. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/promise/post_processing_promise.py +0 -0
  42. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/promise/promise.py +0 -0
  43. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/request/__init__.py +0 -0
  44. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/request/invocation_request.py +0 -0
  45. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/request/job_fetching_request.py +0 -0
  46. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/request/request.py +0 -0
  47. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/response/__init__.py +0 -0
  48. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/response/authentication.py +0 -0
  49. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/response/custom_header.py +0 -0
  50. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/data/response/job_response.py +0 -0
  51. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/__init__.py +0 -0
  52. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/base_enum.py +0 -0
  53. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/http_header.py +0 -0
  54. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/invocation_step.py +0 -0
  55. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/language.py +0 -0
  56. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/media_type.py +0 -0
  57. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/processing_unit.py +0 -0
  58. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/provider_tag.py +0 -0
  59. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/sdk.py +0 -0
  60. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/status/__init__.py +0 -0
  61. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/status/job_status.py +0 -0
  62. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/status/status_code.py +0 -0
  63. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/enum/token_type.py +0 -0
  64. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/factory/__init__.py +0 -0
  65. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/factory/device_factory.py +0 -0
  66. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/factory/handler_factory.py +0 -0
  67. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/factory/provider_factory.py +0 -0
  68. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/handler/__init__.py +0 -0
  69. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/handler/handler.py +0 -0
  70. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/__init__.py +0 -0
  71. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/device/__init__.py +0 -0
  72. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/device/custom_device.py +0 -0
  73. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/device/device.py +0 -0
  74. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/invocation.py +0 -0
  75. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/provider/__init__.py +0 -0
  76. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/model/provider/provider.py +0 -0
  77. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/util/__init__.py +0 -0
  78. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/util/file_utils.py +0 -0
  79. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/util/http_utils.py +0 -0
  80. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/util/json_parser_utils.py +0 -0
  81. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common/util/response_utils.py +0 -0
  82. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common.egg-info/SOURCES.txt +0 -0
  83. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common.egg-info/dependency_links.txt +0 -0
  84. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common.egg-info/requires.txt +0 -0
  85. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/quapp_common.egg-info/top_level.txt +0 -0
  86. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/setup.cfg +0 -0
  87. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/tests/test_circuit_adapter.py +0 -0
  88. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/tests/test_json_parser_utils.py +0 -0
  89. {quapp_common-0.0.12.dev15 → quapp_common-0.0.13.dev1}/tests/test_result_serializer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quapp-common
3
- Version: 0.0.12.dev15
3
+ Version: 0.0.13.dev1
4
4
  Summary: Quapp common library supporting Quapp Platform for Quantum Computing
5
5
  Author-email: "CITYNOW Co. Ltd. " <corp@citynow.vn>
6
6
  License: The MIT License (MIT)
@@ -80,15 +80,22 @@ responses while work continues in the background.
80
80
  - Multi-language SDK support:
81
81
  - Language enum for validating and resolving Python, JavaScript, and Q#
82
82
  runtimes.
83
- - SubprocessDispatcher to delegate tasks to non-Python runtimes via
84
- subprocess with timeout management and JSON payload processing; supports
85
- Node.js and `dotnet run` (Q#) runners.
86
- - SubprocessBridge integrating dispatcher, circuit adapter, and result
87
- serializer for seamless JS-Python handler interaction.
88
- - CircuitAdapter for converting JS subprocess circuit outputs into native
89
- SDK formats (OpenQASM, QUBO, JSON) across Qiskit, Braket, PennyLane, etc.
90
- - ResultSerializer for converting complex job results into JSON-serializable
91
- dictionaries for subprocess communication.
83
+ - Standalone `dispatch()` function (formerly `SubprocessDispatcher` class)
84
+ to delegate tasks to non-Python runtimes via subprocess with timeout
85
+ management and JSON payload processing; supports Node.js and precompiled
86
+ Q# binary (`./handler_runner_bin/Function[.exe]`) runners.
87
+ - Working directory configurable via `QUAPP_WORKING_DIR` environment
88
+ variable; falls back to `os.getcwd()` when unset.
89
+ - `SubprocessBridge` class integrating standalone dispatcher, circuit
90
+ adapter, and result serializer for seamless JS/Q#-Python handler
91
+ interaction.
92
+ - Standalone `adapt()` function (formerly `CircuitAdapter` class) for
93
+ converting subprocess circuit outputs into native SDK formats (OpenQASM,
94
+ QUBO, JSON) across Qiskit, Braket, PennyLane, PyQuil, Qibo, Qulacs, and
95
+ CUDA Quantum.
96
+ - Standalone `serialize()` function (formerly `ResultSerializer` class) for
97
+ converting complex job results into JSON-serializable dictionaries for
98
+ subprocess communication.
92
99
 
93
100
  ## Installation
94
101
 
@@ -107,6 +114,33 @@ Notes:
107
114
 
108
115
  ## Recently Changes Highlights
109
116
 
117
+ ### v0.0.13.dev1
118
+ - Refactor: Replace class-based subprocess components with standalone
119
+ module-level functions for simpler imports and testability:
120
+ - `SubprocessDispatcher` class → `dispatch()` and `is_subprocess_language()`
121
+ in `dispatcher.py`.
122
+ - `CircuitAdapter` class → `adapt()` and private helper functions in
123
+ `circuit_adapter.py`.
124
+ - `ResultSerializer` class → `serialize()` in `result_serializer.py`.
125
+ - `SubprocessBridge` retains its class form but delegates internally to the
126
+ new standalone functions.
127
+ - Refactor `dispatcher.py`: `WORKING_DIR` is now read from the
128
+ `QUAPP_WORKING_DIR` environment variable (previously hardcoded `None`);
129
+ falls back to `os.getcwd()` when the variable is unset.
130
+ - Refactor `dispatcher.py`: Q# runner command changed from
131
+ `dotnet run --project HandlerRunner.csproj` to a precompiled
132
+ platform-specific binary — `./handler_runner_bin/Function.exe` on Windows
133
+ and `./handler_runner_bin/Function` on other platforms — eliminating the
134
+ `dotnet` toolchain requirement at runtime.
135
+ - Refactor `circuit_adapter.py`: Extract `_load_qasm_circuit(qasm_str)` private
136
+ utility that centralises OpenQASM 2.0 string parsing with Qiskit version
137
+ compatibility — uses `qiskit.qasm2.loads` (Qiskit >= 1.0) and falls back to
138
+ `QiskitCircuit.from_qasm_str` (Qiskit < 1.0).
139
+ - Fix: `subprocess.run` now passes `check=True` so a non-zero exit code raises
140
+ `CalledProcessError` before the manual return-code branch is reached.
141
+ - Add unit tests: `tests/test_circuit_adapter.py`,
142
+ `tests/test_json_parser_utils.py`, `tests/test_result_serializer.py`.
143
+
110
144
  ### v0.0.12.dev15
111
145
  - Extend multi-language SDK support with Q# (QSharp) runtime:
112
146
  - Add `QSHARP` to `Language` enum.
@@ -39,15 +39,22 @@ responses while work continues in the background.
39
39
  - Multi-language SDK support:
40
40
  - Language enum for validating and resolving Python, JavaScript, and Q#
41
41
  runtimes.
42
- - SubprocessDispatcher to delegate tasks to non-Python runtimes via
43
- subprocess with timeout management and JSON payload processing; supports
44
- Node.js and `dotnet run` (Q#) runners.
45
- - SubprocessBridge integrating dispatcher, circuit adapter, and result
46
- serializer for seamless JS-Python handler interaction.
47
- - CircuitAdapter for converting JS subprocess circuit outputs into native
48
- SDK formats (OpenQASM, QUBO, JSON) across Qiskit, Braket, PennyLane, etc.
49
- - ResultSerializer for converting complex job results into JSON-serializable
50
- dictionaries for subprocess communication.
42
+ - Standalone `dispatch()` function (formerly `SubprocessDispatcher` class)
43
+ to delegate tasks to non-Python runtimes via subprocess with timeout
44
+ management and JSON payload processing; supports Node.js and precompiled
45
+ Q# binary (`./handler_runner_bin/Function[.exe]`) runners.
46
+ - Working directory configurable via `QUAPP_WORKING_DIR` environment
47
+ variable; falls back to `os.getcwd()` when unset.
48
+ - `SubprocessBridge` class integrating standalone dispatcher, circuit
49
+ adapter, and result serializer for seamless JS/Q#-Python handler
50
+ interaction.
51
+ - Standalone `adapt()` function (formerly `CircuitAdapter` class) for
52
+ converting subprocess circuit outputs into native SDK formats (OpenQASM,
53
+ QUBO, JSON) across Qiskit, Braket, PennyLane, PyQuil, Qibo, Qulacs, and
54
+ CUDA Quantum.
55
+ - Standalone `serialize()` function (formerly `ResultSerializer` class) for
56
+ converting complex job results into JSON-serializable dictionaries for
57
+ subprocess communication.
51
58
 
52
59
  ## Installation
53
60
 
@@ -66,6 +73,33 @@ Notes:
66
73
 
67
74
  ## Recently Changes Highlights
68
75
 
76
+ ### v0.0.13.dev1
77
+ - Refactor: Replace class-based subprocess components with standalone
78
+ module-level functions for simpler imports and testability:
79
+ - `SubprocessDispatcher` class → `dispatch()` and `is_subprocess_language()`
80
+ in `dispatcher.py`.
81
+ - `CircuitAdapter` class → `adapt()` and private helper functions in
82
+ `circuit_adapter.py`.
83
+ - `ResultSerializer` class → `serialize()` in `result_serializer.py`.
84
+ - `SubprocessBridge` retains its class form but delegates internally to the
85
+ new standalone functions.
86
+ - Refactor `dispatcher.py`: `WORKING_DIR` is now read from the
87
+ `QUAPP_WORKING_DIR` environment variable (previously hardcoded `None`);
88
+ falls back to `os.getcwd()` when the variable is unset.
89
+ - Refactor `dispatcher.py`: Q# runner command changed from
90
+ `dotnet run --project HandlerRunner.csproj` to a precompiled
91
+ platform-specific binary — `./handler_runner_bin/Function.exe` on Windows
92
+ and `./handler_runner_bin/Function` on other platforms — eliminating the
93
+ `dotnet` toolchain requirement at runtime.
94
+ - Refactor `circuit_adapter.py`: Extract `_load_qasm_circuit(qasm_str)` private
95
+ utility that centralises OpenQASM 2.0 string parsing with Qiskit version
96
+ compatibility — uses `qiskit.qasm2.loads` (Qiskit >= 1.0) and falls back to
97
+ `QiskitCircuit.from_qasm_str` (Qiskit < 1.0).
98
+ - Fix: `subprocess.run` now passes `check=True` so a non-zero exit code raises
99
+ `CalledProcessError` before the manual return-code branch is reached.
100
+ - Add unit tests: `tests/test_circuit_adapter.py`,
101
+ `tests/test_json_parser_utils.py`, `tests/test_result_serializer.py`.
102
+
69
103
  ### v0.0.12.dev15
70
104
  - Extend multi-language SDK support with Q# (QSharp) runtime:
71
105
  - Add `QSHARP` to `Language` enum.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quapp-common"
7
- version = "0.0.12.dev15"
7
+ version = "0.0.13.dev1"
8
8
  description = "Quapp common library supporting Quapp Platform for Quantum Computing"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "CITYNOW Co. Ltd. ", email = "corp@citynow.vn" }]
@@ -9,6 +9,10 @@ from typing import Any, Dict
9
9
  import numpy as np
10
10
  import pennylane as qml
11
11
  import pennylane.measurements as _plm
12
+ try:
13
+ import qiskit.qasm2 as _qasm2
14
+ except ImportError:
15
+ _qasm2 = None
12
16
  from dimod import BinaryQuadraticModel
13
17
  from pytket.qasm import circuit_from_qasm_str
14
18
  from qibo.models import Circuit
@@ -22,6 +26,16 @@ from ..enum.sdk import Sdk
22
26
  logger = logger.bind(context=__name__)
23
27
 
24
28
 
29
+ def _load_qasm_circuit(qasm_str: str) -> QiskitCircuit:
30
+ """Parse OpenQASM 2.0 string into a Qiskit QuantumCircuit.
31
+
32
+ Compatible with Qiskit >= 1.0 (qiskit.qasm2.loads) and < 1.0 (from_qasm_str).
33
+ """
34
+ if _qasm2 is not None:
35
+ return _qasm2.loads(qasm_str)
36
+ return QiskitCircuit.from_qasm_str(qasm_str)
37
+
38
+
25
39
  def adapt(sdk: Sdk, result: dict):
26
40
  """Route to the appropriate adapter based on the 'format' field."""
27
41
  fmt = result.get("format")
@@ -142,8 +156,8 @@ def _openqasm_to_qibo(qasm_str):
142
156
 
143
157
 
144
158
  def _openqasm_to_qiskit(qasm_str):
145
- logger.debug("Converting OpenQASM via Qiskit QuantumCircuit.from_qasm_str")
146
- return QiskitCircuit.from_qasm_str(qasm_str)
159
+ logger.debug("Converting OpenQASM via Qiskit QuantumCircuit")
160
+ return _load_qasm_circuit(qasm_str)
147
161
 
148
162
 
149
163
  def _openqasm_to_qulacs(qasm_str):
@@ -151,7 +165,7 @@ def _openqasm_to_qulacs(qasm_str):
151
165
  # Try the Qiskit bridge first; fall back to raw pass-through if
152
166
  # qiskit is not installed or the conversion fails.
153
167
  try:
154
- qiskit_circ = QiskitCircuit.from_qasm_str(qasm_str)
168
+ qiskit_circ = _load_qasm_circuit(qasm_str)
155
169
  logger.debug(
156
170
  f"Qiskit parsed circuit: num_qubits={qiskit_circ.num_qubits} num_gates={len(qiskit_circ.data)}")
157
171
  return _qiskit_to_qulacs(qiskit_circ)
@@ -166,7 +180,7 @@ def _qiskit_to_pennylane(qasm_str, num_wires):
166
180
  Fallback for environments where qml.from_qasm is unavailable because
167
181
  pennylane-qiskit is not installed (PennyLane < 0.36).
168
182
  """
169
- qiskit_circ = QiskitCircuit.from_qasm_str(qasm_str)
183
+ qiskit_circ = _load_qasm_circuit(qasm_str)
170
184
  qubit_map = {bit: idx for idx, bit in enumerate(qiskit_circ.qubits)}
171
185
  logger.debug(
172
186
  f"_qiskit_to_pennylane: num_qubits={qiskit_circ.num_qubits} "
@@ -5,21 +5,24 @@
5
5
  import json
6
6
  import os
7
7
  import subprocess
8
+ import sys
8
9
 
9
10
  from ..config.logging_config import logger
10
11
  from ..enum.language import Language
11
12
 
12
13
  logger = logger.bind(context=__name__)
13
14
 
14
- WORKING_DIR: str = None
15
+ WORKING_DIR: str = os.environ.get('QUAPP_WORKING_DIR')
16
+
17
+ _QSHARP_BINARY = './handler_runner_bin/Function.exe' if sys.platform == 'win32' else './handler_runner_bin/Function'
15
18
 
16
19
  RUNNER_MAP = {
17
20
  Language.JAVASCRIPT: {
18
21
  'command': ['node', 'handler_runner.js'],
19
22
  'timeout': 300,
20
23
  },
21
- Language.QSHARP: {
22
- 'command': ['dotnet', 'run', '--project', 'HandlerRunner.csproj'],
24
+ Language.QSHARP: {
25
+ 'command': [_QSHARP_BINARY],
23
26
  'timeout': 300,
24
27
  },
25
28
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quapp-common
3
- Version: 0.0.12.dev15
3
+ Version: 0.0.13.dev1
4
4
  Summary: Quapp common library supporting Quapp Platform for Quantum Computing
5
5
  Author-email: "CITYNOW Co. Ltd. " <corp@citynow.vn>
6
6
  License: The MIT License (MIT)
@@ -80,15 +80,22 @@ responses while work continues in the background.
80
80
  - Multi-language SDK support:
81
81
  - Language enum for validating and resolving Python, JavaScript, and Q#
82
82
  runtimes.
83
- - SubprocessDispatcher to delegate tasks to non-Python runtimes via
84
- subprocess with timeout management and JSON payload processing; supports
85
- Node.js and `dotnet run` (Q#) runners.
86
- - SubprocessBridge integrating dispatcher, circuit adapter, and result
87
- serializer for seamless JS-Python handler interaction.
88
- - CircuitAdapter for converting JS subprocess circuit outputs into native
89
- SDK formats (OpenQASM, QUBO, JSON) across Qiskit, Braket, PennyLane, etc.
90
- - ResultSerializer for converting complex job results into JSON-serializable
91
- dictionaries for subprocess communication.
83
+ - Standalone `dispatch()` function (formerly `SubprocessDispatcher` class)
84
+ to delegate tasks to non-Python runtimes via subprocess with timeout
85
+ management and JSON payload processing; supports Node.js and precompiled
86
+ Q# binary (`./handler_runner_bin/Function[.exe]`) runners.
87
+ - Working directory configurable via `QUAPP_WORKING_DIR` environment
88
+ variable; falls back to `os.getcwd()` when unset.
89
+ - `SubprocessBridge` class integrating standalone dispatcher, circuit
90
+ adapter, and result serializer for seamless JS/Q#-Python handler
91
+ interaction.
92
+ - Standalone `adapt()` function (formerly `CircuitAdapter` class) for
93
+ converting subprocess circuit outputs into native SDK formats (OpenQASM,
94
+ QUBO, JSON) across Qiskit, Braket, PennyLane, PyQuil, Qibo, Qulacs, and
95
+ CUDA Quantum.
96
+ - Standalone `serialize()` function (formerly `ResultSerializer` class) for
97
+ converting complex job results into JSON-serializable dictionaries for
98
+ subprocess communication.
92
99
 
93
100
  ## Installation
94
101
 
@@ -107,6 +114,33 @@ Notes:
107
114
 
108
115
  ## Recently Changes Highlights
109
116
 
117
+ ### v0.0.13.dev1
118
+ - Refactor: Replace class-based subprocess components with standalone
119
+ module-level functions for simpler imports and testability:
120
+ - `SubprocessDispatcher` class → `dispatch()` and `is_subprocess_language()`
121
+ in `dispatcher.py`.
122
+ - `CircuitAdapter` class → `adapt()` and private helper functions in
123
+ `circuit_adapter.py`.
124
+ - `ResultSerializer` class → `serialize()` in `result_serializer.py`.
125
+ - `SubprocessBridge` retains its class form but delegates internally to the
126
+ new standalone functions.
127
+ - Refactor `dispatcher.py`: `WORKING_DIR` is now read from the
128
+ `QUAPP_WORKING_DIR` environment variable (previously hardcoded `None`);
129
+ falls back to `os.getcwd()` when the variable is unset.
130
+ - Refactor `dispatcher.py`: Q# runner command changed from
131
+ `dotnet run --project HandlerRunner.csproj` to a precompiled
132
+ platform-specific binary — `./handler_runner_bin/Function.exe` on Windows
133
+ and `./handler_runner_bin/Function` on other platforms — eliminating the
134
+ `dotnet` toolchain requirement at runtime.
135
+ - Refactor `circuit_adapter.py`: Extract `_load_qasm_circuit(qasm_str)` private
136
+ utility that centralises OpenQASM 2.0 string parsing with Qiskit version
137
+ compatibility — uses `qiskit.qasm2.loads` (Qiskit >= 1.0) and falls back to
138
+ `QiskitCircuit.from_qasm_str` (Qiskit < 1.0).
139
+ - Fix: `subprocess.run` now passes `check=True` so a non-zero exit code raises
140
+ `CalledProcessError` before the manual return-code branch is reached.
141
+ - Add unit tests: `tests/test_circuit_adapter.py`,
142
+ `tests/test_json_parser_utils.py`, `tests/test_result_serializer.py`.
143
+
110
144
  ### v0.0.12.dev15
111
145
  - Extend multi-language SDK support with Q# (QSharp) runtime:
112
146
  - Add `QSHARP` to `Language` enum.