luna-quantum 1.1.0__cp312-cp312-win_amd64.whl

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 (276) hide show
  1. luna_quantum/__init__.py +139 -0
  2. luna_quantum/__init__.pyi +98 -0
  3. luna_quantum/_core.cp312-win_amd64.pyd +0 -0
  4. luna_quantum/_core.pyi +4286 -0
  5. luna_quantum/_utility.py +148 -0
  6. luna_quantum/_utility.pyi +20 -0
  7. luna_quantum/algorithms/__init__.py +1 -0
  8. luna_quantum/aqm_overwrites/__init__.py +3 -0
  9. luna_quantum/aqm_overwrites/model.py +184 -0
  10. luna_quantum/backends/__init__.py +1 -0
  11. luna_quantum/client/__init__.py +0 -0
  12. luna_quantum/client/controllers/__init__.py +4 -0
  13. luna_quantum/client/controllers/luna_http_client.py +37 -0
  14. luna_quantum/client/controllers/luna_platform_client.py +256 -0
  15. luna_quantum/client/controllers/luna_q.py +67 -0
  16. luna_quantum/client/controllers/luna_solve.py +129 -0
  17. luna_quantum/client/error/__init__.py +0 -0
  18. luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
  19. luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
  20. luna_quantum/client/error/luna_error.py +2 -0
  21. luna_quantum/client/error/luna_server_error.py +20 -0
  22. luna_quantum/client/error/timeout_error.py +12 -0
  23. luna_quantum/client/error/transformation_error.py +18 -0
  24. luna_quantum/client/error/utils/__init__.py +0 -0
  25. luna_quantum/client/error/utils/http_error_utils.py +112 -0
  26. luna_quantum/client/interfaces/__init__.py +4 -0
  27. luna_quantum/client/interfaces/clients/__init__.py +25 -0
  28. luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
  29. luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
  30. luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
  31. luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
  32. luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
  33. luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
  34. luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
  35. luna_quantum/client/interfaces/services/__init__.py +0 -0
  36. luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
  37. luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
  38. luna_quantum/client/interfaces/services/service_i.py +56 -0
  39. luna_quantum/client/rest_client/__init__.py +15 -0
  40. luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
  41. luna_quantum/client/rest_client/info_rest_client.py +74 -0
  42. luna_quantum/client/rest_client/model_rest_client.py +216 -0
  43. luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
  44. luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
  45. luna_quantum/client/rest_client/users_rest_client.py +35 -0
  46. luna_quantum/client/schemas/__init__.py +26 -0
  47. luna_quantum/client/schemas/circuit.py +48 -0
  48. luna_quantum/client/schemas/create/__init__.py +15 -0
  49. luna_quantum/client/schemas/create/circuit.py +30 -0
  50. luna_quantum/client/schemas/create/optimization.py +39 -0
  51. luna_quantum/client/schemas/create/qpu_token.py +22 -0
  52. luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
  53. luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
  54. luna_quantum/client/schemas/create/qubo.py +19 -0
  55. luna_quantum/client/schemas/create/solve_job_create.py +43 -0
  56. luna_quantum/client/schemas/enums/__init__.py +0 -0
  57. luna_quantum/client/schemas/enums/call_style.py +13 -0
  58. luna_quantum/client/schemas/enums/circuit.py +42 -0
  59. luna_quantum/client/schemas/enums/model_format.py +11 -0
  60. luna_quantum/client/schemas/enums/problem.py +50 -0
  61. luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
  62. luna_quantum/client/schemas/enums/sense.py +8 -0
  63. luna_quantum/client/schemas/enums/status.py +40 -0
  64. luna_quantum/client/schemas/enums/timeframe.py +11 -0
  65. luna_quantum/client/schemas/error_message.py +14 -0
  66. luna_quantum/client/schemas/model_metadata.py +35 -0
  67. luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
  68. luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
  69. luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
  70. luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
  71. luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
  72. luna_quantum/client/schemas/representation.py +19 -0
  73. luna_quantum/client/schemas/solution.py +106 -0
  74. luna_quantum/client/schemas/solve_job.py +50 -0
  75. luna_quantum/client/schemas/solver_info.py +11 -0
  76. luna_quantum/client/schemas/user.py +11 -0
  77. luna_quantum/client/schemas/wrappers/__init__.py +5 -0
  78. luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
  79. luna_quantum/client/utils/__init__.py +0 -0
  80. luna_quantum/client/utils/qpu_token_utils.py +147 -0
  81. luna_quantum/config.py +11 -0
  82. luna_quantum/decorators.py +248 -0
  83. luna_quantum/errors.py +34 -0
  84. luna_quantum/errors.pyi +287 -0
  85. luna_quantum/exceptions/__init__.py +0 -0
  86. luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
  87. luna_quantum/exceptions/luna_quantum_call_type_error.py +9 -0
  88. luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
  89. luna_quantum/factories/__init__.py +4 -0
  90. luna_quantum/factories/luna_solve_client_factory.py +100 -0
  91. luna_quantum/factories/usecase_factory.py +489 -0
  92. luna_quantum/py.typed +0 -0
  93. luna_quantum/solve/__init__.py +13 -0
  94. luna_quantum/solve/default_token.py +304 -0
  95. luna_quantum/solve/domain/__init__.py +0 -0
  96. luna_quantum/solve/domain/abstract/__init__.py +4 -0
  97. luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
  98. luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
  99. luna_quantum/solve/domain/model_metadata.py +56 -0
  100. luna_quantum/solve/domain/solve_job.py +230 -0
  101. luna_quantum/solve/errors/__init__.py +0 -0
  102. luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
  103. luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
  104. luna_quantum/solve/errors/solve_base_error.py +5 -0
  105. luna_quantum/solve/errors/token_missing_error.py +11 -0
  106. luna_quantum/solve/interfaces/__init__.py +0 -0
  107. luna_quantum/solve/interfaces/algorithm_i.py +49 -0
  108. luna_quantum/solve/interfaces/backend_i.py +28 -0
  109. luna_quantum/solve/interfaces/usecases/__init__.py +59 -0
  110. luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
  111. luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
  112. luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
  113. luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
  114. luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
  115. luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
  116. luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
  117. luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
  118. luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
  119. luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
  120. luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
  121. luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
  122. luna_quantum/solve/interfaces/usecases/solve_job_get_by_id_usecase_i.py +27 -0
  123. luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
  124. luna_quantum/solve/parameters/__init__.py +0 -0
  125. luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
  126. luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
  127. luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
  128. luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
  129. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
  130. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
  131. luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
  132. luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
  133. luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
  134. luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
  135. luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
  136. luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
  137. luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
  138. luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
  139. luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
  140. luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
  141. luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
  142. luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
  143. luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
  144. luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
  145. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
  146. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
  147. luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
  148. luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
  149. luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
  150. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
  151. luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
  152. luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
  153. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +10 -0
  154. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/__init__.py +29 -0
  155. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/config.py +58 -0
  156. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/flexqaoa.py +188 -0
  157. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/optimizers.py +53 -0
  158. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/pipeline.py +164 -0
  159. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +112 -0
  160. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
  161. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
  162. luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
  163. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
  164. luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
  165. luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
  166. luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
  167. luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
  168. luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
  169. luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
  170. luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
  171. luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
  172. luna_quantum/solve/parameters/backends/__init__.py +27 -0
  173. luna_quantum/solve/parameters/backends/aqarios.py +17 -0
  174. luna_quantum/solve/parameters/backends/aqarios_gpu.py +17 -0
  175. luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
  176. luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
  177. luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
  178. luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
  179. luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
  180. luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
  181. luna_quantum/solve/parameters/backends/cudaq/__init__.py +5 -0
  182. luna_quantum/solve/parameters/backends/cudaq/cudaq_base.py +16 -0
  183. luna_quantum/solve/parameters/backends/cudaq/cudaq_cpu.py +30 -0
  184. luna_quantum/solve/parameters/backends/cudaq/cudaq_gpu.py +32 -0
  185. luna_quantum/solve/parameters/backends/dwave.py +17 -0
  186. luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
  187. luna_quantum/solve/parameters/backends/fda.py +17 -0
  188. luna_quantum/solve/parameters/backends/ibm.py +138 -0
  189. luna_quantum/solve/parameters/backends/qctrl.py +103 -0
  190. luna_quantum/solve/parameters/backends/zib.py +17 -0
  191. luna_quantum/solve/parameters/constants.py +11 -0
  192. luna_quantum/solve/parameters/errors.py +30 -0
  193. luna_quantum/solve/parameters/mixins/__init__.py +0 -0
  194. luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
  195. luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
  196. luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
  197. luna_quantum/solve/use_cases/__init__.py +119 -0
  198. luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
  199. luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
  200. luna_quantum/solve/use_cases/base.py +7 -0
  201. luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
  202. luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
  203. luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
  204. luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
  205. luna_quantum/solve/use_cases/exact_cover.py +51 -0
  206. luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
  207. luna_quantum/solve/use_cases/graph_coloring.py +42 -0
  208. luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
  209. luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
  210. luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
  211. luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
  212. luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
  213. luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
  214. luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
  215. luna_quantum/solve/use_cases/linear_regression.py +60 -0
  216. luna_quantum/solve/use_cases/lmwcs.py +84 -0
  217. luna_quantum/solve/use_cases/longest_path.py +50 -0
  218. luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
  219. luna_quantum/solve/use_cases/max2sat.py +54 -0
  220. luna_quantum/solve/use_cases/max3sat.py +55 -0
  221. luna_quantum/solve/use_cases/max_clique.py +60 -0
  222. luna_quantum/solve/use_cases/max_cut.py +48 -0
  223. luna_quantum/solve/use_cases/max_independent_set.py +37 -0
  224. luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
  225. luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
  226. luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
  227. luna_quantum/solve/use_cases/number_partitioning.py +32 -0
  228. luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
  229. luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
  230. luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
  231. luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
  232. luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
  233. luna_quantum/solve/use_cases/sensor_placement.py +58 -0
  234. luna_quantum/solve/use_cases/set_cover.py +56 -0
  235. luna_quantum/solve/use_cases/set_packing.py +54 -0
  236. luna_quantum/solve/use_cases/set_partitioning.py +52 -0
  237. luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
  238. luna_quantum/solve/use_cases/subset_sum.py +37 -0
  239. luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
  240. luna_quantum/solve/use_cases/traffic_flow.py +35 -0
  241. luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
  242. luna_quantum/solve/use_cases/type_aliases.py +9 -0
  243. luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
  244. luna_quantum/solve/usecases/__init__.py +45 -0
  245. luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
  246. luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
  247. luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
  248. luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
  249. luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
  250. luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
  251. luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
  252. luna_quantum/solve/usecases/model_save_usecase.py +63 -0
  253. luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
  254. luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
  255. luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
  256. luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
  257. luna_quantum/solve/usecases/solve_job_get_by_id_usecase.py +44 -0
  258. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +105 -0
  259. luna_quantum/transformations.py +18 -0
  260. luna_quantum/transformations.pyi +371 -0
  261. luna_quantum/translator.py +23 -0
  262. luna_quantum/translator.pyi +869 -0
  263. luna_quantum/util/__init__.py +0 -0
  264. luna_quantum/util/active_waiting.py +79 -0
  265. luna_quantum/util/class_patcher.py +164 -0
  266. luna_quantum/util/debug_info.py +52 -0
  267. luna_quantum/util/log_utils.py +187 -0
  268. luna_quantum/util/pretty_base.py +67 -0
  269. luna_quantum/util/pydantic_utils.py +38 -0
  270. luna_quantum/utils.py +3 -0
  271. luna_quantum/utils.pyi +67 -0
  272. luna_quantum-1.1.0.dist-info/METADATA +36 -0
  273. luna_quantum-1.1.0.dist-info/RECORD +276 -0
  274. luna_quantum-1.1.0.dist-info/WHEEL +4 -0
  275. luna_quantum-1.1.0.dist-info/licenses/LICENSE +176 -0
  276. luna_quantum-1.1.0.dist-info/licenses/NOTICE +13 -0
File without changes
@@ -0,0 +1,79 @@
1
+ import logging
2
+ from collections.abc import Callable
3
+ from time import sleep
4
+ from typing import ClassVar
5
+
6
+ from luna_quantum.util.log_utils import Logging
7
+
8
+
9
+ class ActiveWaiting:
10
+ """
11
+ Provides active waiting functionality using a customizable loop.
12
+
13
+ The `ActiveWaiting` class offers a static method to perform a loop with
14
+ a sleep interval that increases iteratively, allowing the user to
15
+ regularly check a condition and optionally perform an additional action.
16
+ """
17
+
18
+ _logger: ClassVar[logging.Logger] = Logging.get_logger(__name__)
19
+
20
+ @staticmethod
21
+ def run(
22
+ loop_check: Callable[[], bool],
23
+ loop_call: Callable[[], None] | None = None,
24
+ sleep_time_max: float = 60.0,
25
+ sleep_time_increment: float = 5.0,
26
+ sleep_time_initial: float = 5.0,
27
+ ) -> None:
28
+ """
29
+ Execute a loop that checks a condition and optionally performs an action.
30
+
31
+ This function executes a loop that repeatedly checks a condition using a
32
+ callback function. If provided, it will also execute another callback after
33
+ each sleep period. The sleep time increases incrementally up to a maximum
34
+ value, starting from an initial sleep time.
35
+
36
+ Parameters
37
+ ----------
38
+ loop_check : Callable[[], bool]
39
+ A callable function that returns a boolean. The loop will continue as
40
+ long as this callable returns True.
41
+ loop_call : Optional[Callable[[], None]]
42
+ An optional callable function to be executed after each sleep period.
43
+ Defaults to None.
44
+ sleep_time_max : float
45
+ The maximum sleep time between condition checks. Defaults to 60.0 seconds.
46
+ sleep_time_increment : float
47
+ The amount of time to increment the sleep period after each iteration.
48
+ Defaults to 5.0 seconds.
49
+ sleep_time_initial : float
50
+ The initial sleep time before the first condition check. Defaults to
51
+ 5.0 seconds. If invalid (< 0.0), it will be adjusted to the default.
52
+
53
+ Raises
54
+ ------
55
+ ValueError
56
+ If `sleep_time_initial`, `sleep_time_increment`, or `sleep_time_max` are
57
+ non-positive values where a positive value is required.
58
+ """
59
+ cur_sleep_time: float
60
+
61
+ if sleep_time_initial > 0.0:
62
+ cur_sleep_time = sleep_time_initial
63
+ else:
64
+ cur_sleep_time = 5.0
65
+ ActiveWaiting._logger.warning(
66
+ f"Invalid sleep_time_initial: {sleep_time_initial},"
67
+ f" setting it to default value {cur_sleep_time}"
68
+ )
69
+
70
+ while loop_check():
71
+ ActiveWaiting._logger.info(
72
+ f"Sleeping for {cur_sleep_time} seconds. "
73
+ f"Waiting and checking a function in a loop."
74
+ )
75
+ sleep(cur_sleep_time)
76
+ cur_sleep_time += sleep_time_increment
77
+ cur_sleep_time = min(cur_sleep_time, sleep_time_max)
78
+ if loop_call:
79
+ loop_call()
@@ -0,0 +1,164 @@
1
+ from collections.abc import Callable
2
+ from functools import wraps
3
+ from typing import Any, Literal, TypeVar
4
+
5
+ from luna_quantum.exceptions.patch_class_field_exists_error import (
6
+ PatchClassFieldExistsError,
7
+ )
8
+
9
+ T = TypeVar("T") # To represent the return type of the decorated function
10
+
11
+
12
+ def add_to_class(
13
+ class_: type[Any],
14
+ method_type: Literal["normal", "static", "class", "property"] = "normal",
15
+ ) -> Callable[[Callable[..., T]], Callable[..., T]]:
16
+ """
17
+ Add a function as a method into a specified class.
18
+
19
+ The decorator facilitates adding a function to a class as a method. The
20
+ method can be of type 'normal' (instance method), 'static', 'class', or
21
+ 'property'. The function metadata is preserved during this process.
22
+
23
+ Parameters
24
+ ----------
25
+ class_ : Type
26
+ The class to which the function will be added.
27
+
28
+ method_type : {"normal", "static", "class", "property"}, optional
29
+ The type of method to integrate into the class. Defaults to "normal".
30
+ - "normal": Adds the function as an instance-level method.
31
+ - "static": Adds the function as a static method.
32
+ - "class": Adds the function as a class-level method.
33
+ - "property": Adds the function as a property.
34
+
35
+ Returns
36
+ -------
37
+ Callable
38
+ A callable decorator that, when applied to a function, integrates it
39
+ as the specified method type into the class.
40
+
41
+ """
42
+
43
+ def decorator(func: Callable[..., T]) -> Callable[..., T]:
44
+ # Preserve function metadata
45
+ @wraps(func)
46
+ def wrapped_func(*args: Any, **kwargs: Any) -> T:
47
+ return func(*args, **kwargs)
48
+
49
+ # Add the function to the class based on the method type
50
+ if method_type == "static":
51
+ setattr(class_, func.__name__, staticmethod(func)) # Add as static method
52
+ elif method_type == "class":
53
+ setattr(class_, func.__name__, classmethod(func)) # Add as class method
54
+ elif method_type == "property":
55
+ setattr(class_, func.__name__, property(func)) # Add as property
56
+ else: # Default is normal (instance-level method)
57
+ setattr(class_, func.__name__, func)
58
+
59
+ return wrapped_func
60
+
61
+ return decorator
62
+
63
+
64
+ def patch_instance(class_: type[Any]) -> Callable[[Callable[..., T]], Callable[..., T]]:
65
+ """
66
+ Patch a class with a "normal" method.
67
+
68
+ This function acts as a decorator that adds a new method to the given class.
69
+ The newly added method behaves as a standard instance method, meaning it
70
+ has access to the instance (`self`) when called.
71
+
72
+ Parameters
73
+ ----------
74
+ class_: The class to which the method will be added.
75
+
76
+ Returns
77
+ -------
78
+ A decorator function that takes the method to be added as its argument.
79
+ """
80
+ return add_to_class(class_, "normal")
81
+
82
+
83
+ def patch_static(class_: type[Any]) -> Callable[[Callable[..., T]], Callable[..., T]]:
84
+ """
85
+ Patch a class with a "static" method.
86
+
87
+ This function acts as a decorator that adds a new static method to the given class.
88
+ The newly added static method does not require an instance of the class to be
89
+ called.
90
+
91
+ Parameters
92
+ ----------
93
+ class_: The class to which the static method will be added.
94
+
95
+ Returns
96
+ -------
97
+ A decorator function that takes the static method to be added as its argument.
98
+ """
99
+ return add_to_class(class_, "static")
100
+
101
+
102
+ def patch_class(class_: type[Any]) -> Callable[[Callable[..., T]], Callable[..., T]]:
103
+ """
104
+ Patch a class with a "class" method.
105
+
106
+ This function acts as a decorator that adds a new class method to the given class.
107
+ The newly added method will have access to the class itself (`cls`) when called.
108
+
109
+ Parameters
110
+ ----------
111
+ class_: The class to which the class method will be added.
112
+
113
+ Returns
114
+ -------
115
+ A decorator function that takes the class method to be added as its argument.
116
+ """
117
+ return add_to_class(class_, "class")
118
+
119
+
120
+ def patch_property(class_: type[Any]) -> Callable[[Callable[..., T]], Callable[..., T]]:
121
+ """
122
+ Patch a class with a "property" method.
123
+
124
+ This function acts as a decorator that adds a new property to the given class.
125
+ The decorator converts the given method into a readable property.
126
+
127
+ Parameters
128
+ ----------
129
+ class_: The class to which the property will be added.
130
+
131
+ Returns
132
+ -------
133
+ A decorator function that takes the method to be added as a property.
134
+ """
135
+ return add_to_class(class_, "property")
136
+
137
+
138
+ def patch_field_to_class(
139
+ class_: type[Any],
140
+ field_name: str,
141
+ default_value: Any = None, # noqa: ANN401 we dont know the type in the decorator
142
+ ) -> None:
143
+ """
144
+ Add a new field to a class.
145
+
146
+ This function allows adding a field with a default value to the given class.
147
+ If the field already exists in the class, a `PatchClassFieldExistsError` is raised.
148
+
149
+ Parameters
150
+ ----------
151
+ class_: The class to which the field will be added.
152
+ field_name: The name of the field to be added.
153
+ default_value: The default value to assign to the field (optional).
154
+
155
+ Raises
156
+ ------
157
+ PatchClassFieldExistsError
158
+ If the class already has a field with the given name.
159
+ """
160
+ if hasattr(class_, field_name):
161
+ raise PatchClassFieldExistsError(
162
+ class_name=class_.__name__, field_name=field_name
163
+ )
164
+ setattr(class_, field_name, default_value)
@@ -0,0 +1,52 @@
1
+ import platform
2
+ import sys
3
+ from logging import Logger
4
+
5
+ from rich import box
6
+ from rich.table import Table
7
+
8
+ from luna_quantum._core import __aq_model_version__, __luna_quantum_version__
9
+ from luna_quantum.util.log_utils import Logging
10
+
11
+ _logger: Logger = Logging.get_logger(__name__)
12
+ _pkg_list: list[str] = ["numpy", "pydantic"]
13
+
14
+
15
+ def debug_info() -> None:
16
+ """Print debug information."""
17
+ python_version = (
18
+ f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
19
+ )
20
+ os_info = f"{platform.system()} {platform.release()}"
21
+
22
+ # Get additional system information
23
+ architecture = platform.machine()
24
+ python_implementation = platform.python_implementation()
25
+
26
+ table = Table(
27
+ title="Luna Debug Information",
28
+ title_justify="left",
29
+ caption="System and environment details for troubleshooting",
30
+ box=box.MARKDOWN,
31
+ )
32
+ table.add_column("Property", style="cyan", no_wrap=True)
33
+ table.add_column("Version", style="green", no_wrap=True)
34
+
35
+ # Add rows to the table
36
+ table.add_row("Luna Quantum", f"{__luna_quantum_version__}")
37
+ table.add_row("AqModel", f"{__aq_model_version__}")
38
+ table.add_row("Python", f"{python_version}")
39
+ table.add_row("Python Implementation", f"{python_implementation}")
40
+ table.add_row("Operating System", f"{os_info}")
41
+ table.add_row("Architecture", f"{architecture}")
42
+
43
+ for package in _pkg_list:
44
+ try:
45
+ module = __import__(package)
46
+ version = getattr(module, "__version__", "pkg found, version unknown")
47
+ table.add_row(package, version)
48
+ except ImportError:
49
+ table.add_row(package, "pkg not found")
50
+
51
+ # Print the table to console
52
+ Logging.get_console().print(table)
@@ -0,0 +1,187 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from contextlib import contextmanager
5
+ from functools import wraps
6
+ from typing import TYPE_CHECKING, ParamSpec, TypeVar
7
+
8
+ from rich.console import Console
9
+ from rich.logging import RichHandler
10
+ from rich.progress import Progress, SpinnerColumn, TaskID, TextColumn
11
+ from rich.theme import Theme
12
+
13
+ from luna_quantum.config import config
14
+
15
+ if TYPE_CHECKING:
16
+ from collections.abc import Callable, Generator
17
+
18
+
19
+ P = ParamSpec("P")
20
+ T = TypeVar("T")
21
+
22
+
23
+ class Logging:
24
+ """Utilities for configuring and accessing Luna SDK loggers.
25
+
26
+ This class provides static methods to:
27
+ - Set and retrieve the global logging level for SDK components
28
+ - Create and configure loggers with Rich formatting
29
+ - Manage consistent logging behavior across the SDK
30
+ """
31
+
32
+ @staticmethod
33
+ def is_process_bar_shown() -> bool:
34
+ """
35
+ Return whether to use a process bar for progress bars.
36
+
37
+ Returns
38
+ -------
39
+ bool
40
+ Returns whether to use a process bar for progress bars.
41
+ """
42
+ return (
43
+ not config.LUNA_LOG_DISABLE_SPINNER
44
+ and Logging.get_level() != logging.NOTSET
45
+ )
46
+
47
+ @staticmethod
48
+ def set_level(log_level: int) -> None:
49
+ """Set the logging level for all SDK loggers.
50
+
51
+ Parameters
52
+ ----------
53
+ log_level : int
54
+ Logging level to set (e.g., logging.DEBUG, logging.INFO)
55
+ """
56
+ config.LUNA_LOG_DEFAULT_LEVEL = logging.getLevelName(log_level)
57
+
58
+ for logger_name in logging.root.manager.loggerDict:
59
+ if logger_name.startswith("luna_quantum"): # Only modify SDK loggers
60
+ logging.getLogger(logger_name).setLevel(log_level)
61
+
62
+ @staticmethod
63
+ def get_level() -> int:
64
+ """Return the current logging level for the SDK.
65
+
66
+ Returns
67
+ -------
68
+ int
69
+ Current logging level as defined in the logging module
70
+ (e.g., logging.DEBUG, logging.INFO, etc.)
71
+ """
72
+ return logging._nameToLevel.get(config.LUNA_LOG_DEFAULT_LEVEL, logging.INFO) # noqa: SLF001 #No other way to map these log levels.
73
+
74
+ @staticmethod
75
+ def get_console() -> Console:
76
+ """Return a Rich console instance for use in logging."""
77
+ custom_theme = Theme(
78
+ {
79
+ "logging.level.debug": "bright_blue",
80
+ "logging.level.info": "bright_green",
81
+ "logging.level.warning": "bold bright_yellow",
82
+ "logging.level.error": "bold bright_red",
83
+ "logging.level.critical": "bold bright_magenta",
84
+ }
85
+ )
86
+ return Console(theme=custom_theme)
87
+
88
+ @staticmethod
89
+ def get_logger(name: str) -> logging.Logger:
90
+ """Get a logger with the specified name and set up a RichHandler for it.
91
+
92
+ Parameters
93
+ ----------
94
+ name : str
95
+ Name of the logger to retrieve or create
96
+
97
+ Returns
98
+ -------
99
+ logging.Logger
100
+ Configured logger instance with appropriate handlers
101
+ """
102
+ logger = logging.getLogger(name)
103
+ logger.setLevel(Logging.get_level())
104
+ logger.propagate = False
105
+
106
+ if logger.hasHandlers():
107
+ return logger
108
+
109
+ handler = RichHandler(
110
+ console=Logging.get_console(),
111
+ rich_tracebacks=True,
112
+ show_time=True,
113
+ show_level=True,
114
+ show_path=False,
115
+ log_time_format="%Y-%m-%d %H:%M:%S", # ISO 8601 format
116
+ )
117
+
118
+ logger.addHandler(handler)
119
+ return logger
120
+
121
+
122
+ @contextmanager
123
+ def progress_bar(
124
+ total: int | None, desc: str = "", unit: str = "steps"
125
+ ) -> Generator[tuple[Progress, TaskID]]:
126
+ """Create a progress bar using Rich as a context manager.
127
+
128
+ Parameters
129
+ ----------
130
+ total: int | None
131
+ Total number of steps in the progress bar
132
+ desc: str
133
+ Description text to display next to the progress bar
134
+ unit: str
135
+ Unit label for the progress steps, by default "steps"
136
+
137
+ Yields
138
+ ------
139
+ tuple[Progress, TaskID]
140
+ A tuple containing the Progress object and task ID for updating
141
+ """
142
+ with Progress(
143
+ SpinnerColumn(),
144
+ TextColumn("[progress.description]{task.description}"),
145
+ console=Console(
146
+ theme=Theme(
147
+ {
148
+ "bar.back": "blue",
149
+ "bar.pulse": "bright_blue",
150
+ }
151
+ )
152
+ ),
153
+ transient=True,
154
+ disable=not Logging.is_process_bar_shown(),
155
+ ) as progress:
156
+ task = progress.add_task(f"[blue]{desc}", total=total, unit=unit)
157
+ yield progress, task # Yield both progress and task for updates
158
+
159
+
160
+ def progress(
161
+ total: int | None,
162
+ desc: str = "",
163
+ unit: str = "steps",
164
+ ) -> Callable[[Callable[P, T]], Callable[P, T]]:
165
+ """
166
+ Decorate a func with a progress-bar.
167
+
168
+ Parameters
169
+ ----------
170
+ total: int | None
171
+ Total number of steps in the progress bar
172
+ desc: str
173
+ Description text to display next to the progress bar
174
+ unit: str
175
+ Unit label for the progress steps, by default "steps"
176
+
177
+ """
178
+
179
+ def decorated_func(func: Callable[P, T]) -> Callable[P, T]:
180
+ @wraps(func)
181
+ def decorator(*args: P.args, **kwargs: P.kwargs) -> T:
182
+ with progress_bar(total=total, desc=desc, unit=unit):
183
+ return func(*args, **kwargs)
184
+
185
+ return decorator
186
+
187
+ return decorated_func
@@ -0,0 +1,67 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+
5
+ from pydantic import BaseModel
6
+
7
+
8
+ class PrettyBase(BaseModel):
9
+ """Helper class to implement pretty print."""
10
+
11
+ def _pretty_print(self, data: dict, indent: int = 0) -> str: # type: ignore[type-arg]
12
+ """Return nested dictionaries in a readable YAML-inspired format as a string.
13
+
14
+ This format enhances human readability by using a YAML-like structured style.
15
+
16
+ Parameters
17
+ ----------
18
+ data: dict
19
+ indent: int
20
+ """
21
+ output = ""
22
+ for key, value in data.items():
23
+ output += " " * indent + str(key) + ":"
24
+ if isinstance(value, dict):
25
+ if value == {}:
26
+ output += " {}\n"
27
+ else:
28
+ output += "\n"
29
+ output += self._pretty_print(value, indent + 1)
30
+ elif isinstance(value, datetime):
31
+ output += f" {value.strftime('%Y-%m-%d %H:%M:%S (%Z)')}\n"
32
+ else:
33
+ output += f" {value}\n"
34
+ return output
35
+
36
+ def __str__(self) -> str:
37
+ """Override the default object string representation."""
38
+ data = self.model_dump()
39
+
40
+ return self._pretty_print(data)
41
+
42
+ @property
43
+ def head(self) -> str:
44
+ """Print a truncated version of the pretty print console representation."""
45
+ limit = 20
46
+
47
+ def truncate(data: dict, limit: int) -> tuple[dict, bool]: # type: ignore[type-arg]
48
+ if data is None:
49
+ return None, False
50
+
51
+ if isinstance(data, dict):
52
+ d = {
53
+ k: truncate(v, limit)[0]
54
+ for i, (k, v) in enumerate(data.items())
55
+ if i < limit
56
+ }
57
+ return d, len(data) > limit
58
+ if isinstance(data, list):
59
+ d = data[:limit]
60
+ return d, len(data) > limit
61
+ return data, False
62
+
63
+ data = self.model_dump()
64
+
65
+ data_truncated, _ = truncate(data, limit)
66
+
67
+ return self._pretty_print(data_truncated)
@@ -0,0 +1,38 @@
1
+ from typing import TypeVar
2
+
3
+ from pydantic import BaseModel
4
+
5
+ T = TypeVar("T", bound=BaseModel)
6
+
7
+
8
+ class PydanticUtils:
9
+ """A utility class for operations on Pydantic models."""
10
+
11
+ @staticmethod
12
+ def update_model(to_update: T, other_model: T) -> None:
13
+ """
14
+ Update the attributes of a given pydantic model.
15
+
16
+ This function works by iterating over the attributes
17
+ of the second model (provided as input) and assigns the corresponding values
18
+ to the attributes of the first model.
19
+
20
+ Parameters
21
+ ----------
22
+ to_update : T
23
+ The model instance whose attributes need to be updated. This instance
24
+ will have its attributes overridden with the corresponding values from
25
+ the other model instance.
26
+ other_model : T
27
+ The model instance providing the new values for the update. Its
28
+ attributes are used to overwrite the attributes of the `to_update`
29
+ instance.
30
+
31
+ Returns
32
+ -------
33
+ None
34
+ This function does not return a value. Instead, it updates the
35
+ `to_update` instance in place.
36
+ """
37
+ for key, value in other_model.model_dump().items():
38
+ setattr(to_update, key, value)
luna_quantum/utils.py ADDED
@@ -0,0 +1,3 @@
1
+ """Utility module containing convenience functions."""
2
+
3
+ from ._core.utils import * # type: ignore[reportMissingImports] # noqa: F403
luna_quantum/utils.pyi ADDED
@@ -0,0 +1,67 @@
1
+ from collections.abc import Generator, Iterable
2
+ from typing import overload
3
+
4
+ from . import Expression, Variable
5
+
6
+ @overload
7
+ def quicksum(iterable: Generator[Expression], /) -> Expression: ...
8
+ @overload
9
+ def quicksum(iterable: Generator[Variable], /) -> Expression: ...
10
+ @overload
11
+ def quicksum(iterable: Generator[int], /) -> Expression: ...
12
+ @overload
13
+ def quicksum(iterable: Generator[float], /) -> Expression: ...
14
+ @overload
15
+ def quicksum(
16
+ iterable: Generator[Expression], /, start: Expression | None = None
17
+ ) -> Expression: ...
18
+ @overload
19
+ def quicksum(
20
+ iterable: Generator[Variable], /, start: Expression | None = None
21
+ ) -> Expression: ...
22
+ @overload
23
+ def quicksum(
24
+ iterable: Generator[int], /, start: Expression | None = None
25
+ ) -> Expression: ...
26
+ @overload
27
+ def quicksum(
28
+ iterable: Generator[float], /, start: Expression | None = None
29
+ ) -> Expression: ...
30
+ @overload
31
+ def quicksum(
32
+ iterable: Generator[Expression | Variable | float | int],
33
+ /,
34
+ start: Expression | None = None,
35
+ ) -> Expression: ...
36
+ @overload
37
+ def quicksum(iterable: Iterable[Expression], /) -> Expression: ...
38
+ @overload
39
+ def quicksum(iterable: Iterable[Variable], /) -> Expression: ...
40
+ @overload
41
+ def quicksum(iterable: Iterable[int], /) -> Expression: ...
42
+ @overload
43
+ def quicksum(iterable: Iterable[float], /) -> Expression: ...
44
+ @overload
45
+ def quicksum(
46
+ iterable: Iterable[Expression], /, start: Expression | None = None
47
+ ) -> Expression: ...
48
+ @overload
49
+ def quicksum(
50
+ iterable: Iterable[Variable], /, start: Expression | None = None
51
+ ) -> Expression: ...
52
+ @overload
53
+ def quicksum(
54
+ iterable: Iterable[int], /, start: Expression | None = None
55
+ ) -> Expression: ...
56
+ @overload
57
+ def quicksum(
58
+ iterable: Iterable[float], /, start: Expression | None = None
59
+ ) -> Expression: ...
60
+ @overload
61
+ def quicksum(
62
+ iterable: Iterable[Expression | Variable | float | int],
63
+ /,
64
+ start: Expression | None = None,
65
+ ) -> Expression: ...
66
+
67
+ __all__ = ["quicksum"]