luna-quantum 1.1.0__cp312-cp312-win_amd64.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.
Files changed (276) hide show
  1. luna_quantum/__init__.py +139 -0
  2. luna_quantum/__init__.pyi +98 -0
  3. luna_quantum/_core.cp312-win_amd64.pyd +0 -0
  4. luna_quantum/_core.pyi +4286 -0
  5. luna_quantum/_utility.py +148 -0
  6. luna_quantum/_utility.pyi +20 -0
  7. luna_quantum/algorithms/__init__.py +1 -0
  8. luna_quantum/aqm_overwrites/__init__.py +3 -0
  9. luna_quantum/aqm_overwrites/model.py +184 -0
  10. luna_quantum/backends/__init__.py +1 -0
  11. luna_quantum/client/__init__.py +0 -0
  12. luna_quantum/client/controllers/__init__.py +4 -0
  13. luna_quantum/client/controllers/luna_http_client.py +37 -0
  14. luna_quantum/client/controllers/luna_platform_client.py +256 -0
  15. luna_quantum/client/controllers/luna_q.py +67 -0
  16. luna_quantum/client/controllers/luna_solve.py +129 -0
  17. luna_quantum/client/error/__init__.py +0 -0
  18. luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
  19. luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
  20. luna_quantum/client/error/luna_error.py +2 -0
  21. luna_quantum/client/error/luna_server_error.py +20 -0
  22. luna_quantum/client/error/timeout_error.py +12 -0
  23. luna_quantum/client/error/transformation_error.py +18 -0
  24. luna_quantum/client/error/utils/__init__.py +0 -0
  25. luna_quantum/client/error/utils/http_error_utils.py +112 -0
  26. luna_quantum/client/interfaces/__init__.py +4 -0
  27. luna_quantum/client/interfaces/clients/__init__.py +25 -0
  28. luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
  29. luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
  30. luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
  31. luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
  32. luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
  33. luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
  34. luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
  35. luna_quantum/client/interfaces/services/__init__.py +0 -0
  36. luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
  37. luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
  38. luna_quantum/client/interfaces/services/service_i.py +56 -0
  39. luna_quantum/client/rest_client/__init__.py +15 -0
  40. luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
  41. luna_quantum/client/rest_client/info_rest_client.py +74 -0
  42. luna_quantum/client/rest_client/model_rest_client.py +216 -0
  43. luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
  44. luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
  45. luna_quantum/client/rest_client/users_rest_client.py +35 -0
  46. luna_quantum/client/schemas/__init__.py +26 -0
  47. luna_quantum/client/schemas/circuit.py +48 -0
  48. luna_quantum/client/schemas/create/__init__.py +15 -0
  49. luna_quantum/client/schemas/create/circuit.py +30 -0
  50. luna_quantum/client/schemas/create/optimization.py +39 -0
  51. luna_quantum/client/schemas/create/qpu_token.py +22 -0
  52. luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
  53. luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
  54. luna_quantum/client/schemas/create/qubo.py +19 -0
  55. luna_quantum/client/schemas/create/solve_job_create.py +43 -0
  56. luna_quantum/client/schemas/enums/__init__.py +0 -0
  57. luna_quantum/client/schemas/enums/call_style.py +13 -0
  58. luna_quantum/client/schemas/enums/circuit.py +42 -0
  59. luna_quantum/client/schemas/enums/model_format.py +11 -0
  60. luna_quantum/client/schemas/enums/problem.py +50 -0
  61. luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
  62. luna_quantum/client/schemas/enums/sense.py +8 -0
  63. luna_quantum/client/schemas/enums/status.py +40 -0
  64. luna_quantum/client/schemas/enums/timeframe.py +11 -0
  65. luna_quantum/client/schemas/error_message.py +14 -0
  66. luna_quantum/client/schemas/model_metadata.py +35 -0
  67. luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
  68. luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
  69. luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
  70. luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
  71. luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
  72. luna_quantum/client/schemas/representation.py +19 -0
  73. luna_quantum/client/schemas/solution.py +106 -0
  74. luna_quantum/client/schemas/solve_job.py +50 -0
  75. luna_quantum/client/schemas/solver_info.py +11 -0
  76. luna_quantum/client/schemas/user.py +11 -0
  77. luna_quantum/client/schemas/wrappers/__init__.py +5 -0
  78. luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
  79. luna_quantum/client/utils/__init__.py +0 -0
  80. luna_quantum/client/utils/qpu_token_utils.py +147 -0
  81. luna_quantum/config.py +11 -0
  82. luna_quantum/decorators.py +248 -0
  83. luna_quantum/errors.py +34 -0
  84. luna_quantum/errors.pyi +287 -0
  85. luna_quantum/exceptions/__init__.py +0 -0
  86. luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
  87. luna_quantum/exceptions/luna_quantum_call_type_error.py +9 -0
  88. luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
  89. luna_quantum/factories/__init__.py +4 -0
  90. luna_quantum/factories/luna_solve_client_factory.py +100 -0
  91. luna_quantum/factories/usecase_factory.py +489 -0
  92. luna_quantum/py.typed +0 -0
  93. luna_quantum/solve/__init__.py +13 -0
  94. luna_quantum/solve/default_token.py +304 -0
  95. luna_quantum/solve/domain/__init__.py +0 -0
  96. luna_quantum/solve/domain/abstract/__init__.py +4 -0
  97. luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
  98. luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
  99. luna_quantum/solve/domain/model_metadata.py +56 -0
  100. luna_quantum/solve/domain/solve_job.py +230 -0
  101. luna_quantum/solve/errors/__init__.py +0 -0
  102. luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
  103. luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
  104. luna_quantum/solve/errors/solve_base_error.py +5 -0
  105. luna_quantum/solve/errors/token_missing_error.py +11 -0
  106. luna_quantum/solve/interfaces/__init__.py +0 -0
  107. luna_quantum/solve/interfaces/algorithm_i.py +49 -0
  108. luna_quantum/solve/interfaces/backend_i.py +28 -0
  109. luna_quantum/solve/interfaces/usecases/__init__.py +59 -0
  110. luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
  111. luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
  112. luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
  113. luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
  114. luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
  115. luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
  116. luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
  117. luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
  118. luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
  119. luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
  120. luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
  121. luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
  122. luna_quantum/solve/interfaces/usecases/solve_job_get_by_id_usecase_i.py +27 -0
  123. luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
  124. luna_quantum/solve/parameters/__init__.py +0 -0
  125. luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
  126. luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
  127. luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
  128. luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
  129. luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
  130. luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
  131. luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
  132. luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
  133. luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
  134. luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
  135. luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
  136. luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
  137. luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
  138. luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
  139. luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
  140. luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
  141. luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
  142. luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
  143. luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
  144. luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
  145. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
  146. luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
  147. luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
  148. luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
  149. luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
  150. luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
  151. luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
  152. luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
  153. luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +10 -0
  154. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/__init__.py +29 -0
  155. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/config.py +58 -0
  156. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/flexqaoa.py +188 -0
  157. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/optimizers.py +53 -0
  158. luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/pipeline.py +164 -0
  159. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +112 -0
  160. luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
  161. luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
  162. luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
  163. luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
  164. luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
  165. luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
  166. luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
  167. luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
  168. luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
  169. luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
  170. luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
  171. luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
  172. luna_quantum/solve/parameters/backends/__init__.py +27 -0
  173. luna_quantum/solve/parameters/backends/aqarios.py +17 -0
  174. luna_quantum/solve/parameters/backends/aqarios_gpu.py +17 -0
  175. luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
  176. luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
  177. luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
  178. luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
  179. luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
  180. luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
  181. luna_quantum/solve/parameters/backends/cudaq/__init__.py +5 -0
  182. luna_quantum/solve/parameters/backends/cudaq/cudaq_base.py +16 -0
  183. luna_quantum/solve/parameters/backends/cudaq/cudaq_cpu.py +30 -0
  184. luna_quantum/solve/parameters/backends/cudaq/cudaq_gpu.py +32 -0
  185. luna_quantum/solve/parameters/backends/dwave.py +17 -0
  186. luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
  187. luna_quantum/solve/parameters/backends/fda.py +17 -0
  188. luna_quantum/solve/parameters/backends/ibm.py +138 -0
  189. luna_quantum/solve/parameters/backends/qctrl.py +103 -0
  190. luna_quantum/solve/parameters/backends/zib.py +17 -0
  191. luna_quantum/solve/parameters/constants.py +11 -0
  192. luna_quantum/solve/parameters/errors.py +30 -0
  193. luna_quantum/solve/parameters/mixins/__init__.py +0 -0
  194. luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
  195. luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
  196. luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
  197. luna_quantum/solve/use_cases/__init__.py +119 -0
  198. luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
  199. luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
  200. luna_quantum/solve/use_cases/base.py +7 -0
  201. luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
  202. luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
  203. luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
  204. luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
  205. luna_quantum/solve/use_cases/exact_cover.py +51 -0
  206. luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
  207. luna_quantum/solve/use_cases/graph_coloring.py +42 -0
  208. luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
  209. luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
  210. luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
  211. luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
  212. luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
  213. luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
  214. luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
  215. luna_quantum/solve/use_cases/linear_regression.py +60 -0
  216. luna_quantum/solve/use_cases/lmwcs.py +84 -0
  217. luna_quantum/solve/use_cases/longest_path.py +50 -0
  218. luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
  219. luna_quantum/solve/use_cases/max2sat.py +54 -0
  220. luna_quantum/solve/use_cases/max3sat.py +55 -0
  221. luna_quantum/solve/use_cases/max_clique.py +60 -0
  222. luna_quantum/solve/use_cases/max_cut.py +48 -0
  223. luna_quantum/solve/use_cases/max_independent_set.py +37 -0
  224. luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
  225. luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
  226. luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
  227. luna_quantum/solve/use_cases/number_partitioning.py +32 -0
  228. luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
  229. luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
  230. luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
  231. luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
  232. luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
  233. luna_quantum/solve/use_cases/sensor_placement.py +58 -0
  234. luna_quantum/solve/use_cases/set_cover.py +56 -0
  235. luna_quantum/solve/use_cases/set_packing.py +54 -0
  236. luna_quantum/solve/use_cases/set_partitioning.py +52 -0
  237. luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
  238. luna_quantum/solve/use_cases/subset_sum.py +37 -0
  239. luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
  240. luna_quantum/solve/use_cases/traffic_flow.py +35 -0
  241. luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
  242. luna_quantum/solve/use_cases/type_aliases.py +9 -0
  243. luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
  244. luna_quantum/solve/usecases/__init__.py +45 -0
  245. luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
  246. luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
  247. luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
  248. luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
  249. luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
  250. luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
  251. luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
  252. luna_quantum/solve/usecases/model_save_usecase.py +63 -0
  253. luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
  254. luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
  255. luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
  256. luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
  257. luna_quantum/solve/usecases/solve_job_get_by_id_usecase.py +44 -0
  258. luna_quantum/solve/usecases/solve_job_get_result_usecase.py +105 -0
  259. luna_quantum/transformations.py +18 -0
  260. luna_quantum/transformations.pyi +371 -0
  261. luna_quantum/translator.py +23 -0
  262. luna_quantum/translator.pyi +869 -0
  263. luna_quantum/util/__init__.py +0 -0
  264. luna_quantum/util/active_waiting.py +79 -0
  265. luna_quantum/util/class_patcher.py +164 -0
  266. luna_quantum/util/debug_info.py +52 -0
  267. luna_quantum/util/log_utils.py +187 -0
  268. luna_quantum/util/pretty_base.py +67 -0
  269. luna_quantum/util/pydantic_utils.py +38 -0
  270. luna_quantum/utils.py +3 -0
  271. luna_quantum/utils.pyi +67 -0
  272. luna_quantum-1.1.0.dist-info/METADATA +36 -0
  273. luna_quantum-1.1.0.dist-info/RECORD +276 -0
  274. luna_quantum-1.1.0.dist-info/WHEEL +4 -0
  275. luna_quantum-1.1.0.dist-info/licenses/LICENSE +176 -0
  276. luna_quantum-1.1.0.dist-info/licenses/NOTICE +13 -0
@@ -0,0 +1,508 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from pydantic import TypeAdapter
7
+
8
+ from luna_quantum.client.interfaces.clients.qpu_token_rest_client_i import (
9
+ IQpuTokenRestClient,
10
+ )
11
+ from luna_quantum.client.schemas import QpuTokenOut
12
+ from luna_quantum.client.schemas.create import (
13
+ QpuTokenIn,
14
+ QpuTokenTimeQuotaIn,
15
+ QpuTokenTimeQuotaUpdate,
16
+ )
17
+ from luna_quantum.client.schemas.enums.qpu_token_type import QpuTokenTypeEnum
18
+ from luna_quantum.client.schemas.qpu_token.qpu_token_time_quota import (
19
+ QpuTokenTimeQuotaOut,
20
+ )
21
+
22
+ if TYPE_CHECKING:
23
+ from datetime import datetime
24
+
25
+ from httpx import Response
26
+
27
+ _ORGANIZATION_QPU_TOKENS_BACKEND = "shared"
28
+ _PERSONAL_QPU_TOKENS_BACKEND = "private"
29
+
30
+
31
+ class QpuTokenRestClient(IQpuTokenRestClient):
32
+ """Implementation of a solve job REST client."""
33
+
34
+ @property
35
+ def _endpoint(self) -> str:
36
+ return "/qpu-tokens"
37
+
38
+ def _get_endpoint_by_type(self, token_type: QpuTokenTypeEnum | None = None) -> str:
39
+ if token_type is None:
40
+ return f"{self._endpoint}"
41
+ if token_type == QpuTokenTypeEnum.PERSONAL:
42
+ return f"{self._endpoint}/{_PERSONAL_QPU_TOKENS_BACKEND}"
43
+ return f"{self._endpoint}/{_ORGANIZATION_QPU_TOKENS_BACKEND}"
44
+
45
+ def _get_by_name(
46
+ self, name: str, token_type: QpuTokenTypeEnum, **kwargs: Any
47
+ ) -> QpuTokenOut:
48
+ response: Response = self._client.get(
49
+ f"{self._get_endpoint_by_type(token_type)}/{name}", **kwargs
50
+ )
51
+ response.raise_for_status()
52
+
53
+ qpu_token_data = response.json()
54
+ qpu_token_data["token_type"] = token_type
55
+ return QpuTokenOut.model_validate(qpu_token_data)
56
+
57
+ def create(
58
+ self,
59
+ name: str,
60
+ provider: str,
61
+ token: str,
62
+ token_type: QpuTokenTypeEnum,
63
+ **kwargs: Any,
64
+ ) -> QpuTokenOut:
65
+ """
66
+ Create QPU token.
67
+
68
+ Parameters
69
+ ----------
70
+ name: str
71
+ Name of the QPU token
72
+ provider: str
73
+ Name of provider
74
+ token: str
75
+ Token
76
+ token_type: QpuTokenTypeEnum
77
+ There are two types of QPU tokens: PERSONAL and GROUP.
78
+ All users of a group can use group QPU tokens.
79
+ User QPU tokens can only be used by the user who created them.
80
+ **kwargs
81
+ Parameters to pass to `httpx.request`.
82
+
83
+ Returns
84
+ -------
85
+ QpuTokenOut
86
+ QpuToken instances.
87
+ """
88
+ qpu_token = QpuTokenIn(
89
+ name=name,
90
+ provider=provider,
91
+ token=token,
92
+ )
93
+
94
+ response: Response = self._client.post(
95
+ self._get_endpoint_by_type(token_type),
96
+ content=qpu_token.model_dump_json(),
97
+ **kwargs,
98
+ )
99
+ response.raise_for_status()
100
+ qpu_token_data = response.json()
101
+ qpu_token_data["token_type"] = token_type
102
+ return QpuTokenOut.model_validate(qpu_token_data)
103
+
104
+ def get_all(
105
+ self,
106
+ filter_provider: str | None = None,
107
+ token_type: QpuTokenTypeEnum | None = None,
108
+ limit: int | None = None,
109
+ offset: int | None = None,
110
+ **kwargs: Any,
111
+ ) -> dict[QpuTokenTypeEnum, list[QpuTokenOut]]:
112
+ """
113
+ Retrieve a list of QPU tokens.
114
+
115
+ Parameters
116
+ ----------
117
+ filter_provider: Optional[str]
118
+ The provider for which qpu tokens should be retrieved
119
+ token_type: Optional[QpuTokenTypeEnum]
120
+ If you want to retrieve only user or group QPU tokens
121
+ otherwise all QPU tokens will be retrieved
122
+ limit: Optional[int]
123
+ Number of items to fetch. Default is 10.
124
+ offset: Optional[int]
125
+ Optional. Number of items to skip. Default is 0.
126
+ **kwargs
127
+ Parameters to pass to `httpx.request`.
128
+
129
+ Returns
130
+ -------
131
+ Dict[QpuTokenTypeEnum, List[QpuTokenOut]]
132
+ List of QpuTokenOut instances.
133
+ """
134
+ params = {}
135
+ if filter_provider:
136
+ params["filter_provider"] = filter_provider
137
+
138
+ if limit is not None:
139
+ params["limit"] = str(limit)
140
+ if offset is not None:
141
+ params["offset"] = str(offset)
142
+ if token_type == QpuTokenTypeEnum.PERSONAL:
143
+ params["token_type"] = _PERSONAL_QPU_TOKENS_BACKEND
144
+ if token_type == QpuTokenTypeEnum.GROUP:
145
+ params["token_type"] = _ORGANIZATION_QPU_TOKENS_BACKEND
146
+
147
+ response = self._client.get(
148
+ self._endpoint,
149
+ params=params,
150
+ **kwargs,
151
+ )
152
+ ta = TypeAdapter(list[QpuTokenOut])
153
+ to_return: dict[QpuTokenTypeEnum, list[QpuTokenOut]] = {}
154
+ resp = response.json()
155
+
156
+ shared_tokens = resp.get(_ORGANIZATION_QPU_TOKENS_BACKEND, [])
157
+ for qpu_token in shared_tokens:
158
+ qpu_token["token_type"] = QpuTokenTypeEnum.GROUP
159
+ to_return[QpuTokenTypeEnum.GROUP] = ta.validate_python(shared_tokens)
160
+
161
+ personal_tokens = resp.get(_PERSONAL_QPU_TOKENS_BACKEND, [])
162
+ for qpu_token in personal_tokens:
163
+ qpu_token["token_type"] = QpuTokenTypeEnum.PERSONAL
164
+ to_return[QpuTokenTypeEnum.PERSONAL] = ta.validate_python(personal_tokens)
165
+
166
+ return to_return
167
+
168
+ def get(
169
+ self,
170
+ name: str,
171
+ token_type: QpuTokenTypeEnum = QpuTokenTypeEnum.PERSONAL,
172
+ **kwargs: Any,
173
+ ) -> QpuTokenOut:
174
+ """
175
+ Retrieve user QPU token by id.
176
+
177
+ Parameters
178
+ ----------
179
+ name: str
180
+ Name of the QPU token that should be retrieved
181
+ token_type: QpuTokenTypeEnum
182
+ There are two types of QPU tokens: PERSONAL and GROUP.
183
+ All users of a group can use group QPU tokens.
184
+ User QPU tokens can only be used by the user who created them.
185
+ **kwargs
186
+ Parameters to pass to `httpx.request`.
187
+
188
+ Returns
189
+ -------
190
+ QpuTokenOut
191
+ QpuToken instance.
192
+ """
193
+ qpu_token: QpuTokenOut = self._get_by_name(name, token_type, **kwargs)
194
+
195
+ return qpu_token
196
+
197
+ def rename(
198
+ self,
199
+ name: str,
200
+ new_name: str,
201
+ token_type: QpuTokenTypeEnum,
202
+ **kwargs: Any,
203
+ ) -> QpuTokenOut:
204
+ """
205
+ Update QPU token by id.
206
+
207
+ Parameters
208
+ ----------
209
+ name: str
210
+ Current name of the QPU token that should be updated
211
+ new_name: str
212
+ The new name
213
+ token_type: QpuTokenTypeEnum
214
+ There are two types of QPU tokens: PERSONAL and GROUP.
215
+ All users of a group can use group QPU tokens.
216
+ User QPU tokens can only be used by the user who created them.
217
+ **kwargs
218
+ Parameters to pass to `httpx.request`.
219
+
220
+ Returns
221
+ -------
222
+ QpuTokenOut
223
+ QpuToken instance.
224
+ """
225
+ qpu_token_update_data = {"name": new_name}
226
+
227
+ token: QpuTokenOut = self.get(name, token_type)
228
+
229
+ response = self._client.patch(
230
+ f"{self._get_endpoint_by_type(token_type)}/{token.name}",
231
+ content=json.dumps(qpu_token_update_data),
232
+ **kwargs,
233
+ )
234
+ response.raise_for_status()
235
+
236
+ qpu_token_data = response.json()
237
+ qpu_token_data["token_type"] = token_type
238
+ return QpuTokenOut.model_validate(qpu_token_data)
239
+
240
+ def delete(self, name: str, token_type: QpuTokenTypeEnum, **kwargs: Any) -> None:
241
+ """
242
+ Delete QPU token by name.
243
+
244
+ Parameters
245
+ ----------
246
+ name: str
247
+ Name of the QPU token that should be deleted
248
+ token_type: QpuTokenTypeEnum
249
+ There are two types of QPU tokens: PERSONAL and GROUP.
250
+ All users of a group can use organization QPU tokens.
251
+ User QPU tokens can only be used by the user who created them.
252
+ **kwargs
253
+ Parameters to pass to `httpx.request`.
254
+ """
255
+ response = self._client.delete(
256
+ f"{self._get_endpoint_by_type(token_type)}/{name}", **kwargs
257
+ )
258
+ response.raise_for_status()
259
+
260
+ def create_group_time_quota(
261
+ self,
262
+ qpu_token_name: str,
263
+ quota: int,
264
+ start: datetime | None = None,
265
+ end: datetime | None = None,
266
+ **kwargs: Any,
267
+ ) -> None:
268
+ """Create a time quota policy for a shared QPU token for the entire group.
269
+
270
+ Parameters
271
+ ----------
272
+ qpu_token_name : str
273
+ The name of the qpu token. Currently, only DWave tokens are supported.
274
+ quota : int
275
+ quota : int
276
+ The amount of quota to add. For DWave Quantum Annealing, which is currently
277
+ the only algorithm that supports time quota, this is the qpu access time in
278
+ nanoseconds.
279
+ start : Optional[datetime], optional
280
+ The date and time from which the policy is active. If None, the current date
281
+ and time will be used. If the policy is currently not effective, the token
282
+ cannot be used at all.
283
+ Default: None
284
+ end : Optional[datetime], optional
285
+ The date and time until which the policy is active. If None, the policy if
286
+ effective until 265 days after the start date. If the policy is currently
287
+ not effective, the token cannot be used at all.
288
+ Default: None
289
+ """
290
+ time_quota = QpuTokenTimeQuotaIn(quota=quota, start=start, end=end)
291
+
292
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
293
+ response = self._client.post(
294
+ f"{endpoint}/quota/group/{qpu_token_name}",
295
+ content=time_quota.model_dump_json(),
296
+ **kwargs,
297
+ )
298
+ response.raise_for_status()
299
+
300
+ def get_group_time_quota(
301
+ self, qpu_token_name: str, **kwargs: Any
302
+ ) -> QpuTokenTimeQuotaOut | None:
303
+ """Get the group time quota policy for a qpu token.
304
+
305
+ Parameters
306
+ ----------
307
+ qpu_token_name : str
308
+ The name of the qpu token.
309
+
310
+ Returns
311
+ -------
312
+ Optional[QpuTokenTimeQuotaOut]
313
+ The token policy. None, if no group policy is set on this token.
314
+ """
315
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
316
+ response = self._client.get(
317
+ f"{endpoint}/quota/group/{qpu_token_name}", **kwargs
318
+ )
319
+ response.raise_for_status()
320
+
321
+ time_quota_data = response.json()
322
+
323
+ if time_quota_data is None:
324
+ return None
325
+ return QpuTokenTimeQuotaOut.model_validate(time_quota_data)
326
+
327
+ def update_group_time_quota(
328
+ self,
329
+ qpu_token_name: str,
330
+ quota: int | None = None,
331
+ start: datetime | None = None,
332
+ end: datetime | None = None,
333
+ **kwargs: Any,
334
+ ) -> None:
335
+ """Update the details on a group qpu time quota policy.
336
+
337
+ Parameters
338
+ ----------
339
+ qpu_token_name : str
340
+ The name of the qpu token.
341
+ quota : Optional[int], optional
342
+ The amount of quota. For DWave Quantum Annealing, which is currently the
343
+ only supported solver, this is the qpu access time in nanoseconds. If None,
344
+ the available quota won't be updated.
345
+ Default: None
346
+ start : Optional[datetime], optional
347
+ The date and time from which the policy is active. If None, the start date
348
+ won't be updated.
349
+ Default: None
350
+ end : Optional[datetime], optional
351
+ The date and time until which the policy is active. If None, the end date
352
+ won't be updated.
353
+ Default: None
354
+ """
355
+ data = QpuTokenTimeQuotaUpdate(quota=quota, start=start, end=end)
356
+
357
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
358
+ response = self._client.patch(
359
+ f"{endpoint}/quota/group/{qpu_token_name}",
360
+ content=data.model_dump_json(),
361
+ **kwargs,
362
+ )
363
+ response.raise_for_status()
364
+
365
+ def delete_group_time_quota(self, qpu_token_name: str, **kwargs: Any) -> None:
366
+ """Delete the group policy set on a qpu token.
367
+
368
+ Parameters
369
+ ----------
370
+ qpu_token_name : str
371
+ The name of the qpu token.
372
+ """
373
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
374
+ response = self._client.delete(
375
+ f"{endpoint}/quota/group/{qpu_token_name}",
376
+ **kwargs,
377
+ )
378
+ response.raise_for_status()
379
+
380
+ def create_user_time_quota(
381
+ self,
382
+ qpu_token_name: str,
383
+ user_email: str,
384
+ quota: int,
385
+ start: datetime | None = None,
386
+ end: datetime | None = None,
387
+ **kwargs: Any,
388
+ ) -> None:
389
+ """Create a time quota policy for a shared QPU token for a single user.
390
+
391
+ Parameters
392
+ ----------
393
+ qpu_token_name : str
394
+ The name of the qpu token. Currently, only DWave tokens are supported.
395
+ user_email : str
396
+ Email of the user for whom to add the policy.
397
+ quota : int
398
+ The amount of quota to add. For DWave Quantum Annealing, which is currently
399
+ the only algorithm that supports time quota, this is the qpu access time in
400
+ nanoseconds.
401
+ start : Optional[datetime], optional
402
+ The date and time from which the policy is active. If None, the current date
403
+ and time will be used. If the policy is currently not effective, the token
404
+ cannot be used at all.
405
+ Default: None
406
+ end : Optional[datetime], optional
407
+ The date and time until which the policy is active. If None, the policy if
408
+ effective until 265 days after the start date. If the policy is currently
409
+ not effective, the token cannot be used at all.
410
+ Default: None
411
+ """
412
+ time_quota = QpuTokenTimeQuotaIn(quota=quota, start=start, end=end)
413
+
414
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
415
+ response = self._client.post(
416
+ f"{endpoint}/quota/user/{qpu_token_name}/{user_email}",
417
+ content=time_quota.model_dump_json(),
418
+ **kwargs,
419
+ )
420
+ response.raise_for_status()
421
+
422
+ def get_user_time_quota(
423
+ self, qpu_token_name: str, user_email: str, **kwargs: Any
424
+ ) -> QpuTokenTimeQuotaOut | None:
425
+ """Get a user-specific time quota policy for a qpu token.
426
+
427
+ Parameters
428
+ ----------
429
+ qpu_token_name : str
430
+ The name of the qpu token.
431
+ user_email : str
432
+ Email of the user for whom to get the policy.
433
+
434
+ Returns
435
+ -------
436
+ Optional[QpuTokenTimeQuotaOut]
437
+ The token policy. None, if no policy is set on this token for the specified
438
+ user.
439
+ """
440
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
441
+ response = self._client.get(
442
+ f"{endpoint}/quota/user/{qpu_token_name}/{user_email}", **kwargs
443
+ )
444
+ response.raise_for_status()
445
+
446
+ time_quota_data = response.json()
447
+
448
+ if time_quota_data is None:
449
+ return None
450
+ return QpuTokenTimeQuotaOut.model_validate(time_quota_data)
451
+
452
+ def update_user_time_quota(
453
+ self,
454
+ qpu_token_name: str,
455
+ user_email: str,
456
+ quota: int | None = None,
457
+ start: datetime | None = None,
458
+ end: datetime | None = None,
459
+ **kwargs: Any,
460
+ ) -> None:
461
+ """Update the details on a user-specific qpu time quota policy.
462
+
463
+ Parameters
464
+ ----------
465
+ qpu_token_name : str
466
+ The name of the qpu token.
467
+ user_email : str
468
+ Email of the user for whom to update the policy.
469
+ quota : Optional[int], optional
470
+ The amount of quota. For DWave Quantum Annealing, which is currently the
471
+ only supported solver, this is the qpu access time in nanoseconds. If None,
472
+ the available quota won't be updated.
473
+ Default: None
474
+ start : Optional[datetime], optional
475
+ The date and time from which the policy is active. If None, the start date
476
+ won't be updated.
477
+ Default: None
478
+ end : Optional[datetime], optional
479
+ The date and time until which the policy is active. If None, the end date
480
+ won't be updated.
481
+ Default: None
482
+ """
483
+ data = {"quota": quota, "start": start, "end": end}
484
+
485
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
486
+ response = self._client.patch(
487
+ f"{endpoint}/quota/user/{qpu_token_name}/{user_email}",
488
+ content=json.dumps(data),
489
+ **kwargs,
490
+ )
491
+ response.raise_for_status()
492
+
493
+ def delete_user_time_quota(
494
+ self, qpu_token_name: str, user_email: str, **kwargs: Any
495
+ ) -> None:
496
+ """Delete a user-specific policy set on a qpu token.
497
+
498
+ Parameters
499
+ ----------
500
+ qpu_token_name : str
501
+ The name of the qpu token.
502
+ """
503
+ endpoint = self._get_endpoint_by_type(QpuTokenTypeEnum.GROUP)
504
+ response = self._client.delete(
505
+ f"{endpoint}/quota/user/{qpu_token_name}/{user_email}",
506
+ **kwargs,
507
+ )
508
+ response.raise_for_status()