luna-quantum 0.0.33__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.33.dist-info → luna_quantum-0.10.1.dist-info}/METADATA +1 -1
- {luna_quantum-0.0.33.dist-info → luna_quantum-0.10.1.dist-info}/RECORD +25 -23
- luna_sdk/controllers/luna_platform_client.py +1 -1
- luna_sdk/exceptions/encryption_exception.py +0 -6
- luna_sdk/interfaces/circuit_repo_i.py +0 -6
- luna_sdk/interfaces/qpu_token_repo_i.py +200 -6
- luna_sdk/interfaces/solutions_repo_i.py +23 -6
- luna_sdk/repositories/circuit_repo.py +0 -11
- luna_sdk/repositories/qpu_token_repo.py +152 -37
- luna_sdk/repositories/solutions_repo.py +6 -8
- luna_sdk/schemas/create/__init__.py +1 -0
- luna_sdk/schemas/create/circuit.py +0 -3
- luna_sdk/schemas/create/qpu_token.py +0 -3
- luna_sdk/schemas/create/qpu_token_time_quota.py +25 -0
- luna_sdk/schemas/create/solution.py +0 -1
- luna_sdk/schemas/enums/status.py +2 -1
- luna_sdk/schemas/optimization.py +44 -0
- luna_sdk/schemas/qpu_token_time_quota.py +26 -0
- luna_sdk/schemas/solution.py +93 -35
- luna_sdk/schemas/solver_parameters/dwave/base.py +4 -1
- luna_sdk/schemas/solver_parameters/dwave/quantum_annealing.py +13 -0
- luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_quantum_annealing.py +13 -1
- luna_sdk/schemas/solver_parameters/dwave/tabu_search.py +2 -4
- {luna_quantum-0.0.33.dist-info → luna_quantum-0.10.1.dist-info}/LICENSE +0 -0
- {luna_quantum-0.0.33.dist-info → luna_quantum-0.10.1.dist-info}/WHEEL +0 -0
|
@@ -1,20 +1,20 @@
|
|
|
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
|
|
8
8
|
luna_sdk/error/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
luna_sdk/error/http_error_utils.py,sha256=qZ4a43GVR35-bn3QTVmGZBJzEjieo43r36M2G5rfIyw,3509
|
|
10
10
|
luna_sdk/exceptions/__init__.py,sha256=DSKaPN374rR2zccmpLvlqntxDsjFwgSexXtva795ae0,52
|
|
11
|
-
luna_sdk/exceptions/encryption_exception.py,sha256=
|
|
11
|
+
luna_sdk/exceptions/encryption_exception.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
luna_sdk/exceptions/luna_exception.py,sha256=m7U3qFpP9Sc77Z3RG9I4bQXsJSQuVeBLvfHQWziC9sQ,114
|
|
13
13
|
luna_sdk/exceptions/luna_server_exception.py,sha256=y4J1TzfMF_kmuh5g8hpP2k_SnV0acaxks8lg5EOvo0I,639
|
|
14
14
|
luna_sdk/exceptions/timeout_exception.py,sha256=ppEGsUk-6NtBy2-RyBfzjR1IhDmIwPWwg03BOsET4OA,367
|
|
15
15
|
luna_sdk/exceptions/transformation.py,sha256=lykEeWonvfvWAyU2DoKzR-GtFc-KEAvrfWlnWT9ylqc,381
|
|
16
16
|
luna_sdk/interfaces/__init__.py,sha256=WwAzuNWP6SNMJk_U_Hqc5U2mRsG2_m-sSQZPMYUDWfY,213
|
|
17
|
-
luna_sdk/interfaces/circuit_repo_i.py,sha256=
|
|
17
|
+
luna_sdk/interfaces/circuit_repo_i.py,sha256=Y3PZQDILT016UNwORBg51sgHFnDxMTgfQ0JXmEowoK0,1642
|
|
18
18
|
luna_sdk/interfaces/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
luna_sdk/interfaces/clients/client_i.py,sha256=_I8mTIfavI3Yv7TPD9HsTxF3uI4WzDucFvgEb2EtOAo,185
|
|
20
20
|
luna_sdk/interfaces/clients/luna_q_i.py,sha256=_DHDirve9yoVO8zb5i3WkTMx-LPu9TtasjF4OUfCaRw,765
|
|
@@ -24,36 +24,37 @@ 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
|
-
luna_sdk/repositories/circuit_repo.py,sha256=
|
|
32
|
+
luna_sdk/repositories/circuit_repo.py,sha256=gpjEmCRrl8UghJrelOt6VOULIJmM-thJAhf8oaA5Ckg,1964
|
|
33
33
|
luna_sdk/repositories/cplex_repo.py,sha256=6vlx6YTJoDSWFSZDDNrPk3E7pa5WWGqG25bhTwQdqHQ,5098
|
|
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=
|
|
42
|
-
luna_sdk/schemas/create/circuit.py,sha256=
|
|
41
|
+
luna_sdk/schemas/create/__init__.py,sha256=WTthzwyS0PI2zSENoHp7EWLciLz_DyFebCzSCFVensU,144
|
|
42
|
+
luna_sdk/schemas/create/circuit.py,sha256=zYtM6SV1QH4JzjYaAhrGNjdNn8EDYsdG1QKwayTqkEY,643
|
|
43
43
|
luna_sdk/schemas/create/optimization.py,sha256=Z9pKoD0y6BjKvl8gQ6XK76bdvq8etvcoNU4RwxnUvHA,759
|
|
44
|
-
luna_sdk/schemas/create/qpu_token.py,sha256=
|
|
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
|
-
luna_sdk/schemas/create/solution.py,sha256=
|
|
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
|
|
48
49
|
luna_sdk/schemas/enums/circuit.py,sha256=smz_DouDo_K8rs4N5aIOj2PS9w6DX1CFYX0bv6f6JFw,252
|
|
49
50
|
luna_sdk/schemas/enums/optimization.py,sha256=XtFdcfLxGe-MAL64itjxszhRkTcUzUf83tO-5DBVLeY,198
|
|
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,19 +63,20 @@ 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
|
|
74
76
|
luna_sdk/schemas/solver_parameters/aws/qaoa.py,sha256=Mc7zfdWgLxh2Kb0r5OmL3RIkYlB1mnu6jUpmfYG2BBg,2290
|
|
75
77
|
luna_sdk/schemas/solver_parameters/base_parameter.py,sha256=v8nk1aVKW_MaePxxNXXb3hcVDtzkQF1sGlvZ2YXXJVI,123
|
|
76
78
|
luna_sdk/schemas/solver_parameters/dwave/__init__.py,sha256=yHsBQ5d1mCS90Y1JcTCOPjNCrEiGT23wI9GyPnYlIqo,2453
|
|
77
|
-
luna_sdk/schemas/solver_parameters/dwave/base.py,sha256=
|
|
79
|
+
luna_sdk/schemas/solver_parameters/dwave/base.py,sha256=z3zWZQAqDJU5dVY5sYTMe8Sxq92SIjhWlfBAmbsowE4,17364
|
|
78
80
|
luna_sdk/schemas/solver_parameters/dwave/dialectic_search.py,sha256=CnXg7rcZ7mHkbSLrYXPot3-73YiWTRhkhyRmjZ_pvvs,1205
|
|
79
81
|
luna_sdk/schemas/solver_parameters/dwave/kerberos.py,sha256=OPzCgo9h5845R3Sg_TrSkwp4gjoRKEHxhAhSdcJxY6c,2674
|
|
80
82
|
luna_sdk/schemas/solver_parameters/dwave/leap_hybrid_bqm.py,sha256=foPfMJLQ0enO3omknKuqIxfZTXd9oIbfi_e-N0o2tmM,637
|
|
@@ -87,12 +89,12 @@ luna_sdk/schemas/solver_parameters/dwave/qaga.py,sha256=gVucZ_1feFb7aKl6W2m34_Hx
|
|
|
87
89
|
luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_qpu.py,sha256=d72lNLdtD-G6WtVGwqmCse9r_O3inDAbLc6tbDlyu-Y,554
|
|
88
90
|
luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_simulated_annealing.py,sha256=wo5Gt6A-N7APE2Nhz_eOhxmW7P_IYTzvdDKe-4kIMn4,976
|
|
89
91
|
luna_sdk/schemas/solver_parameters/dwave/qbsolv_like_tabu_search.py,sha256=5r5piwo5BsAAlXmyqYMxXZDvgVTvjdJ2hVMr7-7h_lk,840
|
|
90
|
-
luna_sdk/schemas/solver_parameters/dwave/quantum_annealing.py,sha256=
|
|
91
|
-
luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_quantum_annealing.py,sha256=
|
|
92
|
+
luna_sdk/schemas/solver_parameters/dwave/quantum_annealing.py,sha256=V00ZV2XMaYv9TZSezFm36kDUgiHpwBKG6K2t38ebgvY,1008
|
|
93
|
+
luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_quantum_annealing.py,sha256=Y04GIwLAergf-6QXSsdZzdhuxYPsSwTf0Np9ahCwUTQ,4117
|
|
92
94
|
luna_sdk/schemas/solver_parameters/dwave/repeated_reverse_simulated_annealing.py,sha256=UeLr2MnPS3zTBQgH6eq5hYvPJpOjQjqG-shHuQ8Ct0M,4569
|
|
93
95
|
luna_sdk/schemas/solver_parameters/dwave/saga.py,sha256=pXWGZVXRgSMJRi3-NuyO7moai198cWXeGbvq5We-1EE,3118
|
|
94
96
|
luna_sdk/schemas/solver_parameters/dwave/simulated_annealing.py,sha256=cU2UoN8xo3iM34LJhaLc-tYsCo-RqpOstiktEi79QRU,4047
|
|
95
|
-
luna_sdk/schemas/solver_parameters/dwave/tabu_search.py,sha256=
|
|
97
|
+
luna_sdk/schemas/solver_parameters/dwave/tabu_search.py,sha256=M027TrynHGPFWuzXcBwVaJz3J-Qf38k5poQRVqi7jLw,3885
|
|
96
98
|
luna_sdk/schemas/solver_parameters/fujitsu/__init__.py,sha256=V4CSTiNSmtBvNuQpxiTZqX9T-oV4M8hZGQ_eO5Ro8vU,549
|
|
97
99
|
luna_sdk/schemas/solver_parameters/fujitsu/base.py,sha256=yDM2sLBtg-a5OsD3GqwTd-HMmIwJtubbP_QxQcrkDnA,1813
|
|
98
100
|
luna_sdk/schemas/solver_parameters/fujitsu/digital_annealer_cpu.py,sha256=EBPE7mwtUNs5CmyVkdWV9jQT_YnW8FWsYQ0VyCHBVNM,9747
|
|
@@ -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,,
|
|
@@ -15,7 +15,6 @@ class ICircuitRepo(IRepository, ABC):
|
|
|
15
15
|
provider: CircuitProviderEnum,
|
|
16
16
|
params: Dict[str, Any] = {},
|
|
17
17
|
qpu_tokens: Optional[TokenProvider] = None,
|
|
18
|
-
encryption_key: Optional[str] = None,
|
|
19
18
|
**kwargs,
|
|
20
19
|
) -> CircuitJob:
|
|
21
20
|
"""
|
|
@@ -31,8 +30,6 @@ class ICircuitRepo(IRepository, ABC):
|
|
|
31
30
|
Additional parameters of the circuit.
|
|
32
31
|
qpu_tokens: Optional[TokenProvider]
|
|
33
32
|
The tokens to be used for the QPU.
|
|
34
|
-
encryption_key: Optional[str]
|
|
35
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
36
33
|
**kwargs
|
|
37
34
|
Parameters to pass to `httpx.request`.
|
|
38
35
|
|
|
@@ -47,7 +44,6 @@ class ICircuitRepo(IRepository, ABC):
|
|
|
47
44
|
def get(
|
|
48
45
|
self,
|
|
49
46
|
job: CircuitJob,
|
|
50
|
-
encryption_key: Optional[str] = None,
|
|
51
47
|
**kwargs,
|
|
52
48
|
) -> CircuitResult:
|
|
53
49
|
"""
|
|
@@ -55,8 +51,6 @@ class ICircuitRepo(IRepository, ABC):
|
|
|
55
51
|
|
|
56
52
|
Parameters
|
|
57
53
|
----------
|
|
58
|
-
encryption_key: Optional[str]
|
|
59
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
60
54
|
**kwargs
|
|
61
55
|
Parameters to pass to `httpx.request`.
|
|
62
56
|
|
|
@@ -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):
|
|
@@ -14,7 +16,6 @@ class IQpuTokenRepo(IRepository, ABC):
|
|
|
14
16
|
provider: str,
|
|
15
17
|
token: str,
|
|
16
18
|
token_type: QpuTokenTypeEnum,
|
|
17
|
-
encryption_key: Optional[str] = None,
|
|
18
19
|
**kwargs,
|
|
19
20
|
) -> QpuTokenOut:
|
|
20
21
|
"""
|
|
@@ -32,8 +33,6 @@ class IQpuTokenRepo(IRepository, ABC):
|
|
|
32
33
|
There are two types of QPU tokens: PERSONAL and GROUP.
|
|
33
34
|
All users of a group can use group QPU tokens.
|
|
34
35
|
User QPU tokens can only be used by the user who created them.
|
|
35
|
-
encryption_key: Optional[str]
|
|
36
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
37
36
|
**kwargs
|
|
38
37
|
Parameters to pass to `httpx.request`.
|
|
39
38
|
|
|
@@ -48,7 +47,6 @@ class IQpuTokenRepo(IRepository, ABC):
|
|
|
48
47
|
def get_all(
|
|
49
48
|
self,
|
|
50
49
|
filter_provider: Optional[str] = None,
|
|
51
|
-
name: Optional[str] = None,
|
|
52
50
|
token_type: Optional[QpuTokenTypeEnum] = None,
|
|
53
51
|
limit: Optional[int] = None,
|
|
54
52
|
offset: Optional[int] = None,
|
|
@@ -61,8 +59,6 @@ class IQpuTokenRepo(IRepository, ABC):
|
|
|
61
59
|
----------
|
|
62
60
|
filter_provider: Optional[str]
|
|
63
61
|
The provider for which qpu tokens should be retrieved
|
|
64
|
-
name: Optional[str]
|
|
65
|
-
Name of the QPU token that should be retrieved
|
|
66
62
|
token_type: Optional[QpuTokenTypeEnum]
|
|
67
63
|
If you want to retrieve only user or group QPU tokens
|
|
68
64
|
otherwise all QPU tokens will be retrieved
|
|
@@ -151,3 +147,201 @@ class IQpuTokenRepo(IRepository, ABC):
|
|
|
151
147
|
Parameters to pass to `httpx.request`.
|
|
152
148
|
"""
|
|
153
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
|
|
@@ -108,7 +108,6 @@ class ISolutionsRepo(IRepository, ABC):
|
|
|
108
108
|
provider: str,
|
|
109
109
|
qpu_tokens: Optional[TokenProvider] = None,
|
|
110
110
|
solver_parameters: Optional[Union[Dict[str, Any], BaseModel]] = None,
|
|
111
|
-
encryption_key: Optional[str] = None,
|
|
112
111
|
name: Optional[str] = None,
|
|
113
112
|
fail_on_invalid_params: bool = True,
|
|
114
113
|
**kwargs,
|
|
@@ -128,8 +127,6 @@ class ISolutionsRepo(IRepository, ABC):
|
|
|
128
127
|
The tokens to be used for the QPU.
|
|
129
128
|
solver_parameters: Optional[Union[Dict[str, Any], BaseModel]]
|
|
130
129
|
Parameters to be passed to the solver.
|
|
131
|
-
encryption_key: Optional[str]
|
|
132
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
133
130
|
name: Optional[str]
|
|
134
131
|
Default: None, The name of the solution to create.
|
|
135
132
|
fail_on_invalid_params: bool
|
|
@@ -155,7 +152,6 @@ class ISolutionsRepo(IRepository, ABC):
|
|
|
155
152
|
sleep_time_max: float = 60.0,
|
|
156
153
|
sleep_time_increment: float = 5.0,
|
|
157
154
|
sleep_time_initial: float = 5.0,
|
|
158
|
-
encryption_key: Optional[str] = None,
|
|
159
155
|
name: Optional[str] = None,
|
|
160
156
|
fail_on_invalid_params: bool = True,
|
|
161
157
|
**kwargs,
|
|
@@ -182,8 +178,6 @@ class ISolutionsRepo(IRepository, ABC):
|
|
|
182
178
|
Increment of sleep time between requests. Initial sleep time will be
|
|
183
179
|
sleep_time_initial: float
|
|
184
180
|
Initial sleep time.
|
|
185
|
-
encryption_key: Optional[str]
|
|
186
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
187
181
|
name: Optional[str]
|
|
188
182
|
Default: None, The name of the solution to create.
|
|
189
183
|
fail_on_invalid_params: bool
|
|
@@ -237,3 +231,26 @@ class ISolutionsRepo(IRepository, ABC):
|
|
|
237
231
|
not (yet) available or the solution sense is `None`, `None` is returned.
|
|
238
232
|
"""
|
|
239
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,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import Any, Dict, Optional
|
|
3
3
|
|
|
4
|
-
from luna_sdk.exceptions.encryption_exception import EncryptionNotSetException
|
|
5
4
|
from luna_sdk.interfaces.circuit_repo_i import ICircuitRepo
|
|
6
5
|
from luna_sdk.schemas.circuit import CircuitJob, CircuitResult
|
|
7
6
|
from luna_sdk.schemas.create.circuit import CircuitIn
|
|
@@ -20,7 +19,6 @@ class CircuitRepo(ICircuitRepo):
|
|
|
20
19
|
provider: CircuitProviderEnum,
|
|
21
20
|
params: Dict[str, Any] = {},
|
|
22
21
|
qpu_tokens: Optional[TokenProvider] = None,
|
|
23
|
-
encryption_key: Optional[str] = None,
|
|
24
22
|
**kwargs,
|
|
25
23
|
) -> CircuitJob:
|
|
26
24
|
if qpu_tokens is not None:
|
|
@@ -34,15 +32,11 @@ class CircuitRepo(ICircuitRepo):
|
|
|
34
32
|
if rest_qpu_tokens is None:
|
|
35
33
|
rest_qpu_tokens = extract_qpu_tokens_from_env()
|
|
36
34
|
|
|
37
|
-
encryption_key = encryption_key or os.environ.get("LUNA_ENCRYPTION_KEY")
|
|
38
|
-
if encryption_key is None:
|
|
39
|
-
raise EncryptionNotSetException
|
|
40
35
|
circuit_in: CircuitIn = CircuitIn(
|
|
41
36
|
provider=provider,
|
|
42
37
|
circuit=circuit,
|
|
43
38
|
params=params,
|
|
44
39
|
qpu_tokens=rest_qpu_tokens,
|
|
45
|
-
encryption_key=encryption_key,
|
|
46
40
|
)
|
|
47
41
|
|
|
48
42
|
response = self._client.post(
|
|
@@ -55,16 +49,11 @@ class CircuitRepo(ICircuitRepo):
|
|
|
55
49
|
def get(
|
|
56
50
|
self,
|
|
57
51
|
job: CircuitJob,
|
|
58
|
-
encryption_key: Optional[str] = None,
|
|
59
52
|
**kwargs,
|
|
60
53
|
) -> CircuitResult:
|
|
61
54
|
url = f"{self._endpoint}/{job.id}/{job.provider.value}"
|
|
62
|
-
encryption_key = encryption_key or os.environ.get("LUNA_ENCRYPTION_KEY")
|
|
63
|
-
if encryption_key is None:
|
|
64
|
-
raise EncryptionNotSetException
|
|
65
55
|
if job.params is None:
|
|
66
56
|
job.params = {}
|
|
67
|
-
job.params["encryption_key"] = encryption_key
|
|
68
57
|
response = self._client.get(url, params=job.params, **kwargs)
|
|
69
58
|
|
|
70
59
|
response.raise_for_status()
|
|
@@ -1,14 +1,18 @@
|
|
|
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
|
|
6
|
+
from pydantic import TypeAdapter
|
|
6
7
|
|
|
7
|
-
from luna_sdk.exceptions.encryption_exception import EncryptionNotSetException
|
|
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
|
+
from luna_sdk.schemas.qpu_token_time_quota import QpuTokenTimeQuotaOut
|
|
13
|
+
|
|
14
|
+
_ORGANIZATION_QPU_TOKENS_BACKEND = "shared"
|
|
15
|
+
_PERSONAL_QPU_TOKENS_BACKEND = "private"
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
class QpuTokenRepo(IQpuTokenRepo):
|
|
@@ -22,9 +26,9 @@ class QpuTokenRepo(IQpuTokenRepo):
|
|
|
22
26
|
if token_type is None:
|
|
23
27
|
return f"{self._endpoint}"
|
|
24
28
|
elif token_type == QpuTokenTypeEnum.PERSONAL:
|
|
25
|
-
return f"{self._endpoint}/
|
|
29
|
+
return f"{self._endpoint}/{_PERSONAL_QPU_TOKENS_BACKEND}"
|
|
26
30
|
else:
|
|
27
|
-
return f"{self._endpoint}/
|
|
31
|
+
return f"{self._endpoint}/{_ORGANIZATION_QPU_TOKENS_BACKEND}"
|
|
28
32
|
|
|
29
33
|
def _get_by_name(
|
|
30
34
|
self, name: str, token_type: QpuTokenTypeEnum, **kwargs
|
|
@@ -44,17 +48,12 @@ class QpuTokenRepo(IQpuTokenRepo):
|
|
|
44
48
|
provider: str,
|
|
45
49
|
token: str,
|
|
46
50
|
token_type: QpuTokenTypeEnum,
|
|
47
|
-
encryption_key: Optional[str] = None,
|
|
48
51
|
**kwargs,
|
|
49
52
|
) -> QpuTokenOut:
|
|
50
|
-
encryption_key = encryption_key or os.environ.get("LUNA_ENCRYPTION_KEY")
|
|
51
|
-
if encryption_key is None:
|
|
52
|
-
raise EncryptionNotSetException
|
|
53
53
|
qpu_token = QpuTokenIn(
|
|
54
54
|
name=name,
|
|
55
55
|
provider=provider,
|
|
56
56
|
token=token,
|
|
57
|
-
encryption_key=encryption_key,
|
|
58
57
|
)
|
|
59
58
|
|
|
60
59
|
response: Response = self._client.post(
|
|
@@ -70,7 +69,6 @@ class QpuTokenRepo(IQpuTokenRepo):
|
|
|
70
69
|
def get_all(
|
|
71
70
|
self,
|
|
72
71
|
filter_provider: Optional[str] = None,
|
|
73
|
-
name: Optional[str] = None,
|
|
74
72
|
token_type: Optional[QpuTokenTypeEnum] = None,
|
|
75
73
|
limit: Optional[int] = None,
|
|
76
74
|
offset: Optional[int] = None,
|
|
@@ -80,38 +78,33 @@ class QpuTokenRepo(IQpuTokenRepo):
|
|
|
80
78
|
if filter_provider:
|
|
81
79
|
params["filter_provider"] = filter_provider
|
|
82
80
|
|
|
83
|
-
if name:
|
|
84
|
-
params["name"] = name
|
|
85
81
|
if limit is not None:
|
|
86
82
|
params["limit"] = str(limit)
|
|
87
83
|
if offset is not None:
|
|
88
84
|
params["offset"] = str(offset)
|
|
85
|
+
if token_type == QpuTokenTypeEnum.PERSONAL:
|
|
86
|
+
params["token_type"] = _PERSONAL_QPU_TOKENS_BACKEND
|
|
87
|
+
if token_type == QpuTokenTypeEnum.GROUP:
|
|
88
|
+
params["token_type"] = _ORGANIZATION_QPU_TOKENS_BACKEND
|
|
89
89
|
|
|
90
|
+
response = self._client.get(
|
|
91
|
+
self._endpoint,
|
|
92
|
+
params=params,
|
|
93
|
+
**kwargs,
|
|
94
|
+
)
|
|
95
|
+
ta = TypeAdapter(List[QpuTokenOut])
|
|
90
96
|
to_return: Dict[QpuTokenTypeEnum, List[QpuTokenOut]] = {}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
]
|
|
103
|
-
if token_type is None or token_type == QpuTokenTypeEnum.GROUP:
|
|
104
|
-
response = self._client.get(
|
|
105
|
-
self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP),
|
|
106
|
-
params=params,
|
|
107
|
-
**kwargs,
|
|
108
|
-
)
|
|
109
|
-
response.raise_for_status()
|
|
110
|
-
shared_qpu_tokens = response.json()
|
|
111
|
-
to_return[QpuTokenTypeEnum.GROUP] = [
|
|
112
|
-
QpuTokenOut(**qpu_token, token_type=QpuTokenTypeEnum.GROUP)
|
|
113
|
-
for qpu_token in shared_qpu_tokens
|
|
114
|
-
]
|
|
97
|
+
resp = response.json()
|
|
98
|
+
|
|
99
|
+
shared_tokens = resp.get(_ORGANIZATION_QPU_TOKENS_BACKEND, [])
|
|
100
|
+
for qpu_token in shared_tokens:
|
|
101
|
+
qpu_token["token_type"] = QpuTokenTypeEnum.GROUP
|
|
102
|
+
to_return[QpuTokenTypeEnum.GROUP] = ta.validate_python(shared_tokens)
|
|
103
|
+
|
|
104
|
+
personal_tokens = resp.get(_PERSONAL_QPU_TOKENS_BACKEND, [])
|
|
105
|
+
for qpu_token in personal_tokens:
|
|
106
|
+
qpu_token["token_type"] = QpuTokenTypeEnum.PERSONAL
|
|
107
|
+
to_return[QpuTokenTypeEnum.PERSONAL] = ta.validate_python(personal_tokens)
|
|
115
108
|
|
|
116
109
|
return to_return
|
|
117
110
|
|
|
@@ -148,3 +141,125 @@ class QpuTokenRepo(IQpuTokenRepo):
|
|
|
148
141
|
f"{self._get_endpoint_by_type(token_type)}/{name}", **kwargs
|
|
149
142
|
)
|
|
150
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()
|
|
@@ -5,7 +5,6 @@ from typing import Any, Dict, List, Optional, Type, Union
|
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, ValidationError
|
|
7
7
|
|
|
8
|
-
from luna_sdk.exceptions.encryption_exception import EncryptionNotSetException
|
|
9
8
|
from luna_sdk.interfaces.solutions_repo_i import ISolutionsRepo
|
|
10
9
|
from luna_sdk.schemas.create.solution import SolutionIn
|
|
11
10
|
from luna_sdk.schemas.enums.solution import SenseEnum
|
|
@@ -70,7 +69,6 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
70
69
|
provider: str,
|
|
71
70
|
qpu_tokens: Optional[TokenProvider] = None,
|
|
72
71
|
solver_parameters: Optional[Union[Dict[str, Any], BaseModel]] = None,
|
|
73
|
-
encryption_key: Optional[str] = None,
|
|
74
72
|
name: Optional[str] = None,
|
|
75
73
|
fail_on_invalid_params: bool = True,
|
|
76
74
|
**kwargs,
|
|
@@ -85,9 +83,6 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
85
83
|
if rest_qpu_tokens is None:
|
|
86
84
|
rest_qpu_tokens = extract_qpu_tokens_from_env()
|
|
87
85
|
|
|
88
|
-
encryption_key = encryption_key or os.environ.get("LUNA_ENCRYPTION_KEY")
|
|
89
|
-
if encryption_key is None:
|
|
90
|
-
raise EncryptionNotSetException
|
|
91
86
|
params = SolutionsRepo.validate_solver_params(
|
|
92
87
|
solver_name, provider, solver_parameters, fail_on_invalid_params
|
|
93
88
|
)
|
|
@@ -98,7 +93,6 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
98
93
|
provider=provider,
|
|
99
94
|
parameters=params,
|
|
100
95
|
qpu_tokens=rest_qpu_tokens,
|
|
101
|
-
encryption_key=encryption_key,
|
|
102
96
|
name=name,
|
|
103
97
|
)
|
|
104
98
|
response = self._client.post(
|
|
@@ -118,7 +112,6 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
118
112
|
sleep_time_max: float = 60.0,
|
|
119
113
|
sleep_time_increment: float = 5.0,
|
|
120
114
|
sleep_time_initial: float = 5.0,
|
|
121
|
-
encryption_key: Optional[str] = None,
|
|
122
115
|
name: Optional[str] = None,
|
|
123
116
|
fail_on_invalid_params: bool = True,
|
|
124
117
|
**kwargs,
|
|
@@ -134,7 +127,6 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
134
127
|
provider=provider,
|
|
135
128
|
solver_parameters=params,
|
|
136
129
|
qpu_tokens=qpu_tokens,
|
|
137
|
-
encryption_key=encryption_key,
|
|
138
130
|
name=name,
|
|
139
131
|
**kwargs,
|
|
140
132
|
)
|
|
@@ -273,3 +265,9 @@ class SolutionsRepo(ISolutionsRepo):
|
|
|
273
265
|
"Solving with Luna can still fail due to the parameters."
|
|
274
266
|
)
|
|
275
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)
|
|
@@ -18,12 +18,9 @@ class CircuitIn(BaseModel):
|
|
|
18
18
|
The QASM circuit
|
|
19
19
|
params: Dict[str, Any]
|
|
20
20
|
Additional parameters
|
|
21
|
-
encryption_key: str
|
|
22
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
23
21
|
"""
|
|
24
22
|
|
|
25
23
|
provider: CircuitProviderEnum
|
|
26
24
|
circuit: str
|
|
27
25
|
params: Dict[str, Any] = {}
|
|
28
26
|
qpu_tokens: Optional[RestAPITokenProvider] = None
|
|
29
|
-
encryption_key: str
|
|
@@ -13,14 +13,11 @@ class QpuTokenIn(BaseModel):
|
|
|
13
13
|
Name of provider
|
|
14
14
|
token: str
|
|
15
15
|
Token
|
|
16
|
-
encryption_key: str
|
|
17
|
-
Encryption key to be used for encryption of QPU tokens.
|
|
18
16
|
"""
|
|
19
17
|
|
|
20
18
|
name: str
|
|
21
19
|
provider: str
|
|
22
20
|
token: str
|
|
23
|
-
encryption_key: str
|
|
24
21
|
|
|
25
22
|
class Config:
|
|
26
23
|
extra = Extra.forbid
|
|
@@ -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
|
@@ -38,6 +38,50 @@ class Optimization(PrettyBase):
|
|
|
38
38
|
use_case_name: Optional[str] = None
|
|
39
39
|
params: Optional[Dict[str, Any]] = None
|
|
40
40
|
|
|
41
|
+
verbose: bool = False
|
|
42
|
+
|
|
43
|
+
def __str__(self):
|
|
44
|
+
if self.verbose:
|
|
45
|
+
return self.details()
|
|
46
|
+
return self.subset()
|
|
47
|
+
|
|
48
|
+
def details(self):
|
|
49
|
+
trimmed_keys = [
|
|
50
|
+
"verbose",
|
|
51
|
+
]
|
|
52
|
+
data = self.model_dump()
|
|
53
|
+
output = ""
|
|
54
|
+
data_subset = {key: data[key] for key in data if key not in trimmed_keys}
|
|
55
|
+
ordered_subset = {
|
|
56
|
+
"id": data_subset.pop("id"),
|
|
57
|
+
"name": data_subset.pop("name"),
|
|
58
|
+
"original_format": data_subset.pop("original_format"),
|
|
59
|
+
"created_date": data_subset.pop("created_date"),
|
|
60
|
+
**data_subset,
|
|
61
|
+
}
|
|
62
|
+
output += self._pretty_print(ordered_subset)
|
|
63
|
+
return output
|
|
64
|
+
|
|
65
|
+
def subset(self):
|
|
66
|
+
trimmed_keys = [
|
|
67
|
+
"id",
|
|
68
|
+
"name",
|
|
69
|
+
"original_format",
|
|
70
|
+
"created_date",
|
|
71
|
+
]
|
|
72
|
+
data = self.model_dump()
|
|
73
|
+
output = ""
|
|
74
|
+
data_subset = {key: data[key] for key in data if key in trimmed_keys}
|
|
75
|
+
|
|
76
|
+
ordered_subset = {
|
|
77
|
+
"id": data_subset.pop("id"),
|
|
78
|
+
"name": data_subset.pop("name"),
|
|
79
|
+
"original_format": data_subset.pop("original_format"),
|
|
80
|
+
**data_subset,
|
|
81
|
+
}
|
|
82
|
+
output += self._pretty_print(ordered_subset)
|
|
83
|
+
return output
|
|
84
|
+
|
|
41
85
|
model_config = ConfigDict(extra="ignore", from_attributes=False)
|
|
42
86
|
|
|
43
87
|
|
|
@@ -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
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from datetime import datetime
|
|
1
2
|
from typing import Any, Dict, List, Optional, Union
|
|
2
3
|
|
|
3
4
|
from pydantic import BaseModel
|
|
4
5
|
|
|
6
|
+
from luna_sdk.schemas.enums.optimization import OptFormat
|
|
5
7
|
from luna_sdk.schemas.enums.solution import SenseEnum
|
|
6
8
|
from luna_sdk.schemas.enums.status import StatusEnum
|
|
7
9
|
from luna_sdk.schemas.optimization import Optimization
|
|
@@ -97,7 +99,7 @@ class Solution(PrettyBase):
|
|
|
97
99
|
error_message: Optional[str] = None
|
|
98
100
|
solver_job_info: Optional[str] = None
|
|
99
101
|
|
|
100
|
-
results: Optional[List[Result]]
|
|
102
|
+
results: Optional[List[Result]] = None
|
|
101
103
|
params: Dict[str, Any]
|
|
102
104
|
runtime: Optional[Runtime]
|
|
103
105
|
sense: Optional[SenseEnum]
|
|
@@ -105,45 +107,20 @@ class Solution(PrettyBase):
|
|
|
105
107
|
solver: str
|
|
106
108
|
provider: str
|
|
107
109
|
status: StatusEnum
|
|
110
|
+
status_timeline: Dict[StatusEnum, datetime] = {}
|
|
111
|
+
used_format: Optional[OptFormat] = None
|
|
108
112
|
optimization: Union[Optimization, str]
|
|
109
113
|
representation: Optional[Any] = None
|
|
110
114
|
|
|
111
|
-
|
|
112
|
-
"""Overwrite the default object string representation to use the custom pretty print console representation"""
|
|
113
|
-
data = self.model_dump()
|
|
114
|
-
results = data.pop("results") # Extract and remove results from data
|
|
115
|
-
metadata = data.pop("metadata") # Extract and remove metadata from data
|
|
116
|
-
provider = data["provider"]
|
|
117
|
-
|
|
118
|
-
divider = "--------------------------------------------------------------------------------\n"
|
|
119
|
-
|
|
120
|
-
# Build Meta Data section
|
|
121
|
-
output = f"{divider}META DATA:\n{divider}"
|
|
122
|
-
output += self._pretty_print(data)
|
|
123
|
-
|
|
124
|
-
# Build Results section
|
|
125
|
-
if results:
|
|
126
|
-
output += f"\n\n{divider}RESULTS:\n{divider}"
|
|
127
|
-
for i, result in enumerate(results, start=1):
|
|
128
|
-
r = f"Result {i}:\n"
|
|
129
|
-
r += f" {result}\n"
|
|
130
|
-
output += r
|
|
131
|
-
else:
|
|
132
|
-
output += f"\n\n{divider}RESULTS:\n{divider}"
|
|
133
|
-
output += " No results..\n"
|
|
134
|
-
output += " Solution has status: " + str(self.status.value) + "\n"
|
|
135
|
-
if self.error_message:
|
|
136
|
-
output += " Error message: " + str(self.error_message) + "\n"
|
|
115
|
+
verbose: bool = False
|
|
137
116
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
output += (
|
|
141
|
-
self._pretty_print(metadata)
|
|
142
|
-
if metadata
|
|
143
|
-
else " No metadata from provider..\n"
|
|
144
|
-
)
|
|
117
|
+
is_cancelable: bool = True
|
|
118
|
+
is_cancellation_requested: bool = False
|
|
145
119
|
|
|
146
|
-
|
|
120
|
+
def __str__(self):
|
|
121
|
+
if self.verbose:
|
|
122
|
+
return self.details()
|
|
123
|
+
return self.subset()
|
|
147
124
|
|
|
148
125
|
@property
|
|
149
126
|
def head(self):
|
|
@@ -216,6 +193,87 @@ class Solution(PrettyBase):
|
|
|
216
193
|
|
|
217
194
|
return output
|
|
218
195
|
|
|
196
|
+
def details(self):
|
|
197
|
+
"""Overwrite the default object string representation to use the custom pretty print console representation"""
|
|
198
|
+
data = self.model_dump()
|
|
199
|
+
results = data.pop("results") # Extract and remove results from data
|
|
200
|
+
metadata = data.pop("metadata") # Extract and remove metadata from data
|
|
201
|
+
provider = data["provider"]
|
|
202
|
+
data.pop("verbose") # Remove verbose field from data
|
|
203
|
+
|
|
204
|
+
divider = "--------------------------------------------------------------------------------\n"
|
|
205
|
+
|
|
206
|
+
# Build Meta Data section
|
|
207
|
+
output = f"{divider}META DATA:\n{divider}"
|
|
208
|
+
output += self._pretty_print(data)
|
|
209
|
+
|
|
210
|
+
# Build Results section
|
|
211
|
+
if results:
|
|
212
|
+
output += f"\n\n{divider}RESULTS:\n{divider}"
|
|
213
|
+
for i, result in enumerate(results, start=1):
|
|
214
|
+
r = f"Result {i}:\n"
|
|
215
|
+
r += f" {result}\n"
|
|
216
|
+
output += r
|
|
217
|
+
else:
|
|
218
|
+
output += f"\n\n{divider}RESULTS:\n{divider}"
|
|
219
|
+
output += " No results..\n"
|
|
220
|
+
output += " Solution has status: " + str(self.status.value) + "\n"
|
|
221
|
+
if self.error_message:
|
|
222
|
+
output += " Error message: " + str(self.error_message) + "\n"
|
|
223
|
+
|
|
224
|
+
# Build Provider Meta Data section
|
|
225
|
+
output += f"\n\n{divider}{provider.upper()} META DATA:\n{divider}"
|
|
226
|
+
output += (
|
|
227
|
+
self._pretty_print(metadata)
|
|
228
|
+
if metadata
|
|
229
|
+
else " No metadata from provider..\n"
|
|
230
|
+
)
|
|
231
|
+
return output
|
|
232
|
+
|
|
233
|
+
def subset(self):
|
|
234
|
+
limit = 5
|
|
235
|
+
subset_keys = [
|
|
236
|
+
"id",
|
|
237
|
+
"name",
|
|
238
|
+
"status",
|
|
239
|
+
"solver",
|
|
240
|
+
"provider",
|
|
241
|
+
"runtime",
|
|
242
|
+
"optimization_name",
|
|
243
|
+
"created_date",
|
|
244
|
+
]
|
|
245
|
+
data = self.model_dump()
|
|
246
|
+
data["optimization_name"] = data["optimization"]["name"]
|
|
247
|
+
output = ""
|
|
248
|
+
data_subset = {key: data.get(key) for key in subset_keys if key in data}
|
|
249
|
+
output += self._pretty_print(data_subset)
|
|
250
|
+
|
|
251
|
+
# Build Results section
|
|
252
|
+
results = data.pop("results")
|
|
253
|
+
if results:
|
|
254
|
+
output += "results:\n"
|
|
255
|
+
output += (
|
|
256
|
+
f"{len(results)} results found. Displaying first {limit} results.\n"
|
|
257
|
+
)
|
|
258
|
+
for i, result in enumerate(results, start=1):
|
|
259
|
+
if i > limit:
|
|
260
|
+
output += "....\n"
|
|
261
|
+
break
|
|
262
|
+
r = f"Result {i}:\n"
|
|
263
|
+
r += (
|
|
264
|
+
f" {str(result)[:150]} ....\n"
|
|
265
|
+
if len(str(result)) > 150
|
|
266
|
+
else f" {result}\n"
|
|
267
|
+
)
|
|
268
|
+
output += r
|
|
269
|
+
else:
|
|
270
|
+
output += "results:\n"
|
|
271
|
+
output += " No results..\n"
|
|
272
|
+
output += " Solution has status: " + str(self.status.value) + "\n"
|
|
273
|
+
if self.error_message:
|
|
274
|
+
output += " Error message: " + str(self.error_message) + "\n"
|
|
275
|
+
return output
|
|
276
|
+
|
|
219
277
|
|
|
220
278
|
class UseCaseResult(BaseModel):
|
|
221
279
|
representation: Any
|
|
@@ -376,6 +376,8 @@ class Loop(BaseParameter):
|
|
|
376
376
|
Energy level that the algorithm tries to reach.
|
|
377
377
|
rtol: float
|
|
378
378
|
Relative tolerance for convergence.
|
|
379
|
+
rtol: float
|
|
380
|
+
Relative tolerance for convergence.
|
|
379
381
|
atol: float
|
|
380
382
|
Absolute tolerance for convergence.
|
|
381
383
|
"""
|
|
@@ -383,7 +385,8 @@ class Loop(BaseParameter):
|
|
|
383
385
|
max_iter: Optional[int] = 100
|
|
384
386
|
max_time: int = 5
|
|
385
387
|
convergence: int = 3
|
|
386
|
-
target: Optional[float] =
|
|
388
|
+
target: Optional[float] = None
|
|
389
|
+
rtol: float = DEFAULT_RTOL
|
|
387
390
|
atol: float = DEFAULT_ATOL
|
|
388
391
|
|
|
389
392
|
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
from luna_sdk.schemas.solver_parameters.base_parameter import BaseParameter
|
|
2
2
|
from luna_sdk.schemas.solver_parameters.dwave import Embedding, SamplingParams
|
|
3
|
+
from pydantic import StringConstraints
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
if sys.version_info >= (3, 9):
|
|
8
|
+
from typing import Annotated
|
|
9
|
+
else:
|
|
10
|
+
from typing_extensions import Annotated
|
|
3
11
|
|
|
4
12
|
|
|
5
13
|
class QuantumAnnealingParameters(BaseParameter):
|
|
@@ -13,7 +21,12 @@ class QuantumAnnealingParameters(BaseParameter):
|
|
|
13
21
|
sampling_params: SamplingParams
|
|
14
22
|
Parameters for the sampling. See https://docs.dwavesys.com/docs/latest/c_solver_parameters.html
|
|
15
23
|
for more details.
|
|
24
|
+
qpu_backend: str
|
|
25
|
+
Specific D-Wave quantum processing unit (QPU) for your optimization
|
|
16
26
|
"""
|
|
17
27
|
|
|
18
28
|
embedding: Embedding = Embedding()
|
|
19
29
|
sampling_params: SamplingParams = SamplingParams()
|
|
30
|
+
qpu_backend: Annotated[
|
|
31
|
+
str, StringConstraints(strip_whitespace=True, min_length=1)
|
|
32
|
+
] = "default"
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
from typing import Any, Dict, List, Optional
|
|
2
2
|
|
|
3
|
-
from pydantic import
|
|
3
|
+
from pydantic import Field, StringConstraints
|
|
4
4
|
|
|
5
5
|
from luna_sdk.schemas.solver_parameters.base_parameter import BaseParameter
|
|
6
6
|
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
if sys.version_info >= (3, 9):
|
|
10
|
+
from typing import Annotated
|
|
11
|
+
else:
|
|
12
|
+
from typing_extensions import Annotated
|
|
13
|
+
|
|
7
14
|
|
|
8
15
|
class RRQuantumAnnealingSamplingParams(BaseParameter):
|
|
9
16
|
"""
|
|
@@ -69,6 +76,8 @@ class RepeatedReverseQuantumAnnealingParameters(BaseParameter):
|
|
|
69
76
|
The target energy for the solving process.
|
|
70
77
|
check_trivial: bool
|
|
71
78
|
Whether to check for trivial variables. Checking for trivial variables means an overhead. On the other hand, when set to `False`, trivial variables, i.e., variables without interactions, will lead to a runtime error.
|
|
79
|
+
qpu_backend: str
|
|
80
|
+
Specific D-Wave quantum processing unit (QPU) for your optimization
|
|
72
81
|
"""
|
|
73
82
|
|
|
74
83
|
sampling_params: RRQuantumAnnealingSamplingParams = (
|
|
@@ -82,3 +91,6 @@ class RepeatedReverseQuantumAnnealingParameters(BaseParameter):
|
|
|
82
91
|
max_iter: int = 10
|
|
83
92
|
target: Optional[Any] = None
|
|
84
93
|
check_trivial: bool = True
|
|
94
|
+
qpu_backend: Annotated[
|
|
95
|
+
str, StringConstraints(strip_whitespace=True, min_length=1)
|
|
96
|
+
] = "default"
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
from typing import Any, Optional
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from .base import Tabu
|
|
4
4
|
|
|
5
|
-
from luna_sdk.schemas.solver_parameters.base_parameter import BaseParameter
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
class TabuSearchParameters(BaseParameter):
|
|
6
|
+
class TabuSearchParameters(Tabu):
|
|
9
7
|
"""
|
|
10
8
|
Tabu Search is a heuristic optimization method that works with the help of a tabu list.
|
|
11
9
|
Initially, random states are chosen in the solution landscape.
|
|
File without changes
|
|
File without changes
|