luna-quantum 0.0.16__py3-none-any.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 (160) hide show
  1. luna_quantum-0.0.16.dist-info/LICENSE +201 -0
  2. luna_quantum-0.0.16.dist-info/METADATA +46 -0
  3. luna_quantum-0.0.16.dist-info/RECORD +160 -0
  4. luna_quantum-0.0.16.dist-info/WHEEL +4 -0
  5. luna_sdk/__init__.py +2 -0
  6. luna_sdk/constants.py +1 -0
  7. luna_sdk/controllers/__init__.py +2 -0
  8. luna_sdk/controllers/custom_login_client.py +61 -0
  9. luna_sdk/controllers/luna_platform_client.py +62 -0
  10. luna_sdk/controllers/luna_q.py +36 -0
  11. luna_sdk/controllers/luna_solve.py +49 -0
  12. luna_sdk/controllers/luna_transform.py +41 -0
  13. luna_sdk/error/__init__.py +0 -0
  14. luna_sdk/error/http_error_utils.py +100 -0
  15. luna_sdk/exceptions/__init__.py +1 -0
  16. luna_sdk/exceptions/encryption_exception.py +6 -0
  17. luna_sdk/exceptions/luna_exception.py +7 -0
  18. luna_sdk/exceptions/luna_server_exception.py +18 -0
  19. luna_sdk/exceptions/timeout_exception.py +10 -0
  20. luna_sdk/exceptions/transformation.py +11 -0
  21. luna_sdk/interfaces/__init__.py +5 -0
  22. luna_sdk/interfaces/circuit_repo_i.py +62 -0
  23. luna_sdk/interfaces/clients/__init__.py +0 -0
  24. luna_sdk/interfaces/clients/client_i.py +10 -0
  25. luna_sdk/interfaces/clients/luna_q_i.py +39 -0
  26. luna_sdk/interfaces/clients/luna_solve_i.py +37 -0
  27. luna_sdk/interfaces/clients/luna_transform_i.py +33 -0
  28. luna_sdk/interfaces/cplex_repo_i.py +121 -0
  29. luna_sdk/interfaces/info_repo_i.py +40 -0
  30. luna_sdk/interfaces/lp_repo_i.py +106 -0
  31. luna_sdk/interfaces/optimization_repo_i.py +262 -0
  32. luna_sdk/interfaces/qpu_token_repo_i.py +151 -0
  33. luna_sdk/interfaces/repository_i.py +14 -0
  34. luna_sdk/interfaces/solutions_repo_i.py +219 -0
  35. luna_sdk/py.typed +0 -0
  36. luna_sdk/repositories/__init__.py +4 -0
  37. luna_sdk/repositories/circuit_repo.py +104 -0
  38. luna_sdk/repositories/cplex_repo.py +118 -0
  39. luna_sdk/repositories/info_repo.py +45 -0
  40. luna_sdk/repositories/lp_repo.py +105 -0
  41. luna_sdk/repositories/optimization_repo.py +358 -0
  42. luna_sdk/repositories/qpu_token_repo.py +226 -0
  43. luna_sdk/repositories/solutions_repo.py +347 -0
  44. luna_sdk/schemas/__init__.py +4 -0
  45. luna_sdk/schemas/circuit.py +43 -0
  46. luna_sdk/schemas/create/__init__.py +3 -0
  47. luna_sdk/schemas/create/circuit.py +29 -0
  48. luna_sdk/schemas/create/optimization.py +22 -0
  49. luna_sdk/schemas/create/qpu_token.py +26 -0
  50. luna_sdk/schemas/create/qubo.py +19 -0
  51. luna_sdk/schemas/create/solution.py +15 -0
  52. luna_sdk/schemas/enums/__init__.py +0 -0
  53. luna_sdk/schemas/enums/circuit.py +14 -0
  54. luna_sdk/schemas/enums/optimization.py +10 -0
  55. luna_sdk/schemas/enums/problem.py +48 -0
  56. luna_sdk/schemas/enums/qpu_token_type.py +6 -0
  57. luna_sdk/schemas/enums/solution.py +8 -0
  58. luna_sdk/schemas/enums/status.py +10 -0
  59. luna_sdk/schemas/enums/timeframe.py +11 -0
  60. luna_sdk/schemas/error_message.py +12 -0
  61. luna_sdk/schemas/optimization.py +75 -0
  62. luna_sdk/schemas/optimization_formats/__init__.py +0 -0
  63. luna_sdk/schemas/optimization_formats/bqm.py +34 -0
  64. luna_sdk/schemas/optimization_formats/cqm.py +127 -0
  65. luna_sdk/schemas/optimization_formats/lp.py +9 -0
  66. luna_sdk/schemas/optimization_formats/qm.py +30 -0
  67. luna_sdk/schemas/pretty_base.py +49 -0
  68. luna_sdk/schemas/qpu_token.py +60 -0
  69. luna_sdk/schemas/representation.py +19 -0
  70. luna_sdk/schemas/rest/__init__.py +0 -0
  71. luna_sdk/schemas/rest/qpu_token/__init__.py +0 -0
  72. luna_sdk/schemas/rest/qpu_token/token_provider.py +45 -0
  73. luna_sdk/schemas/solution.py +227 -0
  74. luna_sdk/schemas/solver_info.py +11 -0
  75. luna_sdk/schemas/solver_parameters/aws/__init__.py +1 -0
  76. luna_sdk/schemas/solver_parameters/aws/qaoa.py +24 -0
  77. luna_sdk/schemas/solver_parameters/dwave/__init__.py +72 -0
  78. luna_sdk/schemas/solver_parameters/dwave/base.py +409 -0
  79. luna_sdk/schemas/solver_parameters/dwave/dialectic_search.py +31 -0
  80. luna_sdk/schemas/solver_parameters/dwave/kerberos.py +71 -0
  81. luna_sdk/schemas/solver_parameters/dwave/leap_hybrid_bqm.py +19 -0
  82. luna_sdk/schemas/solver_parameters/dwave/leap_hybrid_cqm.py +22 -0
  83. luna_sdk/schemas/solver_parameters/dwave/parallel_tempering.py +30 -0
  84. luna_sdk/schemas/solver_parameters/dwave/parallel_tempering_qpu.py +37 -0
  85. luna_sdk/schemas/solver_parameters/dwave/population_annealing.py +25 -0
  86. luna_sdk/schemas/solver_parameters/dwave/population_annealing_qpu.py +35 -0
  87. luna_sdk/schemas/solver_parameters/dwave/qaga.py +56 -0
  88. luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_qpu.py +19 -0
  89. luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_simulated_annealing.py +22 -0
  90. luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_tabu_search.py +21 -0
  91. luna_sdk/schemas/solver_parameters/dwave/quantum_annealing.py +20 -0
  92. luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_quantum_annealing.py +82 -0
  93. luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_simulated_annealing.py +89 -0
  94. luna_sdk/schemas/solver_parameters/dwave/saga.py +61 -0
  95. luna_sdk/schemas/solver_parameters/dwave/simulated_annealing.py +74 -0
  96. luna_sdk/schemas/solver_parameters/dwave/tabu_search.py +72 -0
  97. luna_sdk/schemas/solver_parameters/fujitsu/__init__.py +20 -0
  98. luna_sdk/schemas/solver_parameters/fujitsu/base.py +47 -0
  99. luna_sdk/schemas/solver_parameters/fujitsu/digital_annealer_cpu.py +129 -0
  100. luna_sdk/schemas/solver_parameters/fujitsu/digital_annealer_v2.py +149 -0
  101. luna_sdk/schemas/solver_parameters/fujitsu/digital_annealer_v3.py +150 -0
  102. luna_sdk/schemas/solver_parameters/fujitsu/partial_config.py +177 -0
  103. luna_sdk/schemas/solver_parameters/ibm/__init__.py +4 -0
  104. luna_sdk/schemas/solver_parameters/ibm/qaoa.py +64 -0
  105. luna_sdk/schemas/solver_parameters/ibm/standard_parameters.py +27 -0
  106. luna_sdk/schemas/solver_parameters/ibm/vqe.py +49 -0
  107. luna_sdk/schemas/solver_parameters/qctrl/__init__.py +1 -0
  108. luna_sdk/schemas/solver_parameters/qctrl/qaoa.py +47 -0
  109. luna_sdk/schemas/transformations/__init__.py +2 -0
  110. luna_sdk/schemas/transformations/bqm.py +33 -0
  111. luna_sdk/schemas/transformations/matrix.py +12 -0
  112. luna_sdk/schemas/use_cases/__init__.py +54 -0
  113. luna_sdk/schemas/use_cases/arbitrage_edge_based.py +49 -0
  114. luna_sdk/schemas/use_cases/arbitrage_node_based.py +54 -0
  115. luna_sdk/schemas/use_cases/base.py +5 -0
  116. luna_sdk/schemas/use_cases/binary_integer_linear_programming.py +53 -0
  117. luna_sdk/schemas/use_cases/binary_paint_shop_problem.py +36 -0
  118. luna_sdk/schemas/use_cases/credit_scoring_feature_selection.py +39 -0
  119. luna_sdk/schemas/use_cases/dynamic_portfolio_optimization.py +63 -0
  120. luna_sdk/schemas/use_cases/exact_cover.py +50 -0
  121. luna_sdk/schemas/use_cases/flight_gate_assignment.py +78 -0
  122. luna_sdk/schemas/use_cases/graph_coloring.py +41 -0
  123. luna_sdk/schemas/use_cases/graph_isomorphism.py +53 -0
  124. luna_sdk/schemas/use_cases/graph_partitioning.py +45 -0
  125. luna_sdk/schemas/use_cases/hamiltonian_cycle.py +48 -0
  126. luna_sdk/schemas/use_cases/induced_subgraph_isomorphism.py +49 -0
  127. luna_sdk/schemas/use_cases/job_shop_scheduling.py +43 -0
  128. luna_sdk/schemas/use_cases/k_medoids_clustering.py +48 -0
  129. luna_sdk/schemas/use_cases/knapsack_integer_weights.py +55 -0
  130. luna_sdk/schemas/use_cases/linear_regression.py +59 -0
  131. luna_sdk/schemas/use_cases/lmwcs.py +80 -0
  132. luna_sdk/schemas/use_cases/longest_path.py +49 -0
  133. luna_sdk/schemas/use_cases/market_graph_clustering.py +60 -0
  134. luna_sdk/schemas/use_cases/max2sat.py +51 -0
  135. luna_sdk/schemas/use_cases/max3sat.py +52 -0
  136. luna_sdk/schemas/use_cases/max_clique.py +59 -0
  137. luna_sdk/schemas/use_cases/max_cut.py +47 -0
  138. luna_sdk/schemas/use_cases/max_independent_set.py +36 -0
  139. luna_sdk/schemas/use_cases/minimal_maximal_matching.py +53 -0
  140. luna_sdk/schemas/use_cases/minimal_spanning_tree.py +87 -0
  141. luna_sdk/schemas/use_cases/minimum_vertex_cover.py +44 -0
  142. luna_sdk/schemas/use_cases/number_partitioning.py +31 -0
  143. luna_sdk/schemas/use_cases/portfolio_optimization.py +45 -0
  144. luna_sdk/schemas/use_cases/portfolio_optimization_ib_tv.py +62 -0
  145. luna_sdk/schemas/use_cases/quadratic_assignment.py +48 -0
  146. luna_sdk/schemas/use_cases/quadratic_knapsack.py +47 -0
  147. luna_sdk/schemas/use_cases/satellite_scheduling.py +72 -0
  148. luna_sdk/schemas/use_cases/sensor_placement.py +57 -0
  149. luna_sdk/schemas/use_cases/set_cover.py +55 -0
  150. luna_sdk/schemas/use_cases/set_packing.py +53 -0
  151. luna_sdk/schemas/use_cases/set_partitioning.py +51 -0
  152. luna_sdk/schemas/use_cases/subgraph_isomorphism.py +56 -0
  153. luna_sdk/schemas/use_cases/subset_sum.py +36 -0
  154. luna_sdk/schemas/use_cases/support_vector_machine.py +63 -0
  155. luna_sdk/schemas/use_cases/traffic_flow.py +34 -0
  156. luna_sdk/schemas/use_cases/travelling_salesman_problem.py +52 -0
  157. luna_sdk/schemas/use_cases/type_aliases.py +11 -0
  158. luna_sdk/schemas/use_cases/weighted_max_cut.py +36 -0
  159. luna_sdk/utils/__init__.py +0 -0
  160. luna_sdk/utils/qpu_tokens.py +52 -0
@@ -0,0 +1,347 @@
1
+ import logging
2
+ import os
3
+ from time import sleep
4
+ from typing import Dict, List, Optional, Union
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from luna_sdk.exceptions.encryption_exception import EncryptionNotSetException
9
+ from luna_sdk.interfaces.solutions_repo_i import ISolutionsRepo
10
+ from luna_sdk.schemas.create.solution import SolutionIn
11
+ from luna_sdk.schemas.enums.solution import SenseEnum
12
+ from luna_sdk.schemas.enums.status import StatusEnum
13
+ from luna_sdk.schemas.enums.timeframe import TimeframeEnum
14
+ from luna_sdk.schemas.qpu_token import TokenProvider
15
+ from luna_sdk.schemas.rest.qpu_token.token_provider import RestAPITokenProvider
16
+ from luna_sdk.schemas.solution import (
17
+ Result,
18
+ Solution,
19
+ UseCaseRepresentation,
20
+ UseCaseResult,
21
+ )
22
+ from luna_sdk.utils.qpu_tokens import extract_qpu_tokens_from_env
23
+
24
+
25
+ class SolutionsRepo(ISolutionsRepo):
26
+ _endpoint = "/solutions"
27
+
28
+ def get(
29
+ self,
30
+ solution_id: str,
31
+ ) -> Solution:
32
+ """
33
+ Retrieve one solution by id.
34
+
35
+ Parameters
36
+ ----------
37
+ solution_id: str
38
+ Id of the solution that should be retrieved
39
+
40
+ Returns
41
+ -------
42
+ Solution
43
+ Solution instance
44
+ """
45
+ response = self._client.get(
46
+ f"{self._endpoint}/{solution_id}",
47
+ )
48
+
49
+ response.raise_for_status()
50
+
51
+ return Solution.model_validate_json(response.text)
52
+
53
+ def get_all(
54
+ self,
55
+ timeframe: Optional[TimeframeEnum] = None,
56
+ limit: int = 50,
57
+ offset: int = 0,
58
+ optimization_id: Optional[str] = None,
59
+ ) -> List[Solution]:
60
+ """
61
+ Get list of available optimizations.
62
+
63
+ Parameters
64
+ ----------
65
+ timeframe: Optional[TimeframeEnum]
66
+ Only return Solutions created within a specified timeframe. Default None.
67
+ limit:
68
+ Limit the number of Optimizations to be returned. Default value 10.
69
+ offset:
70
+ Offset the list of solutions by this amount. Default value 0.
71
+ optimization_id: Optional[str]
72
+ Show solutions for only this optimization id. Default None.
73
+
74
+ Returns
75
+ -------
76
+ List[SolutionOut]
77
+ List of SolutionOut instances.
78
+ """
79
+ params = {}
80
+ if timeframe and timeframe != TimeframeEnum.all_time: # no value == all_time
81
+ params["timeframe"] = timeframe.value
82
+
83
+ if limit < 1:
84
+ # set the minimum limit to 1
85
+ limit = 1
86
+
87
+ if optimization_id is not None:
88
+ params["optimization_id"] = str(optimization_id)
89
+
90
+ params["limit"] = str(limit)
91
+ params["offset"] = str(offset)
92
+ response = self._client.get(
93
+ self._endpoint,
94
+ params=params,
95
+ )
96
+
97
+ response.raise_for_status()
98
+
99
+ return [Solution.model_validate(i) for i in response.json()]
100
+
101
+ def delete(self, solution_id: str) -> None:
102
+ """
103
+ Delete one optimization by id.
104
+
105
+ Parameters
106
+ ----------
107
+ solution_id: str
108
+ Id of the optimization that should be deleted
109
+
110
+ Returns
111
+ -------
112
+ """
113
+ self._client.delete(
114
+ f"{self._endpoint}/{solution_id}",
115
+ )
116
+
117
+ def create(
118
+ self,
119
+ optimization_id: str,
120
+ solver_name: str,
121
+ provider: str,
122
+ qpu_tokens: Optional[TokenProvider] = None,
123
+ solver_parameters: Optional[Union[Dict, BaseModel]] = None,
124
+ encryption_key: Optional[str] = None,
125
+ name: Optional[str] = None,
126
+ ) -> Solution:
127
+ """
128
+ Create a solution for an optimization
129
+
130
+ Parameters
131
+ ----------
132
+ optimization_id: str
133
+ The id of the optimization for which solution should be created
134
+ solver_name: str
135
+ The name of the solver to use.
136
+ provider: str
137
+ The name of the QPU provider to use.
138
+ qpu_tokens: Optional[TokenProvider]
139
+ The tokens to be used for the QPU.
140
+ solver_parameters: Optional[Dict]
141
+ Parameters to be passed to the solver.
142
+ encryption_key: Optional[str]
143
+ Encryption key to be used for encryption of QPU tokens.
144
+ name: Optional[str]
145
+ Default: None, The name of the solution to create.
146
+
147
+ Returns
148
+ -------
149
+ SolutionOut
150
+ Returns the location where the solution can be found once solving is complete.
151
+ """
152
+ if solver_parameters is None:
153
+ solver_parameters = {}
154
+ if qpu_tokens is not None:
155
+ rest_qpu_tokens = RestAPITokenProvider.from_sdk_token_provider(qpu_tokens)
156
+ else:
157
+ rest_qpu_tokens = None
158
+ # try to retrieve qpu tokens from env variables
159
+ if rest_qpu_tokens is None:
160
+ rest_qpu_tokens = extract_qpu_tokens_from_env()
161
+
162
+ encryption_key = encryption_key or os.environ.get("LUNA_ENCRYPTION_KEY")
163
+ if encryption_key is None:
164
+ raise EncryptionNotSetException
165
+ solution_in = SolutionIn(
166
+ optimization=optimization_id,
167
+ solver_name=solver_name,
168
+ provider=provider,
169
+ parameters=(
170
+ solver_parameters.model_dump()
171
+ if isinstance(solver_parameters, BaseModel)
172
+ else solver_parameters
173
+ ),
174
+ qpu_tokens=rest_qpu_tokens,
175
+ encryption_key=encryption_key,
176
+ name=name,
177
+ )
178
+ response = self._client.post(
179
+ self._endpoint, content=solution_in.model_dump_json()
180
+ )
181
+ response.raise_for_status()
182
+
183
+ return Solution.model_validate_json(response.text)
184
+
185
+ def create_blocking(
186
+ self,
187
+ optimization_id: str,
188
+ solver_name: str,
189
+ provider: str,
190
+ qpu_tokens: Optional[TokenProvider] = None,
191
+ solver_parameters: Optional[Union[Dict, BaseModel]] = None,
192
+ sleep_time_max: float = 60.0,
193
+ sleep_time_increment: float = 5.0,
194
+ sleep_time_initial: float = 5.0,
195
+ encryption_key: Optional[str] = None,
196
+ name: Optional[str] = None,
197
+ ) -> Solution:
198
+ """
199
+ Create a solution for optimization. This method will block your code until the solution is ready.
200
+ Depending on the problem size, this can take a long time.
201
+
202
+ Parameters
203
+ ----------
204
+ optimization_id: str
205
+ The id of the optimization for which solution should be created
206
+ solver_name: str
207
+ The name of the solver to use.
208
+ provider: str
209
+ The name of the provider to use.
210
+
211
+ qpu_tokens: Optional[TokenProvider] = None
212
+ The tokens to be used for the QPU.
213
+ solver_parameters: Optional[Dict]
214
+ Parameters to be passed to the solver.
215
+
216
+ sleep_time_max: float
217
+ Maximum time to sleep between requests.
218
+ sleep_time_increment: float
219
+ Increment of sleep time between requests. Initial sleep time will be
220
+ sleep_time_initial: float
221
+ Initial sleep time.
222
+ encryption_key: Optional[str]
223
+ Encryption key to be used for encryption of QPU tokens.
224
+ name: Optional[str]
225
+ Default: None, The name of the solution to create.
226
+ Returns
227
+ -------
228
+ SolutionOut
229
+ Returns the location where the solution can be found once solving is complete.
230
+ """
231
+ # First create the solution
232
+
233
+ params: Optional[Union[Dict, BaseModel]] = None
234
+ if solver_parameters is not None:
235
+ params = solver_parameters
236
+ if isinstance(solver_parameters, BaseModel):
237
+ params = solver_parameters.dict()
238
+
239
+ solution: Solution = self.create(
240
+ optimization_id=optimization_id,
241
+ solver_name=solver_name,
242
+ provider=provider,
243
+ solver_parameters=params,
244
+ qpu_tokens=qpu_tokens,
245
+ encryption_key=encryption_key,
246
+ name=name,
247
+ )
248
+ # times are in sec
249
+
250
+ cur_sleep_time: float
251
+
252
+ if sleep_time_initial > 0.0:
253
+ cur_sleep_time = sleep_time_initial
254
+ else:
255
+ cur_sleep_time = 5.0
256
+ logging.warning(
257
+ f"Invalid sleep_time_initial: {sleep_time_initial}, setting it to default value {cur_sleep_time}"
258
+ )
259
+
260
+ while (
261
+ solution.status == StatusEnum.REQUESTED
262
+ or solution.status == StatusEnum.IN_PROGRESS
263
+ ):
264
+ logging.info(
265
+ f"Waiting for solution {solution.id} to complete, "
266
+ f"current status: {solution.status}"
267
+ f", sleeping for {cur_sleep_time} seconds."
268
+ )
269
+ sleep(cur_sleep_time)
270
+ cur_sleep_time += sleep_time_increment
271
+ if cur_sleep_time > sleep_time_max:
272
+ cur_sleep_time = sleep_time_max
273
+
274
+ solution = self.get(solution_id=solution.id)
275
+
276
+ return solution
277
+
278
+ def get_use_case_representation(self, solution_id: str) -> UseCaseRepresentation:
279
+ """
280
+ Get the use-case-specific representation of a solution.
281
+
282
+ Parameters
283
+ ----------
284
+ solution_id: str
285
+ Id of the solution that should be retrieved
286
+
287
+ Returns
288
+ -------
289
+ UseCaseRepresentation
290
+ The use-case-specific representation
291
+ """
292
+ response = self._client.get(f"{self._endpoint}/{solution_id}/representation")
293
+ response.raise_for_status()
294
+ return UseCaseRepresentation.model_validate_json(response.text)
295
+
296
+ def get_best_result(self, solution: Solution) -> Optional[Result]:
297
+ """
298
+ Retrieves the best result from a solution.
299
+
300
+ Parameters
301
+ ----------
302
+ solution : Solution
303
+ The solution received via `solutions.get` or `solutions.get_all`.
304
+
305
+ Returns
306
+ -------
307
+ Result | None
308
+ The best result of the solution. If there are several best solutions with
309
+ the same objective value, return only the first. If the solution results are
310
+ not (yet) available or no the solution sense is `None`, return `None`.
311
+ """
312
+ if solution.results is None or solution.sense is None:
313
+ return None
314
+
315
+ agg = min if solution.sense == SenseEnum.MIN else max
316
+ best_result = agg(solution.results, key=lambda x: x.obj_value)
317
+
318
+ return best_result
319
+
320
+ def get_best_use_case_result(
321
+ self, use_case_representation: UseCaseRepresentation
322
+ ) -> Optional[UseCaseResult]:
323
+ """
324
+ Retrieves the best result from a solution's use case representation.
325
+
326
+ Parameters
327
+ ----------
328
+ use_case_representation : UseCaseRepresentation
329
+ A solution's use case representation.
330
+
331
+ Returns
332
+ -------
333
+ UseCaseResult | None
334
+ The best result of the solution. If there are several best solutions with
335
+ the same objective value, return only the first. If the solution results are
336
+ not (yet) available or no the solution sense is `None`, return `None`.
337
+ """
338
+ if (
339
+ use_case_representation.results is None
340
+ or use_case_representation.sense is None
341
+ ):
342
+ return None
343
+
344
+ agg = min if use_case_representation.sense == SenseEnum.MIN else max
345
+ best_result = agg(use_case_representation.results, key=lambda x: x.obj_value)
346
+
347
+ return best_result
@@ -0,0 +1,4 @@
1
+ from .circuit import CircuitJob, CircuitResult
2
+ from .qpu_token import QpuTokenOut, QpuTokenSource, QpuToken, TokenProvider
3
+ from .solution import Result, Runtime, Solution, UseCaseRepresentation, UseCaseResult
4
+ from .use_cases import * # noqa: F403
@@ -0,0 +1,43 @@
1
+ from typing import Any, Dict, Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from luna_sdk.schemas.enums.circuit import CircuitProviderEnum, CircuitStatusEnum
6
+
7
+
8
+ class CircuitJob(BaseModel):
9
+ """
10
+ Object responsible of retrieving a circuit solution.
11
+
12
+ Attributes
13
+ ----------
14
+ id: str
15
+ Id of the circuit job.
16
+ provider: CircuitProviderEnum
17
+ The provider used to solve this circuit.
18
+ params: Dict[str, Any]
19
+ Additional parameters that were used to create the circuit.
20
+ """
21
+
22
+ id: str
23
+ provider: CircuitProviderEnum
24
+ params: Optional[Dict[str, Any]] = None
25
+
26
+
27
+ class CircuitResult(BaseModel):
28
+ """
29
+ The result of solving the circuit
30
+
31
+ Attributes
32
+ ----------
33
+ result: Optional[Dict[str, Any]]
34
+ The result if the job succeeded. Otherwise None
35
+ error: Optional[str]
36
+ The error message if the job failed. Otherwise None
37
+ status: CircuitStatusEnum
38
+ The job status.
39
+ """
40
+
41
+ status: CircuitStatusEnum
42
+ result: Optional[Dict[str, Any]] = None
43
+ error_message: Optional[str] = None
@@ -0,0 +1,3 @@
1
+ from .circuit import CircuitIn
2
+ from .qpu_token import QpuTokenIn
3
+ from .qubo import QUBOIn
@@ -0,0 +1,29 @@
1
+ from typing import Any, Dict, Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from luna_sdk.schemas.enums.circuit import CircuitProviderEnum
6
+ from luna_sdk.schemas.rest.qpu_token.token_provider import RestAPITokenProvider
7
+
8
+
9
+ class CircuitIn(BaseModel):
10
+ """
11
+ Pydantic model for creation of circuits.
12
+
13
+ Attributes
14
+ ----------
15
+ provider: str
16
+ The provider for circuit solving
17
+ provider: ProviderEnum
18
+ The QASM circuit
19
+ params: Dict[str, Any]
20
+ Additional parameters
21
+ encryption_key: str
22
+ Encryption key to be used for encryption of QPU tokens.
23
+ """
24
+
25
+ provider: CircuitProviderEnum
26
+ circuit: str
27
+ params: Dict[str, Any] = {}
28
+ qpu_tokens: Optional[RestAPITokenProvider] = None
29
+ encryption_key: str
@@ -0,0 +1,22 @@
1
+ from typing import Any, Dict, Generic, Optional, TypeVar
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from luna_sdk.schemas import UseCase
6
+
7
+ # This works but is kind of ugly.
8
+ # In the future, we should find another solution for "dumping" a child of UseCase
9
+ # with the name and params.
10
+ # OptimizationUseCaseIn can still be created like this:
11
+ # opt = OptimizationUseCaseIn(name=name, use_case=use_case)
12
+ # Somehow this tricks pydantic into accepting the child of UseCase and adding
13
+ # it to the model_dump_json. Without the Generic[UseCase] only the name will be
14
+ # added to the model_dump_json
15
+
16
+ _UseCase = TypeVar("_UseCase", bound=UseCase)
17
+
18
+
19
+ class OptimizationUseCaseIn(BaseModel, Generic[_UseCase]):
20
+ name: str
21
+ use_case: _UseCase
22
+ params: Optional[Dict[str, Any]]
@@ -0,0 +1,26 @@
1
+ from pydantic import BaseModel, Extra
2
+
3
+
4
+ class QpuTokenIn(BaseModel):
5
+ """
6
+ Pydantic model for creation QPU token.
7
+
8
+ Attributes
9
+ ----------
10
+ name: str
11
+ Name of the QPU token
12
+ provider: ProviderEnum
13
+ Name of provider
14
+ token: str
15
+ Token
16
+ encryption_key: str
17
+ Encryption key to be used for encryption of QPU tokens.
18
+ """
19
+
20
+ name: str
21
+ provider: str
22
+ token: str
23
+ encryption_key: str
24
+
25
+ class Config:
26
+ extra = Extra.forbid
@@ -0,0 +1,19 @@
1
+ from typing import List
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class QUBOIn(BaseModel):
7
+ """
8
+ Pydantic model for QUBO
9
+
10
+ Attributes
11
+ ----------
12
+ name: str
13
+ Name of the Model
14
+ matrix: List[List[float]]
15
+ QUBO matrix
16
+ """
17
+
18
+ name: str
19
+ matrix: List[List[float]]
@@ -0,0 +1,15 @@
1
+ from typing import Dict, Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from luna_sdk.schemas.rest.qpu_token.token_provider import RestAPITokenProvider
6
+
7
+
8
+ class SolutionIn(BaseModel):
9
+ optimization: str # id of the optimization
10
+ solver_name: str
11
+ provider: str
12
+ parameters: Dict
13
+ qpu_tokens: Optional[RestAPITokenProvider] = None
14
+ encryption_key: str
15
+ name: Optional[str] = None
File without changes
@@ -0,0 +1,14 @@
1
+ from enum import Enum
2
+
3
+
4
+ class CircuitProviderEnum(str, Enum):
5
+ IBM = "ibm"
6
+ QCTRL = "qctrl"
7
+ AWS = "aws"
8
+
9
+
10
+ class CircuitStatusEnum(str, Enum):
11
+ IN_PROGRESS = "IN_PROGRESS"
12
+ DONE = "DONE"
13
+ FAILED = "FAILED"
14
+ CANCELLED = "CANCELLED"
@@ -0,0 +1,10 @@
1
+ from enum import Enum
2
+
3
+
4
+ class InputType(str, Enum):
5
+ bqm_spin = "bqm_spin"
6
+ bqm_binary = "bqm_binary"
7
+ cqm = "cqm"
8
+ lp = "lp"
9
+ aq = "aq"
10
+ qubo = "qubo"
@@ -0,0 +1,48 @@
1
+ from enum import Enum
2
+
3
+
4
+ class UseCaseEnum(str, Enum):
5
+ AEB = "AEB"
6
+ ANB = "ANB"
7
+ BIP = "BIP"
8
+ BPSP = "BPSP"
9
+ CSFS = "CSFS"
10
+ DPO = "DPO"
11
+ EC = "EC"
12
+ FGO = "FGO"
13
+ GC = "GC"
14
+ GI = "GI"
15
+ GP = "GP"
16
+ HC = "HC"
17
+ ISGI = "ISGI"
18
+ JSS = "JSS"
19
+ KMC = "KMC"
20
+ KIW = "KIW"
21
+ LR = "LR"
22
+ LMWCS = "LMWCS"
23
+ LP = "LP"
24
+ MGC = "MGC"
25
+ M2SAT = "M2SAT"
26
+ M3SAT = "M3SAT"
27
+ MCQ = "MCQ"
28
+ MC = "MC"
29
+ MIS = "MIS"
30
+ MMM = "MMM"
31
+ MST = "MST"
32
+ MVC = "MVC"
33
+ NP = "NP"
34
+ PO = "PO"
35
+ POIBTV = "POIBTV"
36
+ QA = "QA"
37
+ QK = "QK"
38
+ SSC = "SSC"
39
+ SPL = "SPL"
40
+ SC = "SC"
41
+ SP = "SP"
42
+ SPP = "SPP"
43
+ SGI = "SGI"
44
+ SSP = "SSP"
45
+ SVM = "SVM"
46
+ TFO = "TFO"
47
+ TSP = "TSP"
48
+ WMC = "WMC"
@@ -0,0 +1,6 @@
1
+ from enum import Enum
2
+
3
+
4
+ class QpuTokenTypeEnum(str, Enum):
5
+ ORGANIZATION = "organization"
6
+ PERSONAL = "personal"
@@ -0,0 +1,8 @@
1
+ from enum import Enum
2
+
3
+
4
+ class SenseEnum(str, Enum):
5
+ """Optimization Sense"""
6
+
7
+ MAX = "max"
8
+ MIN = "min"
@@ -0,0 +1,10 @@
1
+ from enum import Enum
2
+
3
+
4
+ class StatusEnum(str, Enum):
5
+ REQUESTED = "REQUESTED"
6
+ CREATED = "CREATED"
7
+ IN_PROGRESS = "IN_PROGRESS"
8
+ DONE = "DONE"
9
+ FAILED = "FAILED"
10
+ CANCELLED = "CANCELED"
@@ -0,0 +1,11 @@
1
+ from enum import Enum
2
+
3
+
4
+ class TimeframeEnum(str, Enum):
5
+ """Enum class for query filter timeframes"""
6
+
7
+ today = "today"
8
+ this_week = "last_week"
9
+ this_month = "last_month"
10
+ this_year = "last_year"
11
+ all_time = "all_time"
@@ -0,0 +1,12 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class ErrorMessage(BaseModel):
5
+ """
6
+ Error message model. If an error occurs, this model is used to return error messages
7
+ to the client. It contains the internal code and the message that describes
8
+ the error.
9
+ """
10
+
11
+ internal_code: str
12
+ message: str