luna-quantum 1.0.0__cp313-cp313-musllinux_1_2_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 (253) hide show
  1. luna_quantum/__init__.py +96 -0
  2. luna_quantum/__init__.pyi +68 -0
  3. luna_quantum/_core.cpython-313-x86_64-linux-musl.so +0 -0
  4. luna_quantum/_core.pyi +3017 -0
  5. luna_quantum/aqm_overwrites/__init__.py +3 -0
  6. luna_quantum/aqm_overwrites/model.py +184 -0
  7. luna_quantum/client/__init__.py +0 -0
  8. luna_quantum/client/controllers/__init__.py +4 -0
  9. luna_quantum/client/controllers/luna_http_client.py +37 -0
  10. luna_quantum/client/controllers/luna_platform_client.py +153 -0
  11. luna_quantum/client/controllers/luna_q.py +62 -0
  12. luna_quantum/client/controllers/luna_solve.py +125 -0
  13. luna_quantum/client/error/__init__.py +0 -0
  14. luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
  15. luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
  16. luna_quantum/client/error/luna_error.py +2 -0
  17. luna_quantum/client/error/luna_server_error.py +20 -0
  18. luna_quantum/client/error/timeout_error.py +12 -0
  19. luna_quantum/client/error/transformation_error.py +18 -0
  20. luna_quantum/client/error/utils/__init__.py +0 -0
  21. luna_quantum/client/error/utils/http_error_utils.py +112 -0
  22. luna_quantum/client/interfaces/__init__.py +4 -0
  23. luna_quantum/client/interfaces/clients/__init__.py +25 -0
  24. luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
  25. luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
  26. luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
  27. luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
  28. luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
  29. luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
  30. luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
  31. luna_quantum/client/interfaces/services/__init__.py +0 -0
  32. luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
  33. luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
  34. luna_quantum/client/interfaces/services/service_i.py +36 -0
  35. luna_quantum/client/rest_client/__init__.py +15 -0
  36. luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
  37. luna_quantum/client/rest_client/info_rest_client.py +76 -0
  38. luna_quantum/client/rest_client/model_rest_client.py +216 -0
  39. luna_quantum/client/rest_client/qpu_token_rest_client.py +504 -0
  40. luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
  41. luna_quantum/client/rest_client/users_rest_client.py +35 -0
  42. luna_quantum/client/schemas/__init__.py +26 -0
  43. luna_quantum/client/schemas/circuit.py +49 -0
  44. luna_quantum/client/schemas/create/__init__.py +6 -0
  45. luna_quantum/client/schemas/create/circuit.py +31 -0
  46. luna_quantum/client/schemas/create/optimization.py +39 -0
  47. luna_quantum/client/schemas/create/qpu_token.py +25 -0
  48. luna_quantum/client/schemas/create/qpu_token_time_quota.py +29 -0
  49. luna_quantum/client/schemas/create/qubo.py +19 -0
  50. luna_quantum/client/schemas/create/solve_job_create.py +43 -0
  51. luna_quantum/client/schemas/enums/__init__.py +0 -0
  52. luna_quantum/client/schemas/enums/call_style.py +13 -0
  53. luna_quantum/client/schemas/enums/circuit.py +42 -0
  54. luna_quantum/client/schemas/enums/model_format.py +11 -0
  55. luna_quantum/client/schemas/enums/problem.py +50 -0
  56. luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
  57. luna_quantum/client/schemas/enums/sense.py +8 -0
  58. luna_quantum/client/schemas/enums/status.py +40 -0
  59. luna_quantum/client/schemas/enums/timeframe.py +11 -0
  60. luna_quantum/client/schemas/error_message.py +14 -0
  61. luna_quantum/client/schemas/model_metadata.py +35 -0
  62. luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
  63. luna_quantum/client/schemas/qpu_token/qpu_token.py +161 -0
  64. luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
  65. luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +28 -0
  66. luna_quantum/client/schemas/qpu_token/token_provider.py +135 -0
  67. luna_quantum/client/schemas/representation.py +19 -0
  68. luna_quantum/client/schemas/solution.py +106 -0
  69. luna_quantum/client/schemas/solve_job.py +47 -0
  70. luna_quantum/client/schemas/solver_info.py +11 -0
  71. luna_quantum/client/schemas/user.py +11 -0
  72. luna_quantum/client/schemas/wrappers/__init__.py +5 -0
  73. luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
  74. luna_quantum/client/utils/__init__.py +0 -0
  75. luna_quantum/client/utils/qpu_token_utils.py +147 -0
  76. luna_quantum/errors.py +1 -0
  77. luna_quantum/errors.pyi +202 -0
  78. luna_quantum/exceptions/__init__.py +0 -0
  79. luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
  80. luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
  81. luna_quantum/factories/__init__.py +4 -0
  82. luna_quantum/factories/luna_solve_client_factory.py +75 -0
  83. luna_quantum/factories/usecase_factory.py +457 -0
  84. luna_quantum/py.typed +0 -0
  85. luna_quantum/solve/__init__.py +13 -0
  86. luna_quantum/solve/default_token.py +304 -0
  87. luna_quantum/solve/domain/__init__.py +0 -0
  88. luna_quantum/solve/domain/abstract/__init__.py +4 -0
  89. luna_quantum/solve/domain/abstract/luna_algorithm.py +203 -0
  90. luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
  91. luna_quantum/solve/domain/model_metadata.py +54 -0
  92. luna_quantum/solve/domain/solve_job.py +187 -0
  93. luna_quantum/solve/errors/__init__.py +0 -0
  94. luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
  95. luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
  96. luna_quantum/solve/errors/solve_base_error.py +5 -0
  97. luna_quantum/solve/errors/token_missing_error.py +11 -0
  98. luna_quantum/solve/interfaces/__init__.py +0 -0
  99. luna_quantum/solve/interfaces/algorithm_i.py +47 -0
  100. luna_quantum/solve/interfaces/backend_i.py +28 -0
  101. luna_quantum/solve/interfaces/usecases/__init__.py +55 -0
  102. luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
  103. luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
  104. luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
  105. luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
  106. luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
  107. luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
  108. luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
  109. luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
  110. luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
  111. luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
  112. luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
  113. luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
  114. luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
  115. luna_quantum/solve/parameters/__init__.py +0 -0
  116. luna_quantum/solve/parameters/algorithms/__init__.py +49 -0
  117. luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
  118. luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
  119. luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
  120. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +78 -0
  121. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +120 -0
  122. luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
  123. luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
  124. luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
  125. luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
  126. luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
  127. luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
  128. luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
  129. luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
  130. luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
  131. luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
  132. luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
  133. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
  134. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
  135. luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
  136. luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
  137. luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
  138. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +105 -0
  139. luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
  140. luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
  141. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +26 -0
  142. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/config.py +80 -0
  143. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/flex_qaoa.py +226 -0
  144. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/optimizers.py +97 -0
  145. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/pipeline.py +87 -0
  146. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +104 -0
  147. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
  148. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +109 -0
  149. luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
  150. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +152 -0
  151. luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
  152. luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
  153. luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
  154. luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
  155. luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
  156. luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
  157. luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
  158. luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
  159. luna_quantum/solve/parameters/backends/__init__.py +20 -0
  160. luna_quantum/solve/parameters/backends/aqarios.py +17 -0
  161. luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
  162. luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
  163. luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
  164. luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
  165. luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
  166. luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
  167. luna_quantum/solve/parameters/backends/dwave.py +17 -0
  168. luna_quantum/solve/parameters/backends/dwave_qpu.py +164 -0
  169. luna_quantum/solve/parameters/backends/ibm.py +132 -0
  170. luna_quantum/solve/parameters/backends/qctrl.py +130 -0
  171. luna_quantum/solve/parameters/backends/zib.py +17 -0
  172. luna_quantum/solve/parameters/constants.py +11 -0
  173. luna_quantum/solve/parameters/mixins/__init__.py +0 -0
  174. luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
  175. luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
  176. luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
  177. luna_quantum/solve/use_cases/__init__.py +119 -0
  178. luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
  179. luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
  180. luna_quantum/solve/use_cases/base.py +7 -0
  181. luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
  182. luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
  183. luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
  184. luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
  185. luna_quantum/solve/use_cases/exact_cover.py +51 -0
  186. luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
  187. luna_quantum/solve/use_cases/graph_coloring.py +42 -0
  188. luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
  189. luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
  190. luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
  191. luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
  192. luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
  193. luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
  194. luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
  195. luna_quantum/solve/use_cases/linear_regression.py +60 -0
  196. luna_quantum/solve/use_cases/lmwcs.py +84 -0
  197. luna_quantum/solve/use_cases/longest_path.py +50 -0
  198. luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
  199. luna_quantum/solve/use_cases/max2sat.py +54 -0
  200. luna_quantum/solve/use_cases/max3sat.py +55 -0
  201. luna_quantum/solve/use_cases/max_clique.py +60 -0
  202. luna_quantum/solve/use_cases/max_cut.py +48 -0
  203. luna_quantum/solve/use_cases/max_independent_set.py +37 -0
  204. luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
  205. luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
  206. luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
  207. luna_quantum/solve/use_cases/number_partitioning.py +32 -0
  208. luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
  209. luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
  210. luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
  211. luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
  212. luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
  213. luna_quantum/solve/use_cases/sensor_placement.py +58 -0
  214. luna_quantum/solve/use_cases/set_cover.py +56 -0
  215. luna_quantum/solve/use_cases/set_packing.py +54 -0
  216. luna_quantum/solve/use_cases/set_partitioning.py +52 -0
  217. luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
  218. luna_quantum/solve/use_cases/subset_sum.py +37 -0
  219. luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
  220. luna_quantum/solve/use_cases/traffic_flow.py +35 -0
  221. luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
  222. luna_quantum/solve/use_cases/type_aliases.py +9 -0
  223. luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
  224. luna_quantum/solve/usecases/__init__.py +45 -0
  225. luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
  226. luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
  227. luna_quantum/solve/usecases/model_get_solution_usecase.py +56 -0
  228. luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
  229. luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
  230. luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
  231. luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
  232. luna_quantum/solve/usecases/model_save_usecase.py +63 -0
  233. luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
  234. luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
  235. luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
  236. luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
  237. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +97 -0
  238. luna_quantum/translator.py +1 -0
  239. luna_quantum/translator.pyi +833 -0
  240. luna_quantum/util/__init__.py +0 -0
  241. luna_quantum/util/active_waiting.py +79 -0
  242. luna_quantum/util/class_patcher.py +164 -0
  243. luna_quantum/util/log_utils.py +167 -0
  244. luna_quantum/util/pretty_base.py +67 -0
  245. luna_quantum/util/pydantic_utils.py +38 -0
  246. luna_quantum/utils.py +54 -0
  247. luna_quantum/utils.pyi +35 -0
  248. luna_quantum-1.0.0.dist-info/METADATA +37 -0
  249. luna_quantum-1.0.0.dist-info/RECORD +253 -0
  250. luna_quantum-1.0.0.dist-info/WHEEL +4 -0
  251. luna_quantum-1.0.0.dist-info/licenses/LICENSE +176 -0
  252. luna_quantum-1.0.0.dist-info/licenses/NOTICE +13 -0
  253. luna_quantum.libs/libgcc_s-02f3f192.so.1 +0 -0
@@ -0,0 +1,47 @@
1
+ from datetime import datetime
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from luna_quantum.client.schemas.enums.model_format import ModelFormat
6
+ from luna_quantum.client.schemas.enums.status import StatusEnum
7
+
8
+
9
+ class SolveJobSchema(BaseModel):
10
+ """
11
+ Solve job schema.
12
+
13
+ Attributes
14
+ ----------
15
+ id: str
16
+ The ID of the solve job.
17
+ status: StatusEnum
18
+ The current status of the solve job.
19
+ status_timeline: dict[StatusEnum, datetime]
20
+ The history of status changes for the solve job.
21
+ used_format: ModelFormat | None
22
+ The format that is used for solving. None if not applicable.
23
+ error_message: str | None
24
+ The error message if the solve job failed.
25
+ provider: str
26
+ The name of the provider where the solve job is scheduled.
27
+ solver_job_info: str | None
28
+ Additional information about the solve job. None if not available.
29
+ is_cancelable: bool
30
+ Indicates if the solve job can be cancelled.
31
+ is_cancellation_requested: bool
32
+ Indicates if cancellation of the solve job has been requested.
33
+ """
34
+
35
+ id: str
36
+ status: StatusEnum
37
+ status_timeline: dict[StatusEnum, datetime]
38
+ used_format: ModelFormat | None = None
39
+
40
+ error_message: str | None
41
+ provider: str
42
+
43
+ # TODO(Lev): Consider renaming? # noqa: FIX002
44
+ solver_job_info: str | None = None
45
+
46
+ is_cancelable: bool
47
+ is_cancellation_requested: bool
@@ -0,0 +1,11 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class SolverInfo(BaseModel):
5
+ """Solver info schema."""
6
+
7
+ full_name: str
8
+ short_name: str
9
+ available: bool
10
+ params: dict # type: ignore[type-arg]
11
+ description: str | None
@@ -0,0 +1,11 @@
1
+ from pydantic import BaseModel, EmailStr
2
+
3
+
4
+ class User(BaseModel):
5
+ """Pydantic model for user going OUT."""
6
+
7
+ email: EmailStr
8
+ first_name: str
9
+ last_name: str
10
+ groups: list[str] = []
11
+ orgs: list[str] = []
@@ -0,0 +1,5 @@
1
+ from luna_quantum.client.schemas.wrappers.datetime_wrapper import (
2
+ PydanticDatetimeWrapper,
3
+ )
4
+
5
+ __all__ = ["PydanticDatetimeWrapper"]
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+ from typing import Annotated
5
+
6
+ from dateutil.parser import parse
7
+ from pydantic import BeforeValidator
8
+
9
+
10
+ def validate_datetime(date_string: str | datetime) -> datetime:
11
+ """Validate an ISO date string and return it in the local timezone.
12
+
13
+ Parameters
14
+ ----------
15
+ date_string : str
16
+ The ISO date string
17
+
18
+ Returns
19
+ -------
20
+ datetime
21
+ The datetime in the user's local timezone
22
+
23
+ Raises
24
+ ------
25
+ ValueError
26
+ If `date_string` does not have a valid format.
27
+ """
28
+ dt = date_string if isinstance(date_string, datetime) else parse(date_string)
29
+ return dt.astimezone()
30
+
31
+
32
+ PydanticDatetimeWrapper = Annotated[datetime, BeforeValidator(validate_datetime)]
File without changes
@@ -0,0 +1,147 @@
1
+ import os
2
+
3
+ from luna_quantum.client.schemas.qpu_token.qpu_token import (
4
+ QpuToken,
5
+ QpuTokenSource,
6
+ TokenProvider,
7
+ )
8
+
9
+
10
+ class QpuTokenUtils:
11
+ """Utilities for QPU tokens."""
12
+
13
+ @staticmethod
14
+ def patch_qpu_tokens_from_env(
15
+ qpu_token: TokenProvider = TokenProvider(),
16
+ ) -> TokenProvider | None:
17
+ """
18
+ Add QPU tokens from environment variables.
19
+
20
+ If a token is not found in the environment, it will be set to None.
21
+ If no token-provider is provided, a new one will be created.
22
+
23
+ Parameters
24
+ ----------
25
+ qpu_token: TokenProvider
26
+ Token-provider to update. If no token-provider is provided,
27
+ a new one will be created.
28
+
29
+ Returns
30
+ -------
31
+ Optional[TokenProvider]
32
+ Returns the updated token-provider. If the token-provider is empty,
33
+ returns None.
34
+ """
35
+ qpu_token.dwave = QpuTokenUtils.get_token_from_provider_or_env(
36
+ token=qpu_token.dwave, env_key="LUNA_DWAVE_TOKEN"
37
+ )
38
+ qpu_token.ibm = QpuTokenUtils.get_token_from_provider_or_env(
39
+ token=qpu_token.ibm, env_key="LUNA_IBM_TOKEN"
40
+ )
41
+ qpu_token.qctrl = QpuTokenUtils.get_token_from_provider_or_env(
42
+ token=qpu_token.qctrl, env_key="LUNA_QCTRL_TOKEN"
43
+ )
44
+ qpu_token.fujitsu = QpuTokenUtils.get_token_from_provider_or_env(
45
+ token=qpu_token.fujitsu, env_key="LUNA_FUJITSU_TOKEN"
46
+ )
47
+ qpu_token.aws_access_key = QpuTokenUtils.get_token_from_provider_or_env(
48
+ token=qpu_token.aws_access_key, env_key="LUNA_AWS_ACCESS_KEY"
49
+ )
50
+ qpu_token.aws_secret_access_key = QpuTokenUtils.get_token_from_provider_or_env(
51
+ token=qpu_token.aws_secret_access_key, env_key="LUNA_AWS_SECRET_ACCESS_KEY"
52
+ )
53
+ qpu_token.aws_session_token = QpuTokenUtils.get_token_from_provider_or_env(
54
+ token=qpu_token.aws_session_token, env_key="LUNA_AWS_SESSION_TOKEN"
55
+ )
56
+
57
+ if QpuTokenUtils.is_token_provider_empty(qpu_token):
58
+ return None
59
+
60
+ return qpu_token
61
+
62
+ @staticmethod
63
+ def is_qpu_token_empty(qpu_token: QpuToken) -> bool:
64
+ """
65
+ Check if the QpuToken object is empty.
66
+
67
+ An empty QpuToken is defined as having both its `name` and `token`
68
+ attributes set to `None`.
69
+
70
+ Parameters
71
+ ----------
72
+ qpu_token : QpuToken
73
+ The QpuToken object to check for emptiness.
74
+
75
+ Returns
76
+ -------
77
+ bool
78
+ True if the QpuToken is empty, otherwise False.
79
+
80
+ """
81
+ return qpu_token.name is None and qpu_token.token is None
82
+
83
+ @staticmethod
84
+ def is_token_provider_empty(qpu_token: TokenProvider) -> bool:
85
+ """
86
+ Check if the token provider is empty.
87
+
88
+ The function checks whether all attributes of the provided token provider are
89
+ None, indicating that it is empty.
90
+
91
+ Parameters
92
+ ----------
93
+ qpu_token : TokenProvider
94
+ The token provider object containing various token attributes.
95
+
96
+ Returns
97
+ -------
98
+ bool
99
+ True if all token attributes are None, otherwise False.
100
+ """
101
+ if qpu_token is None:
102
+ return True
103
+ for field in [
104
+ qpu_token.dwave,
105
+ qpu_token.ibm,
106
+ qpu_token.qctrl,
107
+ qpu_token.fujitsu,
108
+ qpu_token.aws_access_key,
109
+ qpu_token.aws_secret_access_key,
110
+ qpu_token.aws_session_token,
111
+ ]:
112
+ if field is not None and not QpuTokenUtils.is_qpu_token_empty(field):
113
+ return False
114
+ return True
115
+
116
+ @staticmethod
117
+ def get_token_from_provider_or_env(
118
+ token: QpuToken | None, env_key: str
119
+ ) -> QpuToken | None:
120
+ """
121
+ Get token from provider or environment variable.
122
+
123
+ If a token is provided and not empty, return it. Otherwise, attempt to retrieve
124
+ a token from the specified environment variable. If no token is found, return
125
+ None.
126
+
127
+ Parameters
128
+ ----------
129
+ token : Optional[QpuToken]
130
+ Token provided by the caller.
131
+ env_key : str
132
+ The key for the environment variable to look for a token.
133
+
134
+ Returns
135
+ -------
136
+ Optional[QpuToken]
137
+ The token retrieved either from the provided input or the environment.
138
+ """
139
+ if token is None or QpuTokenUtils.is_qpu_token_empty(token):
140
+ env_value = os.environ.get(env_key, None)
141
+ if env_value is not None:
142
+ return QpuToken(
143
+ source=QpuTokenSource.INLINE,
144
+ token=env_value,
145
+ )
146
+ return None
147
+ return token
luna_quantum/errors.py ADDED
@@ -0,0 +1 @@
1
+ from ._core.errors import * # type: ignore[import-not-found] # noqa: F403
@@ -0,0 +1,202 @@
1
+ class VariableOutOfRangeError(Exception):
2
+ """
3
+ Raised when a variable referenced in an expression is out of bounds for the environment.
4
+
5
+ This error typically occurs when querying coefficients (linear, quadratic,
6
+ or higher-order) from an `Expression` using a `Variable` whose index does not
7
+ exist in the environment's internal registry.
8
+
9
+ This may happen if:
10
+ - A variable is used from a different environment
11
+ - A variable was removed or never registered properly
12
+ - A raw index or tuple refers to a non-existent variable ID
13
+ """
14
+
15
+ class VariableExistsError(Exception):
16
+ """
17
+ Raised when trying to create a variable with a name that already exists.
18
+
19
+ Variable names must be unique within an `Environment`. Attempting to redefine
20
+ a variable with the same name will raise this exception.
21
+ """
22
+
23
+ class VariableNotExistingError(Exception):
24
+ """
25
+ Raised when trying to get a variable with a name that does not exist.
26
+ """
27
+
28
+ class VariableCreationError(Exception):
29
+ """
30
+ Raised when an error occurs during the creation of a variable.
31
+
32
+ For example, binary and spin variables cannot be created with bounds.
33
+ """
34
+
35
+ class VariablesFromDifferentEnvsError(Exception):
36
+ """
37
+ Raised when multiple variables from different environments are used together.
38
+
39
+ All variables in an expression or constraint must belong to the same
40
+ `Environment`. Mixing across environments is disallowed to ensure consistency.
41
+ """
42
+
43
+ class DifferentEnvsError(Exception):
44
+ """
45
+ Raised when two incompatible environments are passed to a model or operation.
46
+
47
+ Unlike `VariablesFromDifferentEnvsError`, this error may occur at the model level
48
+ or in structural operations that require consistency across multiple environments.
49
+ """
50
+
51
+ class NoActiveEnvironmentFoundError(Exception):
52
+ """
53
+ Raised when a variable or expression is created without an active environment context.
54
+
55
+ This typically happens when not using `with Environment(): ...` and no environment
56
+ was explicitly provided.
57
+ """
58
+
59
+ class MultipleActiveEnvironmentsError(Exception):
60
+ """
61
+ Raised when multiple environments are active simultaneously.
62
+
63
+ This is a logic error, since `aqmodels` only supports one active environment
64
+ at a time. This is enforced to maintain clarity and safety.
65
+ """
66
+
67
+ class DecodeError(Exception):
68
+ """
69
+ Raised when decoding or deserialization of binary data fails.
70
+
71
+ This can occur if the encoded data is corrupted, incompatible, or not generated
72
+ by `aqmodels.encode()`.
73
+ """
74
+
75
+ class VariableNamesError(Exception):
76
+ """
77
+ Raised when the QuboTranslator tries to create a model from a QUBO matrix, but
78
+ the provided variable names are invalid.
79
+
80
+ If variable names are provided to the QuboTranslator, they have to be unique, and
81
+ the number of names has to match the number of variables in the QUBO matrix.
82
+ """
83
+
84
+ class IllegalConstraintNameError(Exception):
85
+ """
86
+ Raised when a constraint is tried to be created with an illegal name.
87
+ """
88
+
89
+ class TranslationError(Exception):
90
+ """
91
+ Raised when an error occurred during translation.
92
+ """
93
+
94
+ class ModelNotQuadraticError(TranslationError):
95
+ """
96
+ Raised when a model is expected to be quadratic but contains higher-order terms.
97
+
98
+ Some solvers or transformations require the model to have at most quadratic
99
+ expressions. This error signals that unsupported terms were detected.
100
+ """
101
+
102
+ class ModelNotUnconstrainedError(TranslationError):
103
+ """
104
+ Raised when an operation requires an unconstrained model, but constraints are present.
105
+
106
+ Some solution methods may only work on unconstrained models, such as when
107
+ transforming a symbolic model to a low-level format.
108
+ """
109
+
110
+ class ModelSenseNotMinimizeError(TranslationError):
111
+ """
112
+ Raised when an operation requires a model with minimization sense, but has
113
+ maximization sense.
114
+
115
+ Some model formats only work with minimization sense. In this case, consider
116
+ setting the sense to `minimize` before the transformation, and multiplying the
117
+ objective by `-1` if necessary.
118
+ """
119
+
120
+ class ModelVtypeError(TranslationError):
121
+ """
122
+ Raised when an operation has certain constraints on a model's variable types that
123
+ are violated.
124
+
125
+ Some solution methods may only work on models where all variables have the same
126
+ type, or where only certain variable types are permitted.
127
+ """
128
+
129
+ class SolutionTranslationError(Exception):
130
+ """
131
+ Raised when something goes wrong during the translation of a solution.
132
+
133
+ This may happen during the translation to an AqSolution from a different solution
134
+ format, e.g., when the samples have different lengths or the variable types are not
135
+ consistent with the model the solution is created for.
136
+ """
137
+
138
+ class SampleIncorrectLengthError(SolutionTranslationError):
139
+ """
140
+ Raised when a sample length is different from the number of model variables.
141
+
142
+ When an external solution format is translated to an AqSolution, the number of
143
+ variable assignments in the solution's sample has to exactly match the number of
144
+ variables in the model environment that is passed to the translator.
145
+ """
146
+
147
+ class SampleUnexpectedVariableError(SolutionTranslationError):
148
+ """
149
+ Raised when a sample contains a variable with a name that is not present in the
150
+ environment.
151
+
152
+ When a sample is translated to an AqResult, the currently active environment has to
153
+ contain the same variables as the sample.
154
+ """
155
+
156
+ class SampleIncompatibleVtypeError(SolutionTranslationError):
157
+ """
158
+ Raised when a sample's assignments have variable types incompatible with the
159
+ model's variable types.
160
+
161
+ When an external solution format is translated to an AqSolution, the variable
162
+ assignments are tried to be converted into the model's corresponding variable type.
163
+ This may fail when the assignment types are incompatible.
164
+
165
+ Note that conversions with precision loss or truncation are admitted, but
166
+ conversions of variables outside the permitted range will fail.
167
+ """
168
+
169
+ class ComputationError(Exception):
170
+ """
171
+ Raised when an error occured in an internal computation.
172
+ """
173
+
174
+ class EvaluationError(Exception):
175
+ """
176
+ Raised when an error occured during evaluation of a model.
177
+ """
178
+
179
+ __all__ = [
180
+ "ComputationError",
181
+ "DecodeError",
182
+ "DifferentEnvsError",
183
+ "EvaluationError",
184
+ "IllegalConstraintNameError",
185
+ "ModelNotQuadraticError",
186
+ "ModelNotUnconstrainedError",
187
+ "ModelSenseNotMinimizeError",
188
+ "ModelVtypeError",
189
+ "MultipleActiveEnvironmentsError",
190
+ "NoActiveEnvironmentFoundError",
191
+ "SampleIncompatibleVtypeError",
192
+ "SampleIncorrectLengthError",
193
+ "SampleUnexpectedVariableError",
194
+ "SolutionTranslationError",
195
+ "TranslationError",
196
+ "VariableCreationError",
197
+ "VariableExistsError",
198
+ "VariableNamesError",
199
+ "VariableNotExistingError",
200
+ "VariableOutOfRangeError",
201
+ "VariablesFromDifferentEnvsError",
202
+ ]
File without changes
@@ -0,0 +1,2 @@
1
+ class BaseLunaQuantumError(Exception):
2
+ """Base class for all Luna Quantum errors."""
@@ -0,0 +1,10 @@
1
+ from luna_quantum.exceptions.base_luna_quantum_error import BaseLunaQuantumError
2
+
3
+
4
+ class PatchClassFieldExistsError(BaseLunaQuantumError, AttributeError):
5
+ """Raised when a field is already present in a class."""
6
+
7
+ def __init__(self, class_name: str, field_name: str) -> None:
8
+ super().__init__(
9
+ f"The class {class_name} already has a field named '{field_name}'"
10
+ )
@@ -0,0 +1,4 @@
1
+ from .luna_solve_client_factory import LunaSolveClientFactory
2
+ from .usecase_factory import UseCaseFactory
3
+
4
+ __all__ = ["LunaSolveClientFactory", "UseCaseFactory"]
@@ -0,0 +1,75 @@
1
+ from typing import ClassVar
2
+
3
+ from luna_quantum.client.interfaces.services.luna_solve_i import ILunaSolve
4
+
5
+
6
+ class LunaSolveClientFactory:
7
+ """
8
+ Factory class for managing ILunaSolve client instances.
9
+
10
+ This class provides methods to retrieve and manage ILunaSolve client instances
11
+ based on class configurations and input specifications.
12
+ """
13
+
14
+ _client_class: ClassVar[type[ILunaSolve]]
15
+
16
+ @staticmethod
17
+ def get_client(client: ILunaSolve | str | None) -> ILunaSolve:
18
+ """
19
+ Get a client based on the input or create a default one.
20
+
21
+ This method retrieves an ILunaSolve client based on the provided input.
22
+ If a client is not given or if the input is invalid,
23
+ a default ILunaSolve client is instantiated and returned.
24
+
25
+ Parameters
26
+ ----------
27
+ client : Optional[Union[ILunaSolve, str]]
28
+ The input client. It can either be an instance of ILunaSolve, a string
29
+ representation of the client, or None.
30
+
31
+ Returns
32
+ -------
33
+ ILunaSolve
34
+ An ILunaSolve client instance.
35
+ """
36
+ if isinstance(client, ILunaSolve):
37
+ return client
38
+ if isinstance(client, str):
39
+ return LunaSolveClientFactory.get_client_class()(client)
40
+ return LunaSolveClientFactory.get_client_class()()
41
+
42
+ @staticmethod
43
+ def get_client_class() -> type[ILunaSolve]:
44
+ """
45
+ Return the class type for the client.
46
+
47
+ Retrieve the class type associated with the client from the client factory.
48
+
49
+ Returns
50
+ -------
51
+ Type[ILunaSolve]
52
+ The class type of the client.
53
+ """
54
+ return LunaSolveClientFactory._client_class
55
+
56
+ @staticmethod
57
+ def set_client_class(client_class: type[ILunaSolve]) -> None:
58
+ """
59
+ Set the client class for the ClientFactory.
60
+
61
+ This method assigns a specific implementation class of ILunaSolve to the
62
+ ClientFactory for creating client instances. This allows the factory to use
63
+ the specified class when creating its objects.
64
+
65
+ Parameters
66
+ ----------
67
+ client_class : Type[ILunaSolve]
68
+ The class implementing the ILunaSolve interface to be used by the factory.
69
+
70
+ Returns
71
+ -------
72
+ None
73
+
74
+ """
75
+ LunaSolveClientFactory._client_class = client_class