luna-quantum 1.0.0__cp311-cp311-macosx_10_12_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of luna-quantum might be problematic. Click here for more details.

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