luna-quantum 0.0.16__py3-none-any.whl → 0.0.33__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 (66) hide show
  1. {luna_quantum-0.0.16.dist-info → luna_quantum-0.0.33.dist-info}/METADATA +2 -1
  2. {luna_quantum-0.0.16.dist-info → luna_quantum-0.0.33.dist-info}/RECORD +64 -58
  3. luna_sdk/controllers/luna_http_client.py +27 -0
  4. luna_sdk/controllers/luna_platform_client.py +41 -23
  5. luna_sdk/controllers/luna_q.py +11 -16
  6. luna_sdk/controllers/luna_solve.py +12 -17
  7. luna_sdk/controllers/luna_transform.py +14 -15
  8. luna_sdk/error/http_error_utils.py +10 -3
  9. luna_sdk/interfaces/circuit_repo_i.py +18 -12
  10. luna_sdk/interfaces/cplex_repo_i.py +25 -10
  11. luna_sdk/interfaces/info_repo_i.py +10 -3
  12. luna_sdk/interfaces/lp_repo_i.py +20 -8
  13. luna_sdk/interfaces/optimization_repo_i.py +35 -60
  14. luna_sdk/interfaces/qpu_token_repo_i.py +40 -38
  15. luna_sdk/interfaces/solutions_repo_i.py +44 -24
  16. luna_sdk/repositories/circuit_repo.py +11 -44
  17. luna_sdk/repositories/cplex_repo.py +32 -20
  18. luna_sdk/repositories/info_repo.py +4 -7
  19. luna_sdk/repositories/lp_repo.py +21 -15
  20. luna_sdk/repositories/optimization_repo.py +36 -210
  21. luna_sdk/repositories/qpu_token_repo.py +52 -128
  22. luna_sdk/repositories/solutions_repo.py +109 -181
  23. luna_sdk/schemas/create/solution.py +2 -2
  24. luna_sdk/schemas/enums/optimization.py +8 -7
  25. luna_sdk/schemas/enums/qpu_token_type.py +1 -1
  26. luna_sdk/schemas/optimization.py +15 -24
  27. luna_sdk/schemas/optimization_formats/qubo.py +8 -0
  28. luna_sdk/schemas/pretty_base.py +10 -3
  29. luna_sdk/schemas/qpu_token.py +4 -5
  30. luna_sdk/schemas/rest/qpu_token/qpu_token_source.py +18 -0
  31. luna_sdk/schemas/rest/qpu_token/token_provider.py +47 -15
  32. luna_sdk/schemas/solution.py +7 -6
  33. luna_sdk/schemas/solver_info.py +31 -1
  34. luna_sdk/schemas/solver_parameters/aws/optimizer_params.py +40 -0
  35. luna_sdk/schemas/solver_parameters/aws/qaoa.py +36 -4
  36. luna_sdk/schemas/solver_parameters/base_parameter.py +5 -0
  37. luna_sdk/schemas/solver_parameters/dwave/base.py +15 -14
  38. luna_sdk/schemas/solver_parameters/dwave/dialectic_search.py +3 -2
  39. luna_sdk/schemas/solver_parameters/dwave/kerberos.py +2 -3
  40. luna_sdk/schemas/solver_parameters/dwave/leap_hybrid_bqm.py +2 -2
  41. luna_sdk/schemas/solver_parameters/dwave/leap_hybrid_cqm.py +2 -2
  42. luna_sdk/schemas/solver_parameters/dwave/parallel_tempering.py +2 -3
  43. luna_sdk/schemas/solver_parameters/dwave/parallel_tempering_qpu.py +2 -3
  44. luna_sdk/schemas/solver_parameters/dwave/population_annealing.py +2 -3
  45. luna_sdk/schemas/solver_parameters/dwave/population_annealing_qpu.py +2 -1
  46. luna_sdk/schemas/solver_parameters/dwave/qaga.py +4 -2
  47. luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_qpu.py +2 -3
  48. luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_simulated_annealing.py +2 -3
  49. luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_tabu_search.py +2 -3
  50. luna_sdk/schemas/solver_parameters/dwave/quantum_annealing.py +2 -3
  51. luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_quantum_annealing.py +4 -2
  52. luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_simulated_annealing.py +3 -2
  53. luna_sdk/schemas/solver_parameters/dwave/saga.py +1 -1
  54. luna_sdk/schemas/solver_parameters/dwave/tabu_search.py +3 -1
  55. luna_sdk/schemas/solver_parameters/fujitsu/base.py +5 -4
  56. luna_sdk/schemas/solver_parameters/fujitsu/partial_config.py +7 -5
  57. luna_sdk/schemas/solver_parameters/ibm/standard_parameters.py +121 -7
  58. luna_sdk/schemas/solver_parameters/qctrl/qaoa.py +2 -2
  59. luna_sdk/schemas/wrappers/__init__.py +1 -0
  60. luna_sdk/schemas/wrappers/datetime_wrapper.py +31 -0
  61. luna_sdk/utils/parameter_finder.py +90 -0
  62. luna_sdk/utils/qpu_tokens.py +14 -13
  63. luna_sdk/constants.py +0 -1
  64. luna_sdk/controllers/custom_login_client.py +0 -61
  65. {luna_quantum-0.0.16.dist-info → luna_quantum-0.0.33.dist-info}/LICENSE +0 -0
  66. {luna_quantum-0.0.16.dist-info → luna_quantum-0.0.33.dist-info}/WHEEL +0 -0
@@ -1,9 +1,9 @@
1
1
  import logging
2
2
  import os
3
3
  from time import sleep
4
- from typing import Dict, List, Optional, Union
4
+ from typing import Any, Dict, List, Optional, Type, Union
5
5
 
6
- from pydantic import BaseModel
6
+ from pydantic import BaseModel, ValidationError
7
7
 
8
8
  from luna_sdk.exceptions.encryption_exception import EncryptionNotSetException
9
9
  from luna_sdk.interfaces.solutions_repo_i import ISolutionsRepo
@@ -19,32 +19,15 @@ from luna_sdk.schemas.solution import (
19
19
  UseCaseRepresentation,
20
20
  UseCaseResult,
21
21
  )
22
+ from luna_sdk.utils.parameter_finder import get_parameter_by_solver
22
23
  from luna_sdk.utils.qpu_tokens import extract_qpu_tokens_from_env
23
24
 
24
25
 
25
26
  class SolutionsRepo(ISolutionsRepo):
26
27
  _endpoint = "/solutions"
27
28
 
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
- )
29
+ def get(self, solution_id: str, **kwargs) -> Solution:
30
+ response = self._client.get(f"{self._endpoint}/{solution_id}", **kwargs)
48
31
 
49
32
  response.raise_for_status()
50
33
 
@@ -56,26 +39,8 @@ class SolutionsRepo(ISolutionsRepo):
56
39
  limit: int = 50,
57
40
  offset: int = 0,
58
41
  optimization_id: Optional[str] = None,
42
+ **kwargs,
59
43
  ) -> 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
44
  params = {}
80
45
  if timeframe and timeframe != TimeframeEnum.all_time: # no value == all_time
81
46
  params["timeframe"] = timeframe.value
@@ -89,30 +54,14 @@ class SolutionsRepo(ISolutionsRepo):
89
54
 
90
55
  params["limit"] = str(limit)
91
56
  params["offset"] = str(offset)
92
- response = self._client.get(
93
- self._endpoint,
94
- params=params,
95
- )
57
+ response = self._client.get(self._endpoint, params=params, **kwargs)
96
58
 
97
59
  response.raise_for_status()
98
60
 
99
61
  return [Solution.model_validate(i) for i in response.json()]
100
62
 
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
- )
63
+ def delete(self, solution_id: str, **kwargs) -> None:
64
+ self._client.delete(f"{self._endpoint}/{solution_id}", **kwargs)
116
65
 
117
66
  def create(
118
67
  self,
@@ -120,39 +69,16 @@ class SolutionsRepo(ISolutionsRepo):
120
69
  solver_name: str,
121
70
  provider: str,
122
71
  qpu_tokens: Optional[TokenProvider] = None,
123
- solver_parameters: Optional[Union[Dict, BaseModel]] = None,
72
+ solver_parameters: Optional[Union[Dict[str, Any], BaseModel]] = None,
124
73
  encryption_key: Optional[str] = None,
125
74
  name: Optional[str] = None,
75
+ fail_on_invalid_params: bool = True,
76
+ **kwargs,
126
77
  ) -> 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
78
  if qpu_tokens is not None:
155
- rest_qpu_tokens = RestAPITokenProvider.from_sdk_token_provider(qpu_tokens)
79
+ rest_qpu_tokens = RestAPITokenProvider.from_sdk_token_provider(
80
+ TokenProvider.model_validate(qpu_tokens)
81
+ )
156
82
  else:
157
83
  rest_qpu_tokens = None
158
84
  # try to retrieve qpu tokens from env variables
@@ -162,21 +88,21 @@ class SolutionsRepo(ISolutionsRepo):
162
88
  encryption_key = encryption_key or os.environ.get("LUNA_ENCRYPTION_KEY")
163
89
  if encryption_key is None:
164
90
  raise EncryptionNotSetException
91
+ params = SolutionsRepo.validate_solver_params(
92
+ solver_name, provider, solver_parameters, fail_on_invalid_params
93
+ )
94
+
165
95
  solution_in = SolutionIn(
166
96
  optimization=optimization_id,
167
97
  solver_name=solver_name,
168
98
  provider=provider,
169
- parameters=(
170
- solver_parameters.model_dump()
171
- if isinstance(solver_parameters, BaseModel)
172
- else solver_parameters
173
- ),
99
+ parameters=params,
174
100
  qpu_tokens=rest_qpu_tokens,
175
101
  encryption_key=encryption_key,
176
102
  name=name,
177
103
  )
178
104
  response = self._client.post(
179
- self._endpoint, content=solution_in.model_dump_json()
105
+ self._endpoint, content=solution_in.model_dump_json(), **kwargs
180
106
  )
181
107
  response.raise_for_status()
182
108
 
@@ -188,53 +114,19 @@ class SolutionsRepo(ISolutionsRepo):
188
114
  solver_name: str,
189
115
  provider: str,
190
116
  qpu_tokens: Optional[TokenProvider] = None,
191
- solver_parameters: Optional[Union[Dict, BaseModel]] = None,
117
+ solver_parameters: Optional[Union[Dict[str, Any], BaseModel]] = None,
192
118
  sleep_time_max: float = 60.0,
193
119
  sleep_time_increment: float = 5.0,
194
120
  sleep_time_initial: float = 5.0,
195
121
  encryption_key: Optional[str] = None,
196
122
  name: Optional[str] = None,
123
+ fail_on_invalid_params: bool = True,
124
+ **kwargs,
197
125
  ) -> 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
126
  # 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()
127
+ params = SolutionsRepo.validate_solver_params(
128
+ solver_name, provider, solver_parameters, fail_on_invalid_params
129
+ )
238
130
 
239
131
  solution: Solution = self.create(
240
132
  optimization_id=optimization_id,
@@ -244,6 +136,7 @@ class SolutionsRepo(ISolutionsRepo):
244
136
  qpu_tokens=qpu_tokens,
245
137
  encryption_key=encryption_key,
246
138
  name=name,
139
+ **kwargs,
247
140
  )
248
141
  # times are in sec
249
142
 
@@ -271,44 +164,20 @@ class SolutionsRepo(ISolutionsRepo):
271
164
  if cur_sleep_time > sleep_time_max:
272
165
  cur_sleep_time = sleep_time_max
273
166
 
274
- solution = self.get(solution_id=solution.id)
167
+ solution = self.get(solution_id=solution.id, **kwargs)
275
168
 
276
169
  return solution
277
170
 
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")
171
+ def get_use_case_representation(
172
+ self, solution_id: str, **kwargs
173
+ ) -> UseCaseRepresentation:
174
+ response = self._client.get(
175
+ f"{self._endpoint}/{solution_id}/representation", **kwargs
176
+ )
293
177
  response.raise_for_status()
294
178
  return UseCaseRepresentation.model_validate_json(response.text)
295
179
 
296
180
  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
181
  if solution.results is None or solution.sense is None:
313
182
  return None
314
183
 
@@ -320,21 +189,6 @@ class SolutionsRepo(ISolutionsRepo):
320
189
  def get_best_use_case_result(
321
190
  self, use_case_representation: UseCaseRepresentation
322
191
  ) -> 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
192
  if (
339
193
  use_case_representation.results is None
340
194
  or use_case_representation.sense is None
@@ -345,3 +199,77 @@ class SolutionsRepo(ISolutionsRepo):
345
199
  best_result = agg(use_case_representation.results, key=lambda x: x.obj_value)
346
200
 
347
201
  return best_result
202
+
203
+ @staticmethod
204
+ def validate_solver_params(
205
+ solver: str,
206
+ provider: str,
207
+ solver_parameter: Optional[Union[Dict[str, Any], BaseModel]],
208
+ fail_on_invalid_params: bool = True,
209
+ ) -> Dict[str, Any]:
210
+ """
211
+ This function checks if the params provided are valid for the provided solver
212
+ and provider.
213
+ If no parameter class was found, there will be no check.
214
+
215
+ Parameters
216
+ ----------
217
+ solver: str
218
+ The solver
219
+ provider: str
220
+ The provider
221
+ solver_parameter: Optional[Union[Dict[str, Any], BaseModel]]
222
+ The solver parameter
223
+ fail_on_invalid_params: bool
224
+ Default true.
225
+ If True, a ValueError will be raised, if the solver_parameter are invalid.
226
+ Otherwise, there will only a warning.
227
+
228
+ Returns
229
+ -------
230
+ Dict[str, Any]
231
+ Validated solver params
232
+
233
+ Raises
234
+ -------
235
+ ValidationError
236
+ If the object could not be validated.
237
+
238
+ """
239
+ if solver_parameter is None:
240
+ logging.info(
241
+ "You didn't provide any specific solver parameters, so we chose the "
242
+ "default ones for this solver."
243
+ )
244
+ return {}
245
+
246
+ params: Dict[str, Any]
247
+ if isinstance(solver_parameter, BaseModel):
248
+ params = solver_parameter.dict()
249
+ else:
250
+ params = solver_parameter
251
+
252
+ parameter_class: Optional[Type[BaseModel]] = get_parameter_by_solver(
253
+ solver, provider
254
+ )
255
+
256
+ if parameter_class is None:
257
+ logging.info(
258
+ f"SDK was not able to find a parameter for solver {solver} "
259
+ f"and provider {provider}."
260
+ )
261
+ return params
262
+
263
+ try:
264
+ parameter_class.model_validate(params)
265
+
266
+ except ValidationError as e:
267
+ if fail_on_invalid_params:
268
+ raise e
269
+ logging.warning(
270
+ "The validation for the provided solver parameter failed.\n"
271
+ f"Detected error:\n{e}\n"
272
+ "Since continue on error is enabled, no error was raised.\n"
273
+ "Solving with Luna can still fail due to the parameters."
274
+ )
275
+ return params
@@ -1,4 +1,4 @@
1
- from typing import Dict, Optional
1
+ from typing import Dict, Optional, Any
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
@@ -9,7 +9,7 @@ class SolutionIn(BaseModel):
9
9
  optimization: str # id of the optimization
10
10
  solver_name: str
11
11
  provider: str
12
- parameters: Dict
12
+ parameters: Dict[str, Any]
13
13
  qpu_tokens: Optional[RestAPITokenProvider] = None
14
14
  encryption_key: str
15
15
  name: Optional[str] = None
@@ -1,10 +1,11 @@
1
1
  from enum import Enum
2
2
 
3
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"
4
+ class OptFormat(str, Enum):
5
+ """Enumeration of all supported formats."""
6
+
7
+ AQ_MODEL = "AQ_MODEL"
8
+ LP = "LP"
9
+ QUBO = "QUBO_MATRIX"
10
+ CQM = "CQM"
11
+ BQM = "BQM"
@@ -2,5 +2,5 @@ from enum import Enum
2
2
 
3
3
 
4
4
  class QpuTokenTypeEnum(str, Enum):
5
- ORGANIZATION = "organization"
5
+ GROUP = "group"
6
6
  PERSONAL = "personal"
@@ -1,13 +1,14 @@
1
- from datetime import datetime
2
- from typing import Any, Dict, Generic, List, Optional, TypeVar
1
+ from typing import Any, Dict, Generic, Optional, TypeVar
3
2
 
4
- from pydantic import BaseModel, Extra
3
+ from pydantic import BaseModel, ConfigDict
5
4
 
6
- from luna_sdk.schemas.enums.optimization import InputType
5
+ from luna_sdk.schemas.enums.optimization import OptFormat
7
6
  from luna_sdk.schemas.optimization_formats.bqm import BQMSchema
8
7
  from luna_sdk.schemas.optimization_formats.cqm import CQMSchema
9
8
  from luna_sdk.schemas.optimization_formats.lp import LPSchema
9
+ from luna_sdk.schemas.optimization_formats.qubo import QuboSchema
10
10
  from luna_sdk.schemas.pretty_base import PrettyBase
11
+ from luna_sdk.schemas.wrappers import PydanticDatetimeWrapper
11
12
 
12
13
 
13
14
  class Optimization(PrettyBase):
@@ -17,11 +18,11 @@ class Optimization(PrettyBase):
17
18
  ----------
18
19
  id: str
19
20
  Id of the optimization
20
- created_date: Optional[datetime]
21
+ created_date: Optional[DatetimeWrapper]
21
22
  Date when optimization was created
22
23
  created_by: Optional[str]
23
24
  Id of the user who created optimization
24
- modified_date: Optional[datetime]
25
+ modified_date: Optional[DatetimeWrapper]
25
26
  Date when optimization was modified
26
27
  modified_by: Optional[str]
27
28
  Id of the user who modified optimization
@@ -29,28 +30,15 @@ class Optimization(PrettyBase):
29
30
 
30
31
  id: str
31
32
  name: Optional[str] = None
32
- created_date: datetime
33
+ created_date: PydanticDatetimeWrapper
33
34
  created_by: str
34
- modified_date: Optional[datetime] = None
35
+ modified_date: Optional[PydanticDatetimeWrapper] = None
35
36
  modified_by: Optional[str] = None
36
- input_type: Optional[InputType] = None
37
+ original_format: Optional[OptFormat] = None
37
38
  use_case_name: Optional[str] = None
38
39
  params: Optional[Dict[str, Any]] = None
39
40
 
40
- class Config:
41
- extra = Extra.ignore
42
- from_attributes = False
43
-
44
-
45
- class OptimizationQubo(BaseModel):
46
- id: str
47
- name: Optional[str] = None
48
- created_date: datetime
49
- created_by: str
50
- modified_date: Optional[datetime] = None
51
- modified_by: Optional[str] = None
52
-
53
- matrix: List[List[float]]
41
+ model_config = ConfigDict(extra="ignore", from_attributes=False)
54
42
 
55
43
 
56
44
  class OptimizationBQM(Optimization, BQMSchema): ...
@@ -62,10 +50,13 @@ class OptimizationCQM(Optimization, CQMSchema): ...
62
50
  class OptimizationLP(Optimization, LPSchema): ...
63
51
 
64
52
 
65
- class OptimizationUseCase(Optimization, BQMSchema):
53
+ class OptimizationUseCase(Optimization, QuboSchema):
66
54
  use_case: Dict[str, Any]
67
55
 
68
56
 
57
+ class OptimizationQubo(Optimization, QuboSchema): ...
58
+
59
+
69
60
  T = TypeVar("T")
70
61
 
71
62
 
@@ -0,0 +1,8 @@
1
+ from typing import List
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class QuboSchema(BaseModel):
7
+ matrix: List[List[float]]
8
+ offset: float
@@ -1,3 +1,5 @@
1
+ from datetime import datetime
2
+
1
3
  from pydantic import BaseModel
2
4
 
3
5
 
@@ -8,10 +10,15 @@ class PrettyBase(BaseModel):
8
10
  for key, value in data.items():
9
11
  output += " " * indent + str(key) + ":"
10
12
  if isinstance(value, dict):
11
- output += "\n"
12
- output += self._pretty_print(value, indent + 1)
13
+ if value == {}:
14
+ output += " {}\n"
15
+ else:
16
+ output += "\n"
17
+ output += self._pretty_print(value, indent + 1)
18
+ elif isinstance(value, datetime):
19
+ output += f" {value.strftime('%Y-%m-%d %H:%M:%S (%Z)')}\n"
13
20
  else:
14
- output += " " + str(value) + "\n"
21
+ output += f" {value}\n"
15
22
  return output
16
23
 
17
24
  def __str__(self):
@@ -3,6 +3,8 @@ from typing import Optional
3
3
 
4
4
  from pydantic import BaseModel, Extra
5
5
 
6
+ from luna_sdk.schemas.enums.qpu_token_type import QpuTokenTypeEnum
7
+
6
8
 
7
9
  class QpuTokenSource(str, Enum):
8
10
  # token currently passed in from the API call (not stored by us)
@@ -10,7 +12,7 @@ class QpuTokenSource(str, Enum):
10
12
  # stored token in user account
11
13
  PERSONAL = "personal"
12
14
  # stored token in group account
13
- ORGANIZATION = "organization"
15
+ GROUP = "group"
14
16
 
15
17
 
16
18
  class QpuToken(BaseModel):
@@ -42,18 +44,15 @@ class QpuTokenOut(BaseModel):
42
44
 
43
45
  Attributes
44
46
  ----------
45
- id: str
46
- Id of the QPU token
47
47
  name: Optional[str]
48
48
  Name of the QPU token
49
49
  provider: ProviderEnum
50
50
  Name of provider: dwave | ibm
51
51
  """
52
52
 
53
- id: str
54
-
55
53
  name: str
56
54
  provider: str
55
+ token_type: QpuTokenTypeEnum
57
56
 
58
57
  class Config:
59
58
  extra = Extra.ignore
@@ -0,0 +1,18 @@
1
+ from enum import Enum
2
+
3
+
4
+ class _RESTQpuTokenSource(str, Enum):
5
+ """
6
+ This schema allow us not to change entire backend,
7
+ but just sync SDK and everything else in terms of qpu token source.
8
+ Currently, the difference is that
9
+ SDK has group qpu token source
10
+ and backend has organization qpu token source which are mapped to each other.
11
+ """
12
+
13
+ # token currently passed in from the API call (not stored by us)
14
+ INLINE = "inline"
15
+ # stored token in user account
16
+ PERSONAL = "personal"
17
+ # stored token in group account
18
+ ORGANIZATION = "organization"