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
@@ -0,0 +1,148 @@
1
+ """Utility module for internals."""
2
+
3
+ import sys
4
+
5
+ if sys.version_info < (3, 13):
6
+ from warnings import warn
7
+
8
+ class DeprecationWarning(Warning): ... # noqa: A001
9
+
10
+ class deprecated: # noqa: N801
11
+ """Indicate that a class, function or overload is deprecated.
12
+
13
+ When this decorator is applied to an object, the type checker
14
+ will generate a diagnostic on usage of the deprecated object.
15
+
16
+ Usage:
17
+
18
+ @deprecated("Use B instead")
19
+ class A:
20
+ pass
21
+
22
+ @deprecated("Use g instead")
23
+ def f():
24
+ pass
25
+
26
+ @overload
27
+ @deprecated("int support is deprecated")
28
+ def g(x: int) -> int: ...
29
+ @overload
30
+ def g(x: str) -> int: ...
31
+
32
+ The warning specified by *category* will be emitted at runtime
33
+ on use of deprecated objects. For functions, that happens on calls;
34
+ for classes, on instantiation and on creation of subclasses.
35
+ If the *category* is ``None``, no warning is emitted at runtime.
36
+ The *stacklevel* determines where the
37
+ warning is emitted. If it is ``1`` (the default), the warning
38
+ is emitted at the direct caller of the deprecated object; if it
39
+ is higher, it is emitted further up the stack.
40
+ Static type checker behavior is not affected by the *category*
41
+ and *stacklevel* arguments.
42
+
43
+ The deprecation message passed to the decorator is saved in the
44
+ ``__deprecated__`` attribute on the decorated object.
45
+ If applied to an overload, the decorator
46
+ must be after the ``@overload`` decorator for the attribute to
47
+ exist on the overload as returned by ``get_overloads()``.
48
+
49
+ See PEP 702 for details.
50
+
51
+ """
52
+
53
+ def __init__(
54
+ self,
55
+ message: str,
56
+ /,
57
+ *,
58
+ category: type[Warning] | None = DeprecationWarning, # noqa: PYI011,RUF100
59
+ stacklevel: int = 1,
60
+ ) -> None:
61
+ if not isinstance(message, str):
62
+ raise TypeError( # noqa: TRY003
63
+ f"Expected an object of type str for 'message', not {type(message).__name__!r}" # noqa: E501
64
+ )
65
+ self.message = message
66
+ self.category = category
67
+ self.stacklevel = stacklevel
68
+
69
+ def __call__(self, arg, /): # noqa: C901,ANN001,ANN204
70
+ # Make sure the inner functions created below don't
71
+ # retain a reference to self.
72
+ msg = self.message
73
+ category = self.category
74
+ stacklevel = self.stacklevel
75
+ if category is None:
76
+ arg.__deprecated__ = msg
77
+ return arg
78
+ elif isinstance(arg, type): # noqa: RET505
79
+ import functools # noqa: PLC0415
80
+ from types import MethodType # noqa: PLC0415
81
+
82
+ original_new = arg.__new__
83
+
84
+ @functools.wraps(original_new)
85
+ def __new__(cls, /, *args, **kwargs): # noqa: N807,ANN001,ANN202,ANN003,ANN002
86
+ if cls is arg:
87
+ warn(msg, category=category, stacklevel=stacklevel + 1)
88
+ if original_new is not object.__new__:
89
+ return original_new(cls, *args, **kwargs)
90
+ # Mirrors a similar check in object.__new__.
91
+ elif cls.__init__ is object.__init__ and (args or kwargs): # noqa: RET505
92
+ raise TypeError(f"{cls.__name__}() takes no arguments") # noqa: TRY003
93
+ else:
94
+ return original_new(cls)
95
+
96
+ arg.__new__ = staticmethod(__new__)
97
+
98
+ original_init_subclass = arg.__init_subclass__
99
+ # We need slightly different behavior if __init_subclass__
100
+ # is a bound method (likely if it was implemented in Python)
101
+ if isinstance(original_init_subclass, MethodType):
102
+ original_init_subclass = original_init_subclass.__func__
103
+
104
+ @functools.wraps(original_init_subclass)
105
+ def __init_subclass__(*args, **kwargs): # noqa: ANN002,ANN202,ANN003,N807
106
+ warn(msg, category=category, stacklevel=stacklevel + 1)
107
+ return original_init_subclass(*args, **kwargs)
108
+
109
+ arg.__init_subclass__ = classmethod(__init_subclass__)
110
+ # Or otherwise, which likely means it's a builtin such as
111
+ # object's implementation of __init_subclass__.
112
+ else:
113
+
114
+ @functools.wraps(original_init_subclass)
115
+ def __init_subclass__(*args, **kwargs): # noqa: ANN202,ANN002,ANN003,N807
116
+ warn(msg, category=category, stacklevel=stacklevel + 1)
117
+ return original_init_subclass(*args, **kwargs)
118
+
119
+ arg.__init_subclass__ = __init_subclass__
120
+
121
+ arg.__deprecated__ = __new__.__deprecated__ = msg
122
+ __init_subclass__.__deprecated__ = msg
123
+ return arg
124
+ elif callable(arg):
125
+ import functools # noqa: PLC0415
126
+ import inspect # noqa: PLC0415
127
+
128
+ @functools.wraps(arg)
129
+ def wrapper(*args, **kwargs): # noqa: ANN002,ANN003,ANN202
130
+ warn(msg, category=category, stacklevel=stacklevel + 1)
131
+ return arg(*args, **kwargs)
132
+
133
+ if inspect.iscoroutinefunction(arg):
134
+ wrapper = inspect.markcoroutinefunction(wrapper)
135
+
136
+ arg.__deprecated__ = wrapper.__deprecated__ = msg
137
+ return wrapper
138
+ else:
139
+ raise TypeError( # noqa: TRY003
140
+ "@deprecated decorator with non-None category must be applied to "
141
+ f"a class or callable, not {arg!r}"
142
+ )
143
+
144
+ else:
145
+ from warnings import deprecated
146
+
147
+
148
+ __all__ = ["deprecated"]
@@ -0,0 +1,20 @@
1
+ import sys
2
+
3
+ if sys.version_info < (3, 13): # noqa: PYI066
4
+ class DeprecationWarning(Warning): ... # noqa: A001
5
+
6
+ class deprecated: # noqa: N801
7
+ def __init__(
8
+ self,
9
+ message: str,
10
+ /,
11
+ *,
12
+ category: type[Warning] | None = ...,
13
+ stacklevel: int = 1,
14
+ ) -> None: ...
15
+ def __call__(self, arg, /): ... # noqa: ANN001,ANN204
16
+
17
+ else:
18
+ from warnings import deprecated
19
+
20
+ __all__ = ["deprecated"]
@@ -0,0 +1 @@
1
+ from luna_quantum.solve.parameters.algorithms import * # noqa: F403
@@ -0,0 +1,3 @@
1
+ from .model import Model
2
+
3
+ __all__ = ["Model"]
@@ -0,0 +1,184 @@
1
+ from luna_quantum._core import Model, Solution
2
+ from luna_quantum.client.interfaces.services.luna_solve_i import ILunaSolve
3
+ from luna_quantum.factories.luna_solve_client_factory import LunaSolveClientFactory
4
+ from luna_quantum.factories.usecase_factory import UseCaseFactory
5
+ from luna_quantum.solve.domain.model_metadata import ModelMetadata
6
+ from luna_quantum.solve.domain.solve_job import SolveJob
7
+ from luna_quantum.util.class_patcher import (
8
+ patch_instance,
9
+ patch_property,
10
+ patch_static,
11
+ )
12
+
13
+
14
+ @patch_property(Model)
15
+ def metadata(self: Model) -> ModelMetadata | None:
16
+ """
17
+ Return metadata for the current Model instance.
18
+
19
+ If metadata is cached and corresponds to the current hash, returns the cached
20
+ metadata. Otherwise, retrieves metadata via a client and updates the cache.
21
+
22
+ Parameters
23
+ ----------
24
+ self
25
+ Instance of Model.
26
+
27
+ Returns
28
+ -------
29
+ Optional[ModelMetadata]
30
+ Metadata for the current Model instance, or None if an error occurs or
31
+ metadata cannot be retrieved.
32
+ """
33
+ _hash = self.__hash__()
34
+ if (
35
+ "metadata" in self._metadata # type: ignore[attr-defined]
36
+ and "hash" in self._metadata # type: ignore[attr-defined]
37
+ and self._metadata["hash"] == _hash # type: ignore[attr-defined]
38
+ ):
39
+ return self._metadata["metadata"] # type: ignore # noqa: PGH003 # Patched Model
40
+ client = LunaSolveClientFactory.get_client(
41
+ None
42
+ ) # TODO(Llewellyn): is there a way to let the user overwrite # noqa: FIX002
43
+ # set the client here
44
+ try:
45
+ _metadata = UseCaseFactory.model_load_metadata_by_hash(client=client).__call__(
46
+ model_hash=_hash
47
+ )
48
+ except Exception:
49
+ _metadata = None
50
+ self._metadata["metadata"] = _metadata # type: ignore # noqa: PGH003 # Patched Model
51
+ self._metadata["hash"] = _hash # type: ignore # noqa: PGH003 # Patched Model
52
+
53
+ return _metadata
54
+
55
+
56
+ @patch_static(Model)
57
+ def load_luna(model_id: str, client: ILunaSolve | str | None = None) -> Model:
58
+ """
59
+ Load an AQ model using a specific model ID.
60
+
61
+ This function retrieves an AQ model from a client obj. The client can either be
62
+ provided directly or created dynamically if not specified.
63
+
64
+ Parameters
65
+ ----------
66
+ model_id : str
67
+ The identifier of the model that needs to be loaded.
68
+ client : Optional[Union[ILunaSolve, str]]
69
+ The client to use for loading the model. If not provided, a client
70
+ will be created automatically.
71
+
72
+ Returns
73
+ -------
74
+ Model
75
+ The AQ model that was successfully loaded.
76
+ """
77
+ client = LunaSolveClientFactory.get_client(client=client)
78
+ return UseCaseFactory.model_load_by_id(client=client).__call__(model_id=model_id)
79
+
80
+
81
+ @patch_instance(Model)
82
+ def save_luna(self: Model, client: ILunaSolve | str | None = None) -> None:
83
+ """
84
+ Save the model and update its metadata and hash.
85
+
86
+ This function saves the current state of the model using the provided client or
87
+ default client obtained from `ClientFactory`. It also updates the local `metadata`
88
+ attributes of the model after saving.
89
+
90
+ Parameters
91
+ ----------
92
+ self : Model
93
+ The instance of the Model class.
94
+ client : Optional[Union[ILunaSolve, str]], default=None
95
+ The client to facilitate saving the model. Can be an instance of `ILunaSolve`,
96
+ a string representing the client, or left as None to use the default client.
97
+
98
+ Returns
99
+ -------
100
+ None
101
+ This function does not return any values.
102
+
103
+ """
104
+ client = LunaSolveClientFactory.get_client(client=client)
105
+ self._metadata["metadata"] = UseCaseFactory.model_save(client=client).__call__(self) # type: ignore # noqa: PGH003 # Patched Model
106
+ self._metadata["hash"] = self.__hash__() # type: ignore[attr-defined]
107
+
108
+
109
+ @patch_instance(Model)
110
+ def delete_luna(self: Model, client: ILunaSolve | str | None = None) -> None:
111
+ """
112
+ Delete the Luna instance of the Model.
113
+
114
+ Ensure the Model instance is removed properly using the provided client or the
115
+ default client.
116
+
117
+ Parameters
118
+ ----------
119
+ self : Model
120
+ The instance of the model to be deleted.
121
+ client : Optional[Union[ILunaSolve, str]], optional
122
+ The client used to connect to the service. If not provided, the default
123
+ client is used.
124
+
125
+ Returns
126
+ -------
127
+ None
128
+ """
129
+ client = LunaSolveClientFactory.get_client(client=client)
130
+ UseCaseFactory.model_delete(client=client).__call__(self)
131
+
132
+
133
+ @patch_instance(Model)
134
+ def load_solutions(
135
+ self: Model, client: ILunaSolve | str | None = None
136
+ ) -> list[Solution]:
137
+ """
138
+ Load solutions for an Model.
139
+
140
+ Fetch and return the list of all solutions for the patched Model
141
+ using the provided client or the default client.
142
+
143
+ Parameters
144
+ ----------
145
+ self : Model
146
+ The Model for which solutions are to be loaded.
147
+ client : Optional[Union[ILunaSolve, str]], optional
148
+ The client used to interact and retrieve model solutions. If not provided,
149
+ a default client will be created using the `ClientFactory`.
150
+
151
+ Returns
152
+ -------
153
+ List[IAqSolution]
154
+ A list of IAqSolution instances containing the solutions.
155
+
156
+ """
157
+ client = LunaSolveClientFactory.get_client(client=client)
158
+ return UseCaseFactory.model_get_solution(client=client).__call__(self)
159
+
160
+
161
+ @patch_instance(Model)
162
+ def load_solve_jobs(
163
+ self: Model, client: ILunaSolve | str | None = None
164
+ ) -> list[SolveJob]:
165
+ """
166
+ Load and return a list of SolveJob objects for the Model instance.
167
+
168
+ Parameters
169
+ ----------
170
+ self : Model
171
+ The instance of the Model for which solve jobs need to be loaded.
172
+ client : Optional[Union[ILunaSolve, str]], optional
173
+ The client object or client type for fetching solve jobs, by default None.
174
+
175
+ Returns
176
+ -------
177
+ List[SolveJob]
178
+ A list of SolveJob objects related to the Model instance.
179
+ """
180
+ client = LunaSolveClientFactory.get_client(client=client)
181
+ return UseCaseFactory.model_get_solve_job(client=client).__call__(self)
182
+
183
+
184
+ __all__ = ["Model"]
@@ -0,0 +1 @@
1
+ from luna_quantum.solve.parameters.backends import * # noqa: F403
File without changes
@@ -0,0 +1,4 @@
1
+ from luna_quantum.client.controllers.luna_q import LunaQ
2
+ from luna_quantum.client.controllers.luna_solve import LunaSolve
3
+
4
+ __all__ = ["LunaQ", "LunaSolve"]
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ from importlib.metadata import version
4
+ from typing import Any
5
+
6
+ import httpx
7
+ from httpx import Client, Response
8
+
9
+ from luna_quantum.client.error.timeout_error import LunaTimeoutError
10
+ from luna_quantum.client.error.utils.http_error_utils import HttpErrorUtils
11
+
12
+
13
+ class LunaHTTPClient(Client):
14
+ """
15
+ Luna HTTP client.
16
+
17
+ Mainly used to set custom headers.
18
+ """
19
+
20
+ _version: str = version("luna-quantum")
21
+
22
+ _user_agent: str = f"LunaSDK/{_version}"
23
+
24
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
25
+ super().__init__(*args, **kwargs)
26
+
27
+ self.headers["User-Agent"] = self._user_agent
28
+
29
+ def request(self, *args: Any, **kwargs: Any) -> Response:
30
+ """Send request to Luna platform."""
31
+ try:
32
+ response: Response = super().request(*args, **kwargs)
33
+ except httpx.TimeoutException:
34
+ # Handle all possible in httpx timeout exceptions
35
+ raise LunaTimeoutError from None
36
+ HttpErrorUtils.check_for_error(response)
37
+ return response
@@ -0,0 +1,256 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from abc import abstractmethod
5
+ from contextlib import suppress
6
+ from enum import Enum
7
+ from http import HTTPStatus
8
+ from typing import TYPE_CHECKING, ClassVar
9
+
10
+ import httpx
11
+ from httpx import HTTPStatusError, Request, Response
12
+
13
+ from luna_quantum.client.controllers.luna_http_client import LunaHTTPClient
14
+ from luna_quantum.client.error.luna_api_key_invalid_error import LunaApiKeyInvalidError
15
+ from luna_quantum.client.error.luna_api_key_missing_error import LunaApiKeyMissingError
16
+ from luna_quantum.client.error.utils.http_error_utils import HttpErrorUtils
17
+ from luna_quantum.client.interfaces.services.service_i import IService
18
+ from luna_quantum.client.rest_client.users_rest_client import UsersRestClient
19
+
20
+ if TYPE_CHECKING:
21
+ from collections.abc import Generator
22
+
23
+
24
+ class LunaPrefixEnum(str, Enum):
25
+ """Enumeration of Luna services."""
26
+
27
+ LUNA_SOLVE = "luna-solve"
28
+ LUNA_Q = "luna-q"
29
+
30
+
31
+ def check_httpx_exceptions(response: Response) -> None:
32
+ """
33
+ Check if response contains errors from the server.
34
+
35
+ This function examines the HTTP response and raises appropriate SDK exceptions
36
+ if error conditions are detected.
37
+
38
+ Parameters
39
+ ----------
40
+ response: Response
41
+ The HTTP response object to be examined for error conditions.
42
+ """
43
+ HttpErrorUtils.check_for_error(response)
44
+
45
+
46
+ class APIKeyAuth(httpx.Auth): # noqa: PLW1641
47
+ """API key authentication method for luna platform."""
48
+
49
+ def __init__(self, token: str) -> None:
50
+ self.token = token
51
+
52
+ self.dev_header_value = os.getenv("LUNA_DEV_EXTRA_HEADER_VALUE", None)
53
+ self.dev_header_name = os.getenv("LUNA_DEV_EXTRA_HEADER_NAME", None)
54
+
55
+ def auth_flow(self, request: Request) -> Generator[Request, Response]:
56
+ """
57
+ Authenticate a request to Luna platform.
58
+
59
+ Parameters
60
+ ----------
61
+ request: Request
62
+ Request that needs to be authenticated.
63
+ """
64
+ request.headers["Luna-API-Key"] = self.token
65
+
66
+ if self.dev_header_name and self.dev_header_value:
67
+ request.headers[self.dev_header_name] = self.dev_header_value
68
+ yield request
69
+
70
+ def __eq__(self, other: object) -> bool:
71
+ """
72
+ Check if the object is equal to the current instance.
73
+
74
+ Parameters
75
+ ----------
76
+ other: object
77
+ Object to compare with the current instance.
78
+
79
+ Returns
80
+ -------
81
+ bool:
82
+ True if the object is equal to the current instance, False otherwise.
83
+
84
+ """
85
+ if self is other:
86
+ return True
87
+ if not isinstance(other, APIKeyAuth):
88
+ return False
89
+ return (
90
+ self.token == other.token
91
+ and self.dev_header_name == other.dev_header_name
92
+ and self.dev_header_value == other.dev_header_value
93
+ )
94
+
95
+
96
+ class LunaPlatformClient(IService):
97
+ """Luna platform REST client."""
98
+
99
+ _base_url: str
100
+
101
+ _httpx_client: httpx.Client
102
+ _api_key: ClassVar[str | None] = None
103
+ _timeout: float | None = None
104
+
105
+ @property
106
+ def client(self) -> httpx.Client:
107
+ """
108
+ Return httpx client.
109
+
110
+ Returns
111
+ -------
112
+ httpx.Client
113
+ """
114
+ return self._httpx_client
115
+
116
+ @classmethod
117
+ @abstractmethod
118
+ def get_api(cls) -> LunaPrefixEnum:
119
+ """Return the api of the client."""
120
+
121
+ def __init__(
122
+ self,
123
+ api_key: str | None = None,
124
+ base_url: str | None = None,
125
+ timeout: float | None = 240.0,
126
+ ) -> None:
127
+ """
128
+ LunaPlatformClient is a main entrypoint of the SDK.
129
+
130
+ All the operations with entities should be processed using an instance of
131
+ LunaPlatformClient.
132
+
133
+ Parameters
134
+ ----------
135
+ api: LunaPrefixEnum
136
+ Current API with which luna client is working. Can be luna-solve or luna-q.
137
+ api_key: Optional[str]
138
+ Api key to be used to authorize. Default none.
139
+ If its none then the key set by the `authorize` method will be used.
140
+ base_url:
141
+ Base API URL.
142
+ If you want to use API not on your local PC then change it.
143
+ You can do that by setting the environment variable LUNA_BASE_URL.
144
+ Default value https://api.aqarios.com.
145
+ timeout:
146
+ Default timeout in seconds for the requests via the LunaQ client. `None`
147
+ means that the SDK uses no timeouts. Note that either way the Luna platform
148
+ itself will time out after 240 seconds.
149
+ Default: 240.0
150
+ """
151
+ self._base_url = self._get_base_url(base_url)
152
+ self._timeout = timeout
153
+
154
+ api_key = self._get_api_key(api_key)
155
+
156
+ self.dev_header_value = os.getenv("LUNA_DEV_EXTRA_HEADER_VALUE", None)
157
+ self.dev_header_name = os.getenv("LUNA_DEV_EXTRA_HEADER_NAME", None)
158
+
159
+ self._httpx_client = LunaHTTPClient(
160
+ auth=APIKeyAuth(api_key),
161
+ base_url=self._base_url,
162
+ follow_redirects=True,
163
+ timeout=self._timeout,
164
+ event_hooks={"response": [check_httpx_exceptions]},
165
+ )
166
+
167
+ self._authenticate()
168
+
169
+ def _get_api_key(self, api_key: str | None = None) -> str:
170
+ """
171
+ Retrieve the API key for authentication.
172
+
173
+ Get the API key from provided arguments, class-specific key, or environment
174
+ variables. Raises an error if no API key is available.
175
+
176
+ Parameters
177
+ ----------
178
+ api_key : str or None, optional
179
+ An API key string if provided.
180
+
181
+ Returns
182
+ -------
183
+ str
184
+ The API key to be used for authentication.
185
+
186
+ Raises
187
+ ------
188
+ LunaApiKeyMissingError
189
+ If no API key is available from any source.
190
+ """
191
+ if api_key:
192
+ auth_key = api_key
193
+ elif self.__class__._api_key: # noqa: SLF001 Use here self.__class__ so that LunaSolve and LunaQ can have different api keys set
194
+ auth_key = self.__class__._api_key # noqa: SLF001 Use here self.__class__ so that LunaSolve and LunaQ can have different api keys set
195
+ elif key := os.getenv("LUNA_API_KEY", None):
196
+ auth_key = key
197
+ else:
198
+ raise LunaApiKeyMissingError
199
+ return auth_key
200
+
201
+ def _get_base_url(self, base_url: str | None = None) -> str:
202
+ """
203
+ Get the base url.
204
+
205
+ Parameters
206
+ ----------
207
+ base_url: str
208
+ Base API URL.
209
+ If you want to use API not on your local PC then change it.
210
+ You can do that by setting the environment variable LUNA_BASE_URL.
211
+ Default value https://api.aqarios.com.
212
+
213
+ Returns
214
+ -------
215
+ str
216
+ Base url.
217
+
218
+ """
219
+ if base_url is None:
220
+ base_url = os.getenv("LUNA_BASE_URL", "https://api.aqarios.com")
221
+ if os.getenv("LUNA_DISABLE_SUFFIX", "false").lower() == "true":
222
+ return f"{base_url}/api/v1"
223
+ return f"{base_url}/{self.get_api().value}/api/v1"
224
+
225
+ def __del__(self) -> None: # noqa: D105
226
+ if hasattr(self, "_httpx_client"):
227
+ with suppress(Exception):
228
+ self._httpx_client.close()
229
+
230
+ def _authenticate(self) -> None:
231
+ try:
232
+ UsersRestClient(service=self).get_me()
233
+ except HTTPStatusError as exception:
234
+ if exception.response.status_code == HTTPStatus.UNAUTHORIZED:
235
+ raise LunaApiKeyInvalidError from exception
236
+ raise
237
+
238
+ def is_same(
239
+ self,
240
+ api_key: str | None = None,
241
+ ) -> bool:
242
+ """
243
+ Whether the service is created with the current environment variables.
244
+
245
+ Returns
246
+ -------
247
+ bool:
248
+ True if the service is created with the current environment variables.
249
+ False otherwise.
250
+ """
251
+ api_key = self._get_api_key(api_key)
252
+
253
+ return (
254
+ self._get_base_url() == self._base_url
255
+ and APIKeyAuth(api_key) == self._httpx_client.auth
256
+ )