luna-quantum 0.0.37__py3-none-any.whl → 0.10.1__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.
- {luna_quantum-0.0.37.dist-info → luna_quantum-0.10.1.dist-info}/METADATA +1 -1
- {luna_quantum-0.0.37.dist-info → luna_quantum-0.10.1.dist-info}/RECORD +15 -13
- luna_sdk/controllers/luna_platform_client.py +1 -1
- luna_sdk/interfaces/qpu_token_repo_i.py +200 -0
- luna_sdk/interfaces/solutions_repo_i.py +23 -0
- luna_sdk/repositories/qpu_token_repo.py +125 -3
- luna_sdk/repositories/solutions_repo.py +6 -0
- luna_sdk/schemas/create/__init__.py +1 -0
- luna_sdk/schemas/create/qpu_token_time_quota.py +25 -0
- luna_sdk/schemas/enums/status.py +2 -1
- luna_sdk/schemas/optimization.py +6 -7
- luna_sdk/schemas/qpu_token_time_quota.py +26 -0
- luna_sdk/schemas/solution.py +6 -2
- {luna_quantum-0.0.37.dist-info → luna_quantum-0.10.1.dist-info}/LICENSE +0 -0
- {luna_quantum-0.0.37.dist-info → luna_quantum-0.10.1.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
luna_sdk/__init__.py,sha256=9s6JkcSeRF4WtFo80TelzXXHFhX8w7fXiaJr59V9ScM,100
|
|
2
2
|
luna_sdk/controllers/__init__.py,sha256=ivTapH8np5mQeVEevxwsWawCtVSG4Wep72rNp7nEZXw,60
|
|
3
3
|
luna_sdk/controllers/luna_http_client.py,sha256=_q3_o-bjC61uQMnNTfbbGei0eNR_AoIv-2R1cYRfEgU,819
|
|
4
|
-
luna_sdk/controllers/luna_platform_client.py,sha256=
|
|
4
|
+
luna_sdk/controllers/luna_platform_client.py,sha256=TUeK9hlbY3LdYkl0UO2FJtCzGFuU8lshA-kdutkDZlM,2406
|
|
5
5
|
luna_sdk/controllers/luna_q.py,sha256=cv28o2fYDSaI8iAsfMYWtR68mfuUDxY3jmBWY2KnkRk,1199
|
|
6
6
|
luna_sdk/controllers/luna_solve.py,sha256=ioMdB7Rlx-1-XB5WE5OT8oVlO_T1l5T64R-ccaNUCAA,1797
|
|
7
7
|
luna_sdk/controllers/luna_transform.py,sha256=7kdIp5oRMG1NQZ1hBSkcNrj-z6g_2dWvQZ4j8BK3M0A,1337
|
|
@@ -24,9 +24,9 @@ luna_sdk/interfaces/cplex_repo_i.py,sha256=a2CWG1m4YmQAlcM022Xfk09BHVmcd3y2H-GMr
|
|
|
24
24
|
luna_sdk/interfaces/info_repo_i.py,sha256=hCUYNoqjAKwz6l-61XtymX-UboosDX1RaTTiX64EXXc,1345
|
|
25
25
|
luna_sdk/interfaces/lp_repo_i.py,sha256=hixIKvJ8jz9VOUi33B3K2VvFLcR7eKfeooJwktquyhc,3052
|
|
26
26
|
luna_sdk/interfaces/optimization_repo_i.py,sha256=4JZikxWTJZTX4tG85ydSP711WROQ5B8RtbvOp1EDvxE,6202
|
|
27
|
-
luna_sdk/interfaces/qpu_token_repo_i.py,sha256=
|
|
27
|
+
luna_sdk/interfaces/qpu_token_repo_i.py,sha256=oTxYxoeMOPJUV4-U1Fd1kD76EVPGmi1Sp9C1J4cvffY,11418
|
|
28
28
|
luna_sdk/interfaces/repository_i.py,sha256=vJz8pbggkuLLC333qzjepj3TMPh49LUnyh3pJDlcGi0,287
|
|
29
|
-
luna_sdk/interfaces/solutions_repo_i.py,sha256=
|
|
29
|
+
luna_sdk/interfaces/solutions_repo_i.py,sha256=uSAClqt_zfg-k9VvVn8DfkG2vE2NXyCqaxRlaK8mCb4,8012
|
|
30
30
|
luna_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
31
|
luna_sdk/repositories/__init__.py,sha256=HxD02fpzlcIt5YkBHd7LwIp_eE6eFuAz2VDnlrakwJQ,169
|
|
32
32
|
luna_sdk/repositories/circuit_repo.py,sha256=gpjEmCRrl8UghJrelOt6VOULIJmM-thJAhf8oaA5Ckg,1964
|
|
@@ -34,14 +34,15 @@ luna_sdk/repositories/cplex_repo.py,sha256=6vlx6YTJoDSWFSZDDNrPk3E7pa5WWGqG25bhT
|
|
|
34
34
|
luna_sdk/repositories/info_repo.py,sha256=GzRW5RwhRJrNjujw8Y7vJY8vV_tHzbfwXo0viHuxqUM,1270
|
|
35
35
|
luna_sdk/repositories/lp_repo.py,sha256=T44XMbdbW7k9a4z6JgIj1kb0bBZxepn-93vxdZOQa80,4370
|
|
36
36
|
luna_sdk/repositories/optimization_repo.py,sha256=xHjMdXhzdwt9DtZG7AvGtUgOqWH142veOpAzaNe-nxk,6078
|
|
37
|
-
luna_sdk/repositories/qpu_token_repo.py,sha256=
|
|
38
|
-
luna_sdk/repositories/solutions_repo.py,sha256=
|
|
37
|
+
luna_sdk/repositories/qpu_token_repo.py,sha256=_qM9dJB23AR1-Kblx_yJcovYmuYwGcZMjH2va19F8yg,8840
|
|
38
|
+
luna_sdk/repositories/solutions_repo.py,sha256=W-VHmhN6wkL3jSg4FE0IyVLydatLE7LjqI-RhP21XFs,9073
|
|
39
39
|
luna_sdk/schemas/__init__.py,sha256=lTix3zUl2Z8ZLA2BTF4pls5S-kqlVZ3cIdAZwGxPSUI,248
|
|
40
40
|
luna_sdk/schemas/circuit.py,sha256=r3Bv0lyhrvFoI3Gf8eq-PS3kyivTWY3IJmRH0X2LoCk,1067
|
|
41
|
-
luna_sdk/schemas/create/__init__.py,sha256=
|
|
41
|
+
luna_sdk/schemas/create/__init__.py,sha256=WTthzwyS0PI2zSENoHp7EWLciLz_DyFebCzSCFVensU,144
|
|
42
42
|
luna_sdk/schemas/create/circuit.py,sha256=zYtM6SV1QH4JzjYaAhrGNjdNn8EDYsdG1QKwayTqkEY,643
|
|
43
43
|
luna_sdk/schemas/create/optimization.py,sha256=Z9pKoD0y6BjKvl8gQ6XK76bdvq8etvcoNU4RwxnUvHA,759
|
|
44
44
|
luna_sdk/schemas/create/qpu_token.py,sha256=_D_QtYOeZQ6b0lG5ALTDmyr4bU42bUZ8OJ0VdwadMNA,380
|
|
45
|
+
luna_sdk/schemas/create/qpu_token_time_quota.py,sha256=5HyfYuXGZmpqB-j4yuStFc7V3b7niPYHYb0KIuvJAzQ,650
|
|
45
46
|
luna_sdk/schemas/create/qubo.py,sha256=5Y_jWicEnoV82Ubc-f0a_qy9hCuPBumhsGWY8wzMIuA,293
|
|
46
47
|
luna_sdk/schemas/create/solution.py,sha256=zPPgm0wGwfn23ccgBoYs6SMTZNmbT_uO1po_je15WjA,386
|
|
47
48
|
luna_sdk/schemas/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -50,10 +51,10 @@ luna_sdk/schemas/enums/optimization.py,sha256=XtFdcfLxGe-MAL64itjxszhRkTcUzUf83t
|
|
|
50
51
|
luna_sdk/schemas/enums/problem.py,sha256=HWL6Lc1pqPtJ0J-rXkUTL6WHe2fiBY1ctuZvDnx1hmM,754
|
|
51
52
|
luna_sdk/schemas/enums/qpu_token_type.py,sha256=KBRrB8ExuTTmpp48obxdJGWwWEHb7xgq9Ajjwptl1VY,105
|
|
52
53
|
luna_sdk/schemas/enums/solution.py,sha256=Vax6MX62UDwApbwzf1nrhuFWw1Iiq77gUch7_1roCYo,114
|
|
53
|
-
luna_sdk/schemas/enums/status.py,sha256=
|
|
54
|
+
luna_sdk/schemas/enums/status.py,sha256=D0ZEu6Bg0GspDrjujwrtRAmkF50m2cUT-b0MOiAi4sg,227
|
|
54
55
|
luna_sdk/schemas/enums/timeframe.py,sha256=vwoZsgAYGvqF67qdcXMEnHkqbiRcVY5uK-4-ZTFcurI,238
|
|
55
56
|
luna_sdk/schemas/error_message.py,sha256=svCs-mWQsp3BMEhzZFqskbyP6iS78eVUOPaiWFc4sEQ,307
|
|
56
|
-
luna_sdk/schemas/optimization.py,sha256=
|
|
57
|
+
luna_sdk/schemas/optimization.py,sha256=juFzE7UUAnLoLvZneOwpXzzhsSUQ2dpXIX48Bm0Sdzg,3172
|
|
57
58
|
luna_sdk/schemas/optimization_formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
59
|
luna_sdk/schemas/optimization_formats/bqm.py,sha256=rrmiZYe_iEdgBFusJeJfY8PVSxgf1Wv79FgMQUm2YVs,910
|
|
59
60
|
luna_sdk/schemas/optimization_formats/cqm.py,sha256=VZiNJy4yc-8o3gHoH0E-uaNOHj7UfAGCqznTzKBv0NQ,4257
|
|
@@ -62,12 +63,13 @@ luna_sdk/schemas/optimization_formats/qm.py,sha256=yUEZF7FOvXv1Mb5FMiX1q0Rk5w2lt
|
|
|
62
63
|
luna_sdk/schemas/optimization_formats/qubo.py,sha256=YN-VbPGTgqOKJuJ7t_TT8H_WIWr1ifU974K98W9Blao,135
|
|
63
64
|
luna_sdk/schemas/pretty_base.py,sha256=ZyVdwdY5JfmNlfqZDm6MdTs5roNGtv0Pe805r4N25Z4,1845
|
|
64
65
|
luna_sdk/schemas/qpu_token.py,sha256=CFKbAhFgo0G-LO_lameHH4-iOFUJWx9hmMWi3xQwURw,1508
|
|
66
|
+
luna_sdk/schemas/qpu_token_time_quota.py,sha256=tIlYU2i43m93BOaCUrv62baY3RSIScWBqbD0BBlwES4,656
|
|
65
67
|
luna_sdk/schemas/representation.py,sha256=0RKVV0XxHOJZ1o9grxTq5ri3cGLziyCFObDwQuXIOEY,364
|
|
66
68
|
luna_sdk/schemas/rest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
69
|
luna_sdk/schemas/rest/qpu_token/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
70
|
luna_sdk/schemas/rest/qpu_token/qpu_token_source.py,sha256=EPMXHpgxqsQ4uJ1hlwe5gPdSsjuHEuKKAIMtBFgPJ1A,583
|
|
69
71
|
luna_sdk/schemas/rest/qpu_token/token_provider.py,sha256=3Gecn2AmN7E_wAPUac_c55Fg-LwdDKsgbwAN2-0msJU,2985
|
|
70
|
-
luna_sdk/schemas/solution.py,sha256=
|
|
72
|
+
luna_sdk/schemas/solution.py,sha256=bNgd0UpsaQM_TrgTB-CJJiXuTg1ubMJP33y813yd5WY,8818
|
|
71
73
|
luna_sdk/schemas/solver_info.py,sha256=ZUCdTI8zpPZ8EquLYyrLU35pZ4VkzcPUSYeQWkdijHM,799
|
|
72
74
|
luna_sdk/schemas/solver_parameters/aws/__init__.py,sha256=CXjKWzgnP_d1_RvQUfWyaaWvsZ1FxLJN5K61QmRa-uw,33
|
|
73
75
|
luna_sdk/schemas/solver_parameters/aws/optimizer_params.py,sha256=w0eg1SnTpKnuq48YG8JAC1LY0bxsTlZIJ2XbT2ySTHw,1374
|
|
@@ -160,7 +162,7 @@ luna_sdk/schemas/wrappers/datetime_wrapper.py,sha256=6usmPJNRYA4Fe_-0NGwe7RYams4
|
|
|
160
162
|
luna_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
161
163
|
luna_sdk/utils/parameter_finder.py,sha256=LKkd1upH3Djd6eqkcSQ2feNwPUiKi8soYkx6JT1_VSg,2937
|
|
162
164
|
luna_sdk/utils/qpu_tokens.py,sha256=xrh5KSoWzbul-6eRa0ELH9iwEENanE7PIms7jlCt3NY,1641
|
|
163
|
-
luna_quantum-0.
|
|
164
|
-
luna_quantum-0.
|
|
165
|
-
luna_quantum-0.
|
|
166
|
-
luna_quantum-0.
|
|
165
|
+
luna_quantum-0.10.1.dist-info/LICENSE,sha256=rwwuFPLz36oRvjWu2oEeX42Qtn9gmbh7zRC2OqCFNaI,11342
|
|
166
|
+
luna_quantum-0.10.1.dist-info/METADATA,sha256=BD5AD8c3uY615XODFmYbFvnf9_WsLt4P_e5K457-KsM,2311
|
|
167
|
+
luna_quantum-0.10.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
168
|
+
luna_quantum-0.10.1.dist-info/RECORD,,
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
+
from datetime import datetime
|
|
2
3
|
from typing import Dict, List, Optional
|
|
3
4
|
|
|
4
5
|
from luna_sdk.interfaces.repository_i import IRepository
|
|
5
6
|
from luna_sdk.schemas import QpuTokenOut
|
|
6
7
|
from luna_sdk.schemas.enums.qpu_token_type import QpuTokenTypeEnum
|
|
8
|
+
from luna_sdk.schemas.qpu_token_time_quota import QpuTokenTimeQuotaOut
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class IQpuTokenRepo(IRepository, ABC):
|
|
@@ -145,3 +147,201 @@ class IQpuTokenRepo(IRepository, ABC):
|
|
|
145
147
|
Parameters to pass to `httpx.request`.
|
|
146
148
|
"""
|
|
147
149
|
raise NotImplementedError
|
|
150
|
+
|
|
151
|
+
@abstractmethod
|
|
152
|
+
def create_group_time_quota(
|
|
153
|
+
self,
|
|
154
|
+
qpu_token_name: str,
|
|
155
|
+
quota: int,
|
|
156
|
+
start: Optional[datetime] = None,
|
|
157
|
+
end: Optional[datetime] = None,
|
|
158
|
+
**kwargs,
|
|
159
|
+
) -> None:
|
|
160
|
+
"""Create a time quota policy for a shared QPU token that affects every user of
|
|
161
|
+
the group.
|
|
162
|
+
|
|
163
|
+
Parameters
|
|
164
|
+
----------
|
|
165
|
+
qpu_token_name : str
|
|
166
|
+
The name of the qpu token. Currently, only DWave tokens are supported.
|
|
167
|
+
quota : int
|
|
168
|
+
quota : int
|
|
169
|
+
The amount of quota to add. For DWave Quantum Annealing, which is currently
|
|
170
|
+
the only algorithm that supports time quota, this is the qpu access time in
|
|
171
|
+
nanoseconds.
|
|
172
|
+
start : Optional[datetime], optional
|
|
173
|
+
The date and time from which the policy is active. If None, the current date
|
|
174
|
+
and time will be used. If the policy is currently not effective, the token
|
|
175
|
+
cannot be used at all.
|
|
176
|
+
Default: None
|
|
177
|
+
end : Optional[datetime], optional
|
|
178
|
+
The date and time until which the policy is active. If None, the policy if
|
|
179
|
+
effective until 265 days after the start date. If the policy is currently
|
|
180
|
+
not effective, the token cannot be used at all.
|
|
181
|
+
Default: None
|
|
182
|
+
"""
|
|
183
|
+
raise NotImplementedError
|
|
184
|
+
|
|
185
|
+
@abstractmethod
|
|
186
|
+
def get_group_time_quota(
|
|
187
|
+
self, qpu_token_name: str, **kwargs
|
|
188
|
+
) -> Optional[QpuTokenTimeQuotaOut]:
|
|
189
|
+
"""Get the group time quota policy for a qpu token.
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
qpu_token_name : str
|
|
194
|
+
The name of the qpu token.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
Optional[QpuTokenTimeQuotaOut]
|
|
199
|
+
The token policy. None, if no group policy is set on this token.
|
|
200
|
+
"""
|
|
201
|
+
raise NotImplementedError
|
|
202
|
+
|
|
203
|
+
@abstractmethod
|
|
204
|
+
def update_group_time_quota(
|
|
205
|
+
self,
|
|
206
|
+
qpu_token_name: str,
|
|
207
|
+
quota: Optional[int] = None,
|
|
208
|
+
start: Optional[datetime] = None,
|
|
209
|
+
end: Optional[datetime] = None,
|
|
210
|
+
**kwargs,
|
|
211
|
+
) -> None:
|
|
212
|
+
"""Update the details on a group qpu time quota policy.
|
|
213
|
+
|
|
214
|
+
Parameters
|
|
215
|
+
----------
|
|
216
|
+
qpu_token_name : str
|
|
217
|
+
The name of the qpu token.
|
|
218
|
+
quota : Optional[int], optional
|
|
219
|
+
The amount of quota. For DWave Quantum Annealing, which is currently the
|
|
220
|
+
only supported solver, this is the qpu access time in nanoseconds. If None,
|
|
221
|
+
the available quota won't be updated.
|
|
222
|
+
Default: None
|
|
223
|
+
start : Optional[datetime], optional
|
|
224
|
+
The date and time from which the policy is active. If None, the start date
|
|
225
|
+
won't be updated.
|
|
226
|
+
Default: None
|
|
227
|
+
end : Optional[datetime], optional
|
|
228
|
+
The date and time until which the policy is active. If None, the end date
|
|
229
|
+
won't be updated.
|
|
230
|
+
Default: None
|
|
231
|
+
"""
|
|
232
|
+
raise NotImplementedError
|
|
233
|
+
|
|
234
|
+
@abstractmethod
|
|
235
|
+
def delete_group_time_quota(self, qpu_token_name: str, **kwargs) -> None:
|
|
236
|
+
"""Delete the group policy set on a qpu token.
|
|
237
|
+
|
|
238
|
+
Parameters
|
|
239
|
+
----------
|
|
240
|
+
qpu_token_name : str
|
|
241
|
+
The name of the qpu token.
|
|
242
|
+
"""
|
|
243
|
+
raise NotImplementedError
|
|
244
|
+
|
|
245
|
+
@abstractmethod
|
|
246
|
+
def create_user_time_quota(
|
|
247
|
+
self,
|
|
248
|
+
qpu_token_name: str,
|
|
249
|
+
user_email: str,
|
|
250
|
+
quota: int,
|
|
251
|
+
start: Optional[datetime] = None,
|
|
252
|
+
end: Optional[datetime] = None,
|
|
253
|
+
**kwargs,
|
|
254
|
+
) -> None:
|
|
255
|
+
"""Create a time quota policy for a shared QPU token that affects a single user
|
|
256
|
+
of the group.
|
|
257
|
+
|
|
258
|
+
Parameters
|
|
259
|
+
----------
|
|
260
|
+
qpu_token_name : str
|
|
261
|
+
The name of the qpu token. Currently, only DWave tokens are supported.
|
|
262
|
+
user_email : str
|
|
263
|
+
Email of the user for whom to add the policy.
|
|
264
|
+
quota : int
|
|
265
|
+
The amount of quota to add. For DWave Quantum Annealing, which is currently
|
|
266
|
+
the only algorithm that supports time quota, this is the qpu access time in
|
|
267
|
+
nanoseconds.
|
|
268
|
+
start : Optional[datetime], optional
|
|
269
|
+
The date and time from which the policy is active. If None, the current date
|
|
270
|
+
and time will be used. If the policy is currently not effective, the token
|
|
271
|
+
cannot be used at all.
|
|
272
|
+
Default: None
|
|
273
|
+
end : Optional[datetime], optional
|
|
274
|
+
The date and time until which the policy is active. If None, the policy if
|
|
275
|
+
effective until 265 days after the start date. If the policy is currently
|
|
276
|
+
not effective, the token cannot be used at all.
|
|
277
|
+
Default: None
|
|
278
|
+
"""
|
|
279
|
+
raise NotImplementedError
|
|
280
|
+
|
|
281
|
+
@abstractmethod
|
|
282
|
+
def get_user_time_quota(
|
|
283
|
+
self, qpu_token_name: str, user_email: str, **kwargs
|
|
284
|
+
) -> Optional[QpuTokenTimeQuotaOut]:
|
|
285
|
+
"""Get a user-specific time quota policy for a qpu token.
|
|
286
|
+
|
|
287
|
+
Parameters
|
|
288
|
+
----------
|
|
289
|
+
qpu_token_name : str
|
|
290
|
+
The name of the qpu token.
|
|
291
|
+
user_email : str
|
|
292
|
+
Email of the user for whom to get the policy.
|
|
293
|
+
|
|
294
|
+
Returns
|
|
295
|
+
-------
|
|
296
|
+
Optional[QpuTokenTimeQuotaOut]
|
|
297
|
+
The token policy. None, if no policy is set on this token for the specified
|
|
298
|
+
user.
|
|
299
|
+
"""
|
|
300
|
+
raise NotImplementedError
|
|
301
|
+
|
|
302
|
+
@abstractmethod
|
|
303
|
+
def update_user_time_quota(
|
|
304
|
+
self,
|
|
305
|
+
qpu_token_name: str,
|
|
306
|
+
user_email: str,
|
|
307
|
+
quota: Optional[int] = None,
|
|
308
|
+
start: Optional[datetime] = None,
|
|
309
|
+
end: Optional[datetime] = None,
|
|
310
|
+
**kwargs,
|
|
311
|
+
) -> None:
|
|
312
|
+
"""Update the details on a user-specific qpu time quota policy.
|
|
313
|
+
|
|
314
|
+
Parameters
|
|
315
|
+
----------
|
|
316
|
+
qpu_token_name : str
|
|
317
|
+
The name of the qpu token.
|
|
318
|
+
user_email : str
|
|
319
|
+
Email of the user for whom to update the policy.
|
|
320
|
+
quota : Optional[int], optional
|
|
321
|
+
The amount of quota. For DWave Quantum Annealing, which is currently the
|
|
322
|
+
only supported solver, this is the qpu access time in nanoseconds. If None,
|
|
323
|
+
the available quota won't be updated.
|
|
324
|
+
Default: None
|
|
325
|
+
start : Optional[datetime], optional
|
|
326
|
+
The date and time from which the policy is active. If None, the start date
|
|
327
|
+
won't be updated.
|
|
328
|
+
Default: None
|
|
329
|
+
end : Optional[datetime], optional
|
|
330
|
+
The date and time until which the policy is active. If None, the end date
|
|
331
|
+
won't be updated.
|
|
332
|
+
Default: None
|
|
333
|
+
"""
|
|
334
|
+
raise NotImplementedError
|
|
335
|
+
|
|
336
|
+
@abstractmethod
|
|
337
|
+
def delete_user_time_quota(
|
|
338
|
+
self, qpu_token_name: str, user_email: str, **kwargs
|
|
339
|
+
) -> None:
|
|
340
|
+
"""Delete a user-specific policy set on a qpu token.
|
|
341
|
+
|
|
342
|
+
Parameters
|
|
343
|
+
----------
|
|
344
|
+
qpu_token_name : str
|
|
345
|
+
The name of the qpu token.
|
|
346
|
+
"""
|
|
347
|
+
raise NotImplementedError
|
|
@@ -231,3 +231,26 @@ class ISolutionsRepo(IRepository, ABC):
|
|
|
231
231
|
not (yet) available or the solution sense is `None`, `None` is returned.
|
|
232
232
|
"""
|
|
233
233
|
raise NotImplementedError
|
|
234
|
+
|
|
235
|
+
@abstractmethod
|
|
236
|
+
def cancel(
|
|
237
|
+
self,
|
|
238
|
+
solution_id: str,
|
|
239
|
+
**kwargs,
|
|
240
|
+
) -> Solution:
|
|
241
|
+
"""
|
|
242
|
+
Cancel a solve job for an optimization.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
solution_id: str
|
|
247
|
+
The id of the solution which should be canceled.
|
|
248
|
+
**kwargs
|
|
249
|
+
Parameters to pass to `httpx.request`.
|
|
250
|
+
|
|
251
|
+
Returns
|
|
252
|
+
-------
|
|
253
|
+
SolutionOut
|
|
254
|
+
The location where the solution can be found once solving is complete.
|
|
255
|
+
"""
|
|
256
|
+
raise NotImplementedError
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import
|
|
2
|
+
from datetime import datetime
|
|
3
3
|
from typing import Dict, List, Optional
|
|
4
4
|
|
|
5
5
|
from httpx import Response
|
|
@@ -7,9 +7,9 @@ from pydantic import TypeAdapter
|
|
|
7
7
|
|
|
8
8
|
from luna_sdk.interfaces.qpu_token_repo_i import IQpuTokenRepo
|
|
9
9
|
from luna_sdk.schemas import QpuTokenOut
|
|
10
|
-
from luna_sdk.schemas.create import QpuTokenIn
|
|
10
|
+
from luna_sdk.schemas.create import QpuTokenIn, QpuTokenTimeQuotaIn
|
|
11
11
|
from luna_sdk.schemas.enums.qpu_token_type import QpuTokenTypeEnum
|
|
12
|
-
|
|
12
|
+
from luna_sdk.schemas.qpu_token_time_quota import QpuTokenTimeQuotaOut
|
|
13
13
|
|
|
14
14
|
_ORGANIZATION_QPU_TOKENS_BACKEND = "shared"
|
|
15
15
|
_PERSONAL_QPU_TOKENS_BACKEND = "private"
|
|
@@ -141,3 +141,125 @@ class QpuTokenRepo(IQpuTokenRepo):
|
|
|
141
141
|
f"{self._get_endpoint_by_type(token_type)}/{name}", **kwargs
|
|
142
142
|
)
|
|
143
143
|
response.raise_for_status()
|
|
144
|
+
|
|
145
|
+
def create_group_time_quota(
|
|
146
|
+
self,
|
|
147
|
+
qpu_token_name: str,
|
|
148
|
+
quota: int,
|
|
149
|
+
start: Optional[datetime] = None,
|
|
150
|
+
end: Optional[datetime] = None,
|
|
151
|
+
**kwargs,
|
|
152
|
+
) -> None:
|
|
153
|
+
time_quota = QpuTokenTimeQuotaIn(quota=quota, start=start, end=end)
|
|
154
|
+
|
|
155
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
156
|
+
response = self._client.post(
|
|
157
|
+
f"{endpoint}/quota/group/{qpu_token_name}",
|
|
158
|
+
content=time_quota.model_dump_json(),
|
|
159
|
+
**kwargs,
|
|
160
|
+
)
|
|
161
|
+
response.raise_for_status()
|
|
162
|
+
|
|
163
|
+
def get_group_time_quota(
|
|
164
|
+
self, qpu_token_name: str, **kwargs
|
|
165
|
+
) -> Optional[QpuTokenTimeQuotaOut]:
|
|
166
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
167
|
+
response = self._client.get(
|
|
168
|
+
f"{endpoint}/quota/group/{qpu_token_name}", **kwargs
|
|
169
|
+
)
|
|
170
|
+
response.raise_for_status()
|
|
171
|
+
|
|
172
|
+
time_quota_data = response.json()
|
|
173
|
+
|
|
174
|
+
if time_quota_data is None:
|
|
175
|
+
return None
|
|
176
|
+
return QpuTokenTimeQuotaOut.model_validate(time_quota_data)
|
|
177
|
+
|
|
178
|
+
def update_group_time_quota(
|
|
179
|
+
self,
|
|
180
|
+
qpu_token_name: str,
|
|
181
|
+
quota: Optional[int] = None,
|
|
182
|
+
start: Optional[datetime] = None,
|
|
183
|
+
end: Optional[datetime] = None,
|
|
184
|
+
**kwargs,
|
|
185
|
+
) -> None:
|
|
186
|
+
data = {"quota": quota, "start": start, "end": end}
|
|
187
|
+
|
|
188
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
189
|
+
response = self._client.patch(
|
|
190
|
+
f"{endpoint}/quota/group/{qpu_token_name}",
|
|
191
|
+
content=json.dumps(data),
|
|
192
|
+
**kwargs,
|
|
193
|
+
)
|
|
194
|
+
response.raise_for_status()
|
|
195
|
+
|
|
196
|
+
def delete_group_time_quota(self, qpu_token_name: str, **kwargs) -> None:
|
|
197
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
198
|
+
response = self._client.delete(
|
|
199
|
+
f"{endpoint}/quota/group/{qpu_token_name}",
|
|
200
|
+
**kwargs,
|
|
201
|
+
)
|
|
202
|
+
response.raise_for_status()
|
|
203
|
+
|
|
204
|
+
def create_user_time_quota(
|
|
205
|
+
self,
|
|
206
|
+
qpu_token_name: str,
|
|
207
|
+
user_email: str,
|
|
208
|
+
quota: int,
|
|
209
|
+
start: Optional[datetime] = None,
|
|
210
|
+
end: Optional[datetime] = None,
|
|
211
|
+
**kwargs,
|
|
212
|
+
) -> None:
|
|
213
|
+
time_quota = QpuTokenTimeQuotaIn(quota=quota, start=start, end=end)
|
|
214
|
+
|
|
215
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
216
|
+
response = self._client.post(
|
|
217
|
+
f"{endpoint}/quota/user/{qpu_token_name}/{user_email}",
|
|
218
|
+
content=time_quota.model_dump_json(),
|
|
219
|
+
**kwargs,
|
|
220
|
+
)
|
|
221
|
+
response.raise_for_status()
|
|
222
|
+
|
|
223
|
+
def get_user_time_quota(
|
|
224
|
+
self, qpu_token_name: str, user_email: str, **kwargs
|
|
225
|
+
) -> Optional[QpuTokenTimeQuotaOut]:
|
|
226
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
227
|
+
response = self._client.get(
|
|
228
|
+
f"{endpoint}/quota/user/{qpu_token_name}/{user_email}", **kwargs
|
|
229
|
+
)
|
|
230
|
+
response.raise_for_status()
|
|
231
|
+
|
|
232
|
+
time_quota_data = response.json()
|
|
233
|
+
|
|
234
|
+
if time_quota_data is None:
|
|
235
|
+
return None
|
|
236
|
+
return QpuTokenTimeQuotaOut.model_validate(time_quota_data)
|
|
237
|
+
|
|
238
|
+
def update_user_time_quota(
|
|
239
|
+
self,
|
|
240
|
+
qpu_token_name: str,
|
|
241
|
+
user_email: str,
|
|
242
|
+
quota: Optional[int] = None,
|
|
243
|
+
start: Optional[datetime] = None,
|
|
244
|
+
end: Optional[datetime] = None,
|
|
245
|
+
**kwargs,
|
|
246
|
+
) -> None:
|
|
247
|
+
data = {"quota": quota, "start": start, "end": end}
|
|
248
|
+
|
|
249
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
250
|
+
response = self._client.patch(
|
|
251
|
+
f"{endpoint}/quota/user/{qpu_token_name}/{user_email}",
|
|
252
|
+
content=json.dumps(data),
|
|
253
|
+
**kwargs,
|
|
254
|
+
)
|
|
255
|
+
response.raise_for_status()
|
|
256
|
+
|
|
257
|
+
def delete_user_time_quota(
|
|
258
|
+
self, qpu_token_name: str, user_email: str, **kwargs
|
|
259
|
+
) -> None:
|
|
260
|
+
endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
|
|
261
|
+
response = self._client.delete(
|
|
262
|
+
f"{endpoint}/quota/user/{qpu_token_name}/{user_email}",
|
|
263
|
+
**kwargs,
|
|
264
|
+
)
|
|
265
|
+
response.raise_for_status()
|
|
@@ -265,3 +265,9 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
265
265
|
"Solving with Luna can still fail due to the parameters."
|
|
266
266
|
)
|
|
267
267
|
return params
|
|
268
|
+
|
|
269
|
+
def cancel(self, solution_id: str, **kwargs) -> Solution:
|
|
270
|
+
response = self._client.post(f"{self._endpoint}/{solution_id}/cancel", **kwargs)
|
|
271
|
+
|
|
272
|
+
response.raise_for_status()
|
|
273
|
+
return Solution.model_validate_json(response.text)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class QpuTokenTimeQuotaIn(BaseModel):
|
|
8
|
+
"""
|
|
9
|
+
Pydantic model for creating a time quota on a qpu token.
|
|
10
|
+
|
|
11
|
+
Attributes
|
|
12
|
+
----------
|
|
13
|
+
quota: int
|
|
14
|
+
The amount of quota.
|
|
15
|
+
start: datetime | None
|
|
16
|
+
Effective start date of the time quota policy.
|
|
17
|
+
If None, policy will be in effect immediately.
|
|
18
|
+
end: datetime | None
|
|
19
|
+
Effective end date of the time quota policy.
|
|
20
|
+
If None, policy will be in effect until 365 days after the start date.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
quota: int
|
|
24
|
+
start: Optional[datetime]
|
|
25
|
+
end: Optional[datetime]
|
luna_sdk/schemas/enums/status.py
CHANGED
luna_sdk/schemas/optimization.py
CHANGED
|
@@ -56,6 +56,7 @@ class Optimization(PrettyBase):
|
|
|
56
56
|
"id": data_subset.pop("id"),
|
|
57
57
|
"name": data_subset.pop("name"),
|
|
58
58
|
"original_format": data_subset.pop("original_format"),
|
|
59
|
+
"created_date": data_subset.pop("created_date"),
|
|
59
60
|
**data_subset,
|
|
60
61
|
}
|
|
61
62
|
output += self._pretty_print(ordered_subset)
|
|
@@ -63,16 +64,14 @@ class Optimization(PrettyBase):
|
|
|
63
64
|
|
|
64
65
|
def subset(self):
|
|
65
66
|
trimmed_keys = [
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"params",
|
|
71
|
-
"verbose",
|
|
67
|
+
"id",
|
|
68
|
+
"name",
|
|
69
|
+
"original_format",
|
|
70
|
+
"created_date",
|
|
72
71
|
]
|
|
73
72
|
data = self.model_dump()
|
|
74
73
|
output = ""
|
|
75
|
-
data_subset = {key: data[key] for key in data if key
|
|
74
|
+
data_subset = {key: data[key] for key in data if key in trimmed_keys}
|
|
76
75
|
|
|
77
76
|
ordered_subset = {
|
|
78
77
|
"id": data_subset.pop("id"),
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class QpuTokenTimeQuotaOut(BaseModel):
|
|
7
|
+
"""
|
|
8
|
+
Pydantic model for QPU token time quota OUT.
|
|
9
|
+
It contains the data received from the API call.
|
|
10
|
+
|
|
11
|
+
Attributes
|
|
12
|
+
----------
|
|
13
|
+
quota: int
|
|
14
|
+
The total amount of quota available on a qpu token.
|
|
15
|
+
start: datetime
|
|
16
|
+
Effective start date of the time quota policy.
|
|
17
|
+
end: datetime
|
|
18
|
+
Effective end date of the time quota policy.
|
|
19
|
+
quota_used: int
|
|
20
|
+
How much quota has already been used from the totally available amount of quota.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
quota: int
|
|
24
|
+
start: datetime
|
|
25
|
+
end: datetime
|
|
26
|
+
quota_used: int
|
luna_sdk/schemas/solution.py
CHANGED
|
@@ -99,7 +99,7 @@ class Solution(PrettyBase):
|
|
|
99
99
|
error_message: Optional[str] = None
|
|
100
100
|
solver_job_info: Optional[str] = None
|
|
101
101
|
|
|
102
|
-
results: Optional[List[Result]]
|
|
102
|
+
results: Optional[List[Result]] = None
|
|
103
103
|
params: Dict[str, Any]
|
|
104
104
|
runtime: Optional[Runtime]
|
|
105
105
|
sense: Optional[SenseEnum]
|
|
@@ -114,6 +114,9 @@ class Solution(PrettyBase):
|
|
|
114
114
|
|
|
115
115
|
verbose: bool = False
|
|
116
116
|
|
|
117
|
+
is_cancelable: bool = True
|
|
118
|
+
is_cancellation_requested: bool = False
|
|
119
|
+
|
|
117
120
|
def __str__(self):
|
|
118
121
|
if self.verbose:
|
|
119
122
|
return self.details()
|
|
@@ -196,6 +199,7 @@ class Solution(PrettyBase):
|
|
|
196
199
|
results = data.pop("results") # Extract and remove results from data
|
|
197
200
|
metadata = data.pop("metadata") # Extract and remove metadata from data
|
|
198
201
|
provider = data["provider"]
|
|
202
|
+
data.pop("verbose") # Remove verbose field from data
|
|
199
203
|
|
|
200
204
|
divider = "--------------------------------------------------------------------------------\n"
|
|
201
205
|
|
|
@@ -239,7 +243,7 @@ class Solution(PrettyBase):
|
|
|
239
243
|
"created_date",
|
|
240
244
|
]
|
|
241
245
|
data = self.model_dump()
|
|
242
|
-
data["optimization_name"] = data["optimization"]["
|
|
246
|
+
data["optimization_name"] = data["optimization"]["name"]
|
|
243
247
|
output = ""
|
|
244
248
|
data_subset = {key: data.get(key) for key in subset_keys if key in data}
|
|
245
249
|
output += self._pretty_print(data_subset)
|
|
File without changes
|
|
File without changes
|