luna-quantum 1.0.8rc2__cp314-cp314-macosx_10_12_x86_64.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.

Potentially problematic release.


This version of luna-quantum might be problematic. Click here for more details.

Files changed (264) hide show
  1. luna_quantum/__init__.py +121 -0
  2. luna_quantum/__init__.pyi +85 -0
  3. luna_quantum/_core.cpython-314-darwin.so +0 -0
  4. luna_quantum/_core.pyi +4185 -0
  5. luna_quantum/algorithms/__init__.py +1 -0
  6. luna_quantum/aqm_overwrites/__init__.py +3 -0
  7. luna_quantum/aqm_overwrites/model.py +184 -0
  8. luna_quantum/backends/__init__.py +1 -0
  9. luna_quantum/client/__init__.py +0 -0
  10. luna_quantum/client/controllers/__init__.py +4 -0
  11. luna_quantum/client/controllers/luna_http_client.py +37 -0
  12. luna_quantum/client/controllers/luna_platform_client.py +256 -0
  13. luna_quantum/client/controllers/luna_q.py +67 -0
  14. luna_quantum/client/controllers/luna_solve.py +129 -0
  15. luna_quantum/client/error/__init__.py +0 -0
  16. luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
  17. luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
  18. luna_quantum/client/error/luna_error.py +2 -0
  19. luna_quantum/client/error/luna_server_error.py +20 -0
  20. luna_quantum/client/error/timeout_error.py +12 -0
  21. luna_quantum/client/error/transformation_error.py +18 -0
  22. luna_quantum/client/error/utils/__init__.py +0 -0
  23. luna_quantum/client/error/utils/http_error_utils.py +112 -0
  24. luna_quantum/client/interfaces/__init__.py +4 -0
  25. luna_quantum/client/interfaces/clients/__init__.py +25 -0
  26. luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
  27. luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
  28. luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
  29. luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
  30. luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
  31. luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
  32. luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
  33. luna_quantum/client/interfaces/services/__init__.py +0 -0
  34. luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
  35. luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
  36. luna_quantum/client/interfaces/services/service_i.py +56 -0
  37. luna_quantum/client/rest_client/__init__.py +15 -0
  38. luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
  39. luna_quantum/client/rest_client/info_rest_client.py +74 -0
  40. luna_quantum/client/rest_client/model_rest_client.py +216 -0
  41. luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
  42. luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
  43. luna_quantum/client/rest_client/users_rest_client.py +35 -0
  44. luna_quantum/client/schemas/__init__.py +26 -0
  45. luna_quantum/client/schemas/circuit.py +48 -0
  46. luna_quantum/client/schemas/create/__init__.py +15 -0
  47. luna_quantum/client/schemas/create/circuit.py +30 -0
  48. luna_quantum/client/schemas/create/optimization.py +39 -0
  49. luna_quantum/client/schemas/create/qpu_token.py +22 -0
  50. luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
  51. luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
  52. luna_quantum/client/schemas/create/qubo.py +19 -0
  53. luna_quantum/client/schemas/create/solve_job_create.py +43 -0
  54. luna_quantum/client/schemas/enums/__init__.py +0 -0
  55. luna_quantum/client/schemas/enums/call_style.py +13 -0
  56. luna_quantum/client/schemas/enums/circuit.py +42 -0
  57. luna_quantum/client/schemas/enums/model_format.py +11 -0
  58. luna_quantum/client/schemas/enums/problem.py +50 -0
  59. luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
  60. luna_quantum/client/schemas/enums/sense.py +8 -0
  61. luna_quantum/client/schemas/enums/status.py +40 -0
  62. luna_quantum/client/schemas/enums/timeframe.py +11 -0
  63. luna_quantum/client/schemas/error_message.py +14 -0
  64. luna_quantum/client/schemas/model_metadata.py +35 -0
  65. luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
  66. luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
  67. luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
  68. luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
  69. luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
  70. luna_quantum/client/schemas/representation.py +19 -0
  71. luna_quantum/client/schemas/solution.py +106 -0
  72. luna_quantum/client/schemas/solve_job.py +50 -0
  73. luna_quantum/client/schemas/solver_info.py +11 -0
  74. luna_quantum/client/schemas/user.py +11 -0
  75. luna_quantum/client/schemas/wrappers/__init__.py +5 -0
  76. luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
  77. luna_quantum/client/utils/__init__.py +0 -0
  78. luna_quantum/client/utils/qpu_token_utils.py +147 -0
  79. luna_quantum/config.py +11 -0
  80. luna_quantum/decorators.py +248 -0
  81. luna_quantum/errors.py +34 -0
  82. luna_quantum/errors.pyi +287 -0
  83. luna_quantum/exceptions/__init__.py +0 -0
  84. luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
  85. luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
  86. luna_quantum/factories/__init__.py +4 -0
  87. luna_quantum/factories/luna_solve_client_factory.py +100 -0
  88. luna_quantum/factories/usecase_factory.py +457 -0
  89. luna_quantum/py.typed +0 -0
  90. luna_quantum/solve/__init__.py +13 -0
  91. luna_quantum/solve/default_token.py +304 -0
  92. luna_quantum/solve/domain/__init__.py +0 -0
  93. luna_quantum/solve/domain/abstract/__init__.py +4 -0
  94. luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
  95. luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
  96. luna_quantum/solve/domain/model_metadata.py +56 -0
  97. luna_quantum/solve/domain/solve_job.py +196 -0
  98. luna_quantum/solve/errors/__init__.py +0 -0
  99. luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
  100. luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
  101. luna_quantum/solve/errors/solve_base_error.py +5 -0
  102. luna_quantum/solve/errors/token_missing_error.py +11 -0
  103. luna_quantum/solve/interfaces/__init__.py +0 -0
  104. luna_quantum/solve/interfaces/algorithm_i.py +49 -0
  105. luna_quantum/solve/interfaces/backend_i.py +28 -0
  106. luna_quantum/solve/interfaces/usecases/__init__.py +55 -0
  107. luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
  108. luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
  109. luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
  110. luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
  111. luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
  112. luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
  113. luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
  114. luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
  115. luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
  116. luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
  117. luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
  118. luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
  119. luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
  120. luna_quantum/solve/parameters/__init__.py +0 -0
  121. luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
  122. luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
  123. luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
  124. luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
  125. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
  126. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
  127. luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
  128. luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
  129. luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
  130. luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
  131. luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
  132. luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
  133. luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
  134. luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
  135. luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
  136. luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
  137. luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
  138. luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
  139. luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
  140. luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
  141. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
  142. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
  143. luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
  144. luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
  145. luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
  146. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
  147. luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
  148. luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
  149. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +26 -0
  150. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/config.py +80 -0
  151. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/flex_qaoa.py +226 -0
  152. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +99 -0
  153. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/pipeline.py +87 -0
  154. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +102 -0
  155. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
  156. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
  157. luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
  158. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
  159. luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
  160. luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
  161. luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
  162. luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
  163. luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
  164. luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
  165. luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
  166. luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
  167. luna_quantum/solve/parameters/backends/__init__.py +22 -0
  168. luna_quantum/solve/parameters/backends/aqarios.py +17 -0
  169. luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
  170. luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
  171. luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
  172. luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
  173. luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
  174. luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
  175. luna_quantum/solve/parameters/backends/dwave.py +17 -0
  176. luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
  177. luna_quantum/solve/parameters/backends/fda.py +17 -0
  178. luna_quantum/solve/parameters/backends/ibm.py +138 -0
  179. luna_quantum/solve/parameters/backends/qctrl.py +103 -0
  180. luna_quantum/solve/parameters/backends/zib.py +17 -0
  181. luna_quantum/solve/parameters/constants.py +11 -0
  182. luna_quantum/solve/parameters/mixins/__init__.py +0 -0
  183. luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
  184. luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
  185. luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
  186. luna_quantum/solve/use_cases/__init__.py +119 -0
  187. luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
  188. luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
  189. luna_quantum/solve/use_cases/base.py +7 -0
  190. luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
  191. luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
  192. luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
  193. luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
  194. luna_quantum/solve/use_cases/exact_cover.py +51 -0
  195. luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
  196. luna_quantum/solve/use_cases/graph_coloring.py +42 -0
  197. luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
  198. luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
  199. luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
  200. luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
  201. luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
  202. luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
  203. luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
  204. luna_quantum/solve/use_cases/linear_regression.py +60 -0
  205. luna_quantum/solve/use_cases/lmwcs.py +84 -0
  206. luna_quantum/solve/use_cases/longest_path.py +50 -0
  207. luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
  208. luna_quantum/solve/use_cases/max2sat.py +54 -0
  209. luna_quantum/solve/use_cases/max3sat.py +55 -0
  210. luna_quantum/solve/use_cases/max_clique.py +60 -0
  211. luna_quantum/solve/use_cases/max_cut.py +48 -0
  212. luna_quantum/solve/use_cases/max_independent_set.py +37 -0
  213. luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
  214. luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
  215. luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
  216. luna_quantum/solve/use_cases/number_partitioning.py +32 -0
  217. luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
  218. luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
  219. luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
  220. luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
  221. luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
  222. luna_quantum/solve/use_cases/sensor_placement.py +58 -0
  223. luna_quantum/solve/use_cases/set_cover.py +56 -0
  224. luna_quantum/solve/use_cases/set_packing.py +54 -0
  225. luna_quantum/solve/use_cases/set_partitioning.py +52 -0
  226. luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
  227. luna_quantum/solve/use_cases/subset_sum.py +37 -0
  228. luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
  229. luna_quantum/solve/use_cases/traffic_flow.py +35 -0
  230. luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
  231. luna_quantum/solve/use_cases/type_aliases.py +9 -0
  232. luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
  233. luna_quantum/solve/usecases/__init__.py +45 -0
  234. luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
  235. luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
  236. luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
  237. luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
  238. luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
  239. luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
  240. luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
  241. luna_quantum/solve/usecases/model_save_usecase.py +63 -0
  242. luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
  243. luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
  244. luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
  245. luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
  246. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +95 -0
  247. luna_quantum/transformations.py +18 -0
  248. luna_quantum/transformations.pyi +371 -0
  249. luna_quantum/translator.py +23 -0
  250. luna_quantum/translator.pyi +869 -0
  251. luna_quantum/util/__init__.py +0 -0
  252. luna_quantum/util/active_waiting.py +79 -0
  253. luna_quantum/util/class_patcher.py +164 -0
  254. luna_quantum/util/debug_info.py +52 -0
  255. luna_quantum/util/log_utils.py +187 -0
  256. luna_quantum/util/pretty_base.py +67 -0
  257. luna_quantum/util/pydantic_utils.py +38 -0
  258. luna_quantum/utils.py +3 -0
  259. luna_quantum/utils.pyi +67 -0
  260. luna_quantum-1.0.8rc2.dist-info/METADATA +36 -0
  261. luna_quantum-1.0.8rc2.dist-info/RECORD +264 -0
  262. luna_quantum-1.0.8rc2.dist-info/WHEEL +4 -0
  263. luna_quantum-1.0.8rc2.dist-info/licenses/LICENSE +176 -0
  264. luna_quantum-1.0.8rc2.dist-info/licenses/NOTICE +13 -0
@@ -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
+ )
@@ -0,0 +1,67 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from luna_quantum.client.controllers.luna_platform_client import (
6
+ LunaPlatformClient,
7
+ LunaPrefixEnum,
8
+ )
9
+ from luna_quantum.client.interfaces.services.luna_q_i import ILunaQ
10
+ from luna_quantum.client.rest_client import CircuitRestClient, QpuTokenRestClient
11
+
12
+ if TYPE_CHECKING:
13
+ from luna_quantum.client.interfaces.clients import ICircuitRestClient
14
+ from luna_quantum.client.interfaces.clients.qpu_token_rest_client_i import (
15
+ IQpuTokenRestClient,
16
+ )
17
+
18
+
19
+ class LunaQ(LunaPlatformClient, ILunaQ):
20
+ """Implementation of LunaQ service."""
21
+
22
+ qpu_token: IQpuTokenRestClient = None # type: ignore[assignment]
23
+ circuit: ICircuitRestClient = None # type: ignore[assignment]
24
+
25
+ def __init__(
26
+ self, api_key: str | None = None, timeout: float | None = 240.0
27
+ ) -> None:
28
+ """
29
+ LunaQ is the main entrypoint for all LunaQ related tasks.
30
+
31
+ Parameters
32
+ ----------
33
+ api_key: str
34
+ User's API key
35
+ timeout: float
36
+ Default timeout in seconds for the requests via the LunaQ client. `None`
37
+ means that the SDK uses no timeouts. Note that either way the Luna platform
38
+ itself will time out after 240 seconds.
39
+ Default: 240.0
40
+ """
41
+ super().__init__(api_key=api_key, timeout=timeout)
42
+
43
+ self.circuit = CircuitRestClient(self)
44
+ self.qpu_token = QpuTokenRestClient(self)
45
+
46
+ @classmethod
47
+ def get_api(cls) -> LunaPrefixEnum:
48
+ """Return the api of the client."""
49
+ return LunaPrefixEnum.LUNA_Q
50
+
51
+ @classmethod
52
+ def authenticate(cls, api_key: str) -> None:
53
+ """
54
+ Authenticate the client with the given API key.
55
+
56
+ Parameters
57
+ ----------
58
+ api_key : str
59
+ The API key used to authenticate the client.
60
+
61
+ Returns
62
+ -------
63
+ None
64
+ This method does not return any value.
65
+ """
66
+ cls(api_key=api_key)
67
+ cls._api_key = api_key
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from luna_quantum.client.controllers.luna_platform_client import (
6
+ LunaPlatformClient,
7
+ LunaPrefixEnum,
8
+ )
9
+ from luna_quantum.client.interfaces.services.luna_solve_i import ILunaSolve
10
+ from luna_quantum.client.rest_client.info_rest_client import InfoRestClient
11
+ from luna_quantum.client.rest_client.model_rest_client import (
12
+ ModelRestClient,
13
+ )
14
+ from luna_quantum.client.rest_client.qpu_token_rest_client import QpuTokenRestClient
15
+ from luna_quantum.client.rest_client.solve_job_rest_client import SolveJobRestClient
16
+
17
+ if TYPE_CHECKING:
18
+ from luna_quantum.client.interfaces.clients import ISolveJobRestClient
19
+ from luna_quantum.client.interfaces.clients.info_rest_client_i import (
20
+ IInfoRestClient,
21
+ )
22
+ from luna_quantum.client.interfaces.clients.model_rest_client_i import (
23
+ IModelRestClient,
24
+ )
25
+ from luna_quantum.client.interfaces.clients.qpu_token_rest_client_i import (
26
+ IQpuTokenRestClient,
27
+ )
28
+
29
+
30
+ class LunaSolve(LunaPlatformClient, ILunaSolve):
31
+ """Implementation of LunaSolve service."""
32
+
33
+ _model: IModelRestClient
34
+ _solve_job: ISolveJobRestClient
35
+ _qpu_token: IQpuTokenRestClient
36
+ _info: IInfoRestClient
37
+
38
+ def __init__(
39
+ self, api_key: str | None = None, timeout: float | None = 240.0
40
+ ) -> None:
41
+ """
42
+ LunaSolve is the main entrypoint for all LunaSolve related tasks.
43
+
44
+ Parameters
45
+ ----------
46
+ api_key: str
47
+ User's API key
48
+ timeout: float
49
+ Default timeout in seconds for the requests via the LunaQ client. `None`
50
+ means that the SDK uses no timeouts. Note that either way the Luna platform
51
+ itself will time out after 240 seconds.
52
+ Default: 240.0
53
+ """
54
+ super().__init__(
55
+ api_key=api_key,
56
+ timeout=timeout,
57
+ )
58
+
59
+ self._model = ModelRestClient(self)
60
+ self._solve_job = SolveJobRestClient(self)
61
+ self._qpu_token = QpuTokenRestClient(self)
62
+ self._info = InfoRestClient(self)
63
+
64
+ @classmethod
65
+ def get_api(cls) -> LunaPrefixEnum:
66
+ """Return the api of the client."""
67
+ return LunaPrefixEnum.LUNA_SOLVE
68
+
69
+ @classmethod
70
+ def authenticate(cls, api_key: str) -> None:
71
+ """
72
+ Authenticate the client with the given API key.
73
+
74
+ Parameters
75
+ ----------
76
+ api_key : str
77
+ The API key used to authenticate the client.
78
+
79
+ Returns
80
+ -------
81
+ None
82
+ This method does not return any value.
83
+ """
84
+ cls(api_key=api_key)
85
+ cls._api_key = api_key
86
+
87
+ @property
88
+ def model(self) -> IModelRestClient:
89
+ """
90
+ Returns a model rest client.
91
+
92
+ Returns
93
+ -------
94
+ IModelRestClient
95
+ """
96
+ return self._model
97
+
98
+ @property
99
+ def solve_job(self) -> ISolveJobRestClient:
100
+ """
101
+ Returns a solve job rest client.
102
+
103
+ Returns
104
+ -------
105
+ ISolveJobRestClient
106
+ """
107
+ return self._solve_job
108
+
109
+ @property
110
+ def qpu_token(self) -> IQpuTokenRestClient:
111
+ """
112
+ Returns a qpu token rest client.
113
+
114
+ Returns
115
+ -------
116
+ IQpuTokenRestClient
117
+ """
118
+ return self._qpu_token
119
+
120
+ @property
121
+ def info(self) -> IInfoRestClient:
122
+ """
123
+ Returns an info rest client.
124
+
125
+ Returns
126
+ -------
127
+ IInfoRestClient
128
+ """
129
+ return self._info
File without changes