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.
- luna_quantum/__init__.py +139 -0
- luna_quantum/__init__.pyi +98 -0
- luna_quantum/_core.cp312-win_amd64.pyd +0 -0
- luna_quantum/_core.pyi +4286 -0
- luna_quantum/_utility.py +148 -0
- luna_quantum/_utility.pyi +20 -0
- luna_quantum/algorithms/__init__.py +1 -0
- luna_quantum/aqm_overwrites/__init__.py +3 -0
- luna_quantum/aqm_overwrites/model.py +184 -0
- luna_quantum/backends/__init__.py +1 -0
- luna_quantum/client/__init__.py +0 -0
- luna_quantum/client/controllers/__init__.py +4 -0
- luna_quantum/client/controllers/luna_http_client.py +37 -0
- luna_quantum/client/controllers/luna_platform_client.py +256 -0
- luna_quantum/client/controllers/luna_q.py +67 -0
- luna_quantum/client/controllers/luna_solve.py +129 -0
- luna_quantum/client/error/__init__.py +0 -0
- luna_quantum/client/error/luna_api_key_invalid_error.py +10 -0
- luna_quantum/client/error/luna_api_key_missing_error.py +10 -0
- luna_quantum/client/error/luna_error.py +2 -0
- luna_quantum/client/error/luna_server_error.py +20 -0
- luna_quantum/client/error/timeout_error.py +12 -0
- luna_quantum/client/error/transformation_error.py +18 -0
- luna_quantum/client/error/utils/__init__.py +0 -0
- luna_quantum/client/error/utils/http_error_utils.py +112 -0
- luna_quantum/client/interfaces/__init__.py +4 -0
- luna_quantum/client/interfaces/clients/__init__.py +25 -0
- luna_quantum/client/interfaces/clients/circuit_rest_client_i.py +68 -0
- luna_quantum/client/interfaces/clients/info_rest_client_i.py +53 -0
- luna_quantum/client/interfaces/clients/model_rest_client_i.py +139 -0
- luna_quantum/client/interfaces/clients/qpu_token_rest_client_i.py +364 -0
- luna_quantum/client/interfaces/clients/rest_client_i.py +21 -0
- luna_quantum/client/interfaces/clients/solve_job_rest_client_i.py +201 -0
- luna_quantum/client/interfaces/clients/users_rest_client_i.py +29 -0
- luna_quantum/client/interfaces/services/__init__.py +0 -0
- luna_quantum/client/interfaces/services/luna_q_i.py +34 -0
- luna_quantum/client/interfaces/services/luna_solve_i.py +72 -0
- luna_quantum/client/interfaces/services/service_i.py +56 -0
- luna_quantum/client/rest_client/__init__.py +15 -0
- luna_quantum/client/rest_client/circuit_rest_client.py +107 -0
- luna_quantum/client/rest_client/info_rest_client.py +74 -0
- luna_quantum/client/rest_client/model_rest_client.py +216 -0
- luna_quantum/client/rest_client/qpu_token_rest_client.py +508 -0
- luna_quantum/client/rest_client/solve_job_rest_client.py +286 -0
- luna_quantum/client/rest_client/users_rest_client.py +35 -0
- luna_quantum/client/schemas/__init__.py +26 -0
- luna_quantum/client/schemas/circuit.py +48 -0
- luna_quantum/client/schemas/create/__init__.py +15 -0
- luna_quantum/client/schemas/create/circuit.py +30 -0
- luna_quantum/client/schemas/create/optimization.py +39 -0
- luna_quantum/client/schemas/create/qpu_token.py +22 -0
- luna_quantum/client/schemas/create/qpu_token_time_quota.py +35 -0
- luna_quantum/client/schemas/create/qpu_token_time_quota_update.py +24 -0
- luna_quantum/client/schemas/create/qubo.py +19 -0
- luna_quantum/client/schemas/create/solve_job_create.py +43 -0
- luna_quantum/client/schemas/enums/__init__.py +0 -0
- luna_quantum/client/schemas/enums/call_style.py +13 -0
- luna_quantum/client/schemas/enums/circuit.py +42 -0
- luna_quantum/client/schemas/enums/model_format.py +11 -0
- luna_quantum/client/schemas/enums/problem.py +50 -0
- luna_quantum/client/schemas/enums/qpu_token_type.py +20 -0
- luna_quantum/client/schemas/enums/sense.py +8 -0
- luna_quantum/client/schemas/enums/status.py +40 -0
- luna_quantum/client/schemas/enums/timeframe.py +11 -0
- luna_quantum/client/schemas/error_message.py +14 -0
- luna_quantum/client/schemas/model_metadata.py +35 -0
- luna_quantum/client/schemas/qpu_token/__init__.py +0 -0
- luna_quantum/client/schemas/qpu_token/qpu_token.py +154 -0
- luna_quantum/client/schemas/qpu_token/qpu_token_source.py +19 -0
- luna_quantum/client/schemas/qpu_token/qpu_token_time_quota.py +30 -0
- luna_quantum/client/schemas/qpu_token/token_provider.py +132 -0
- luna_quantum/client/schemas/representation.py +19 -0
- luna_quantum/client/schemas/solution.py +106 -0
- luna_quantum/client/schemas/solve_job.py +50 -0
- luna_quantum/client/schemas/solver_info.py +11 -0
- luna_quantum/client/schemas/user.py +11 -0
- luna_quantum/client/schemas/wrappers/__init__.py +5 -0
- luna_quantum/client/schemas/wrappers/datetime_wrapper.py +32 -0
- luna_quantum/client/utils/__init__.py +0 -0
- luna_quantum/client/utils/qpu_token_utils.py +147 -0
- luna_quantum/config.py +11 -0
- luna_quantum/decorators.py +248 -0
- luna_quantum/errors.py +34 -0
- luna_quantum/errors.pyi +287 -0
- luna_quantum/exceptions/__init__.py +0 -0
- luna_quantum/exceptions/base_luna_quantum_error.py +2 -0
- luna_quantum/exceptions/luna_quantum_call_type_error.py +9 -0
- luna_quantum/exceptions/patch_class_field_exists_error.py +10 -0
- luna_quantum/factories/__init__.py +4 -0
- luna_quantum/factories/luna_solve_client_factory.py +100 -0
- luna_quantum/factories/usecase_factory.py +489 -0
- luna_quantum/py.typed +0 -0
- luna_quantum/solve/__init__.py +13 -0
- luna_quantum/solve/default_token.py +304 -0
- luna_quantum/solve/domain/__init__.py +0 -0
- luna_quantum/solve/domain/abstract/__init__.py +4 -0
- luna_quantum/solve/domain/abstract/luna_algorithm.py +205 -0
- luna_quantum/solve/domain/abstract/qpu_token_backend.py +34 -0
- luna_quantum/solve/domain/model_metadata.py +56 -0
- luna_quantum/solve/domain/solve_job.py +230 -0
- luna_quantum/solve/errors/__init__.py +0 -0
- luna_quantum/solve/errors/incompatible_backend_error.py +15 -0
- luna_quantum/solve/errors/model_metadata_missing_error.py +11 -0
- luna_quantum/solve/errors/solve_base_error.py +5 -0
- luna_quantum/solve/errors/token_missing_error.py +11 -0
- luna_quantum/solve/interfaces/__init__.py +0 -0
- luna_quantum/solve/interfaces/algorithm_i.py +49 -0
- luna_quantum/solve/interfaces/backend_i.py +28 -0
- luna_quantum/solve/interfaces/usecases/__init__.py +59 -0
- luna_quantum/solve/interfaces/usecases/model_delete_usecase_i.py +27 -0
- luna_quantum/solve/interfaces/usecases/model_fetch_metadata_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_get_solutions_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_get_solve_jobs_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/model_load_by_id_usecase_i.py +32 -0
- luna_quantum/solve/interfaces/usecases/model_load_by_metadata_usecase_i.py +37 -0
- luna_quantum/solve/interfaces/usecases/model_load_metadata_by_hash_usecase_i.py +38 -0
- luna_quantum/solve/interfaces/usecases/model_save_usecase_i.py +36 -0
- luna_quantum/solve/interfaces/usecases/solve_job_cancel_usecase_i.py +33 -0
- luna_quantum/solve/interfaces/usecases/solve_job_create_usecase_i.py +44 -0
- luna_quantum/solve/interfaces/usecases/solve_job_delete_usecase_i.py +32 -0
- luna_quantum/solve/interfaces/usecases/solve_job_fetch_updates_usecase_i.py +38 -0
- luna_quantum/solve/interfaces/usecases/solve_job_get_by_id_usecase_i.py +27 -0
- luna_quantum/solve/interfaces/usecases/solve_job_get_result_usecase_i.py +63 -0
- luna_quantum/solve/parameters/__init__.py +0 -0
- luna_quantum/solve/parameters/algorithms/__init__.py +51 -0
- luna_quantum/solve/parameters/algorithms/base_params/__init__.py +24 -0
- luna_quantum/solve/parameters/algorithms/base_params/decomposer.py +57 -0
- luna_quantum/solve/parameters/algorithms/base_params/qaoa_circuit_params.py +95 -0
- luna_quantum/solve/parameters/algorithms/base_params/quantum_annealing_params.py +79 -0
- luna_quantum/solve/parameters/algorithms/base_params/scipy_optimizer.py +122 -0
- luna_quantum/solve/parameters/algorithms/base_params/simulated_annealing_params.py +106 -0
- luna_quantum/solve/parameters/algorithms/base_params/tabu_kerberos_params.py +39 -0
- luna_quantum/solve/parameters/algorithms/base_params/tabu_search_params.py +129 -0
- luna_quantum/solve/parameters/algorithms/flexible_parameter_algorithm.py +59 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/__init__.py +4 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/qaga.py +131 -0
- luna_quantum/solve/parameters/algorithms/genetic_algorithms/saga.py +139 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/__init__.py +3 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/fujits_da_base.py +85 -0
- luna_quantum/solve/parameters/algorithms/lq_fda/fujitsu_da_v3c.py +155 -0
- luna_quantum/solve/parameters/algorithms/optimization_solvers/__init__.py +3 -0
- luna_quantum/solve/parameters/algorithms/optimization_solvers/scip.py +51 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/__init__.py +19 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/kerberos.py +149 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_bqm.py +75 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/leap_hybrid_cqm.py +75 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/parallel_tempering_qpu.py +139 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/population_annealing_qpu.py +109 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/qbsolv_like_qpu.py +111 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/quantum_annealing.py +121 -0
- luna_quantum/solve/parameters/algorithms/quantum_annealing/repeated_reverse_quantum_annealing.py +174 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/__init__.py +6 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flex_qaoa/__init__.py +10 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/__init__.py +29 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/config.py +58 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/flexqaoa.py +188 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/optimizers.py +53 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/flexqaoa/pipeline.py +164 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa.py +112 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/qaoa_fo.py +69 -0
- luna_quantum/solve/parameters/algorithms/quantum_gate/vqe.py +108 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/__init__.py +5 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/dialectic_search.py +136 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/qbsolv_like_tabu_search.py +117 -0
- luna_quantum/solve/parameters/algorithms/search_algorithms/tabu_search.py +126 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/__init__.py +13 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/parallel_tempering.py +131 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/population_annealing.py +95 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/qbsolv_like_simulated_annealing.py +141 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/repeated_reverse_simulated_annealing.py +172 -0
- luna_quantum/solve/parameters/algorithms/simulated_annealing/simulated_annealing.py +126 -0
- luna_quantum/solve/parameters/backends/__init__.py +27 -0
- luna_quantum/solve/parameters/backends/aqarios.py +17 -0
- luna_quantum/solve/parameters/backends/aqarios_gpu.py +17 -0
- luna_quantum/solve/parameters/backends/aws/__init__.py +11 -0
- luna_quantum/solve/parameters/backends/aws/aws.py +36 -0
- luna_quantum/solve/parameters/backends/aws/aws_backend_base.py +74 -0
- luna_quantum/solve/parameters/backends/aws/ionq.py +43 -0
- luna_quantum/solve/parameters/backends/aws/iqm.py +31 -0
- luna_quantum/solve/parameters/backends/aws/rigetti.py +31 -0
- luna_quantum/solve/parameters/backends/cudaq/__init__.py +5 -0
- luna_quantum/solve/parameters/backends/cudaq/cudaq_base.py +16 -0
- luna_quantum/solve/parameters/backends/cudaq/cudaq_cpu.py +30 -0
- luna_quantum/solve/parameters/backends/cudaq/cudaq_gpu.py +32 -0
- luna_quantum/solve/parameters/backends/dwave.py +17 -0
- luna_quantum/solve/parameters/backends/dwave_qpu.py +166 -0
- luna_quantum/solve/parameters/backends/fda.py +17 -0
- luna_quantum/solve/parameters/backends/ibm.py +138 -0
- luna_quantum/solve/parameters/backends/qctrl.py +103 -0
- luna_quantum/solve/parameters/backends/zib.py +17 -0
- luna_quantum/solve/parameters/constants.py +11 -0
- luna_quantum/solve/parameters/errors.py +30 -0
- luna_quantum/solve/parameters/mixins/__init__.py +0 -0
- luna_quantum/solve/parameters/mixins/fujitsu_common_params_mixin.py +239 -0
- luna_quantum/solve/parameters/mixins/fujitsu_v2_mixin.py +70 -0
- luna_quantum/solve/parameters/mixins/qbsolv_like_mixin.py +60 -0
- luna_quantum/solve/use_cases/__init__.py +119 -0
- luna_quantum/solve/use_cases/arbitrage_edge_based.py +50 -0
- luna_quantum/solve/use_cases/arbitrage_node_based.py +55 -0
- luna_quantum/solve/use_cases/base.py +7 -0
- luna_quantum/solve/use_cases/binary_integer_linear_programming.py +54 -0
- luna_quantum/solve/use_cases/binary_paint_shop_problem.py +37 -0
- luna_quantum/solve/use_cases/credit_scoring_feature_selection.py +40 -0
- luna_quantum/solve/use_cases/dynamic_portfolio_optimization.py +64 -0
- luna_quantum/solve/use_cases/exact_cover.py +51 -0
- luna_quantum/solve/use_cases/flight_gate_assignment.py +79 -0
- luna_quantum/solve/use_cases/graph_coloring.py +42 -0
- luna_quantum/solve/use_cases/graph_isomorphism.py +52 -0
- luna_quantum/solve/use_cases/graph_partitioning.py +46 -0
- luna_quantum/solve/use_cases/hamiltonian_cycle.py +49 -0
- luna_quantum/solve/use_cases/induced_subgraph_isomorphism.py +50 -0
- luna_quantum/solve/use_cases/job_shop_scheduling.py +44 -0
- luna_quantum/solve/use_cases/k_medoids_clustering.py +49 -0
- luna_quantum/solve/use_cases/knapsack_integer_weights.py +56 -0
- luna_quantum/solve/use_cases/linear_regression.py +60 -0
- luna_quantum/solve/use_cases/lmwcs.py +84 -0
- luna_quantum/solve/use_cases/longest_path.py +50 -0
- luna_quantum/solve/use_cases/market_graph_clustering.py +61 -0
- luna_quantum/solve/use_cases/max2sat.py +54 -0
- luna_quantum/solve/use_cases/max3sat.py +55 -0
- luna_quantum/solve/use_cases/max_clique.py +60 -0
- luna_quantum/solve/use_cases/max_cut.py +48 -0
- luna_quantum/solve/use_cases/max_independent_set.py +37 -0
- luna_quantum/solve/use_cases/minimal_maximal_matching.py +54 -0
- luna_quantum/solve/use_cases/minimal_spanning_tree.py +90 -0
- luna_quantum/solve/use_cases/minimum_vertex_cover.py +45 -0
- luna_quantum/solve/use_cases/number_partitioning.py +32 -0
- luna_quantum/solve/use_cases/portfolio_optimization.py +46 -0
- luna_quantum/solve/use_cases/portfolio_optimization_ib_tv.py +63 -0
- luna_quantum/solve/use_cases/quadratic_assignment.py +49 -0
- luna_quantum/solve/use_cases/quadratic_knapsack.py +48 -0
- luna_quantum/solve/use_cases/satellite_scheduling.py +73 -0
- luna_quantum/solve/use_cases/sensor_placement.py +58 -0
- luna_quantum/solve/use_cases/set_cover.py +56 -0
- luna_quantum/solve/use_cases/set_packing.py +54 -0
- luna_quantum/solve/use_cases/set_partitioning.py +52 -0
- luna_quantum/solve/use_cases/subgraph_isomorphism.py +55 -0
- luna_quantum/solve/use_cases/subset_sum.py +37 -0
- luna_quantum/solve/use_cases/support_vector_machine.py +64 -0
- luna_quantum/solve/use_cases/traffic_flow.py +35 -0
- luna_quantum/solve/use_cases/travelling_salesman_problem.py +53 -0
- luna_quantum/solve/use_cases/type_aliases.py +9 -0
- luna_quantum/solve/use_cases/weighted_max_cut.py +37 -0
- luna_quantum/solve/usecases/__init__.py +45 -0
- luna_quantum/solve/usecases/model_delete_usecase.py +49 -0
- luna_quantum/solve/usecases/model_fetch_metadata_usecase.py +50 -0
- luna_quantum/solve/usecases/model_get_solution_usecase.py +59 -0
- luna_quantum/solve/usecases/model_get_solve_jobs_usecase.py +62 -0
- luna_quantum/solve/usecases/model_load_by_id_usecase.py +47 -0
- luna_quantum/solve/usecases/model_load_by_metadata_usecase.py +52 -0
- luna_quantum/solve/usecases/model_load_metadata_by_hash_usecase.py +51 -0
- luna_quantum/solve/usecases/model_save_usecase.py +63 -0
- luna_quantum/solve/usecases/solve_job_cancel_usecase.py +51 -0
- luna_quantum/solve/usecases/solve_job_create_usecase.py +112 -0
- luna_quantum/solve/usecases/solve_job_delete_usecase.py +38 -0
- luna_quantum/solve/usecases/solve_job_fetch_updates_usecase.py +49 -0
- luna_quantum/solve/usecases/solve_job_get_by_id_usecase.py +44 -0
- luna_quantum/solve/usecases/solve_job_get_result_usecase.py +105 -0
- luna_quantum/transformations.py +18 -0
- luna_quantum/transformations.pyi +371 -0
- luna_quantum/translator.py +23 -0
- luna_quantum/translator.pyi +869 -0
- luna_quantum/util/__init__.py +0 -0
- luna_quantum/util/active_waiting.py +79 -0
- luna_quantum/util/class_patcher.py +164 -0
- luna_quantum/util/debug_info.py +52 -0
- luna_quantum/util/log_utils.py +187 -0
- luna_quantum/util/pretty_base.py +67 -0
- luna_quantum/util/pydantic_utils.py +38 -0
- luna_quantum/utils.py +3 -0
- luna_quantum/utils.pyi +67 -0
- luna_quantum-1.1.0.dist-info/METADATA +36 -0
- luna_quantum-1.1.0.dist-info/RECORD +276 -0
- luna_quantum-1.1.0.dist-info/WHEEL +4 -0
- luna_quantum-1.1.0.dist-info/licenses/LICENSE +176 -0
- luna_quantum-1.1.0.dist-info/licenses/NOTICE +13 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
from luna_quantum.client.schemas.enums.model_format import ModelFormat
|
|
7
|
+
from luna_quantum.client.schemas.enums.status import StatusEnum
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SolveJobSchema(BaseModel):
|
|
11
|
+
"""
|
|
12
|
+
Solve job schema.
|
|
13
|
+
|
|
14
|
+
Attributes
|
|
15
|
+
----------
|
|
16
|
+
id: str
|
|
17
|
+
The ID of the solve job.
|
|
18
|
+
status: StatusEnum
|
|
19
|
+
The current status of the solve job.
|
|
20
|
+
status_timeline: dict[StatusEnum, datetime]
|
|
21
|
+
The history of status changes for the solve job.
|
|
22
|
+
used_format: ModelFormat | None
|
|
23
|
+
The format that is used for solving. None if not applicable.
|
|
24
|
+
error_message: str | None
|
|
25
|
+
The error message if the solve job failed.
|
|
26
|
+
provider: str
|
|
27
|
+
The name of the provider where the solve job is scheduled.
|
|
28
|
+
solver_job_info: str | None
|
|
29
|
+
Additional information about the solve job. None if not available.
|
|
30
|
+
is_cancelable: bool
|
|
31
|
+
Indicates if the solve job can be cancelled.
|
|
32
|
+
is_cancellation_requested: bool
|
|
33
|
+
Indicates if cancellation of the solve job has been requested.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
id: str
|
|
37
|
+
status: StatusEnum
|
|
38
|
+
status_timeline: dict[StatusEnum, datetime]
|
|
39
|
+
used_format: ModelFormat | None = None
|
|
40
|
+
|
|
41
|
+
error_message: str | None
|
|
42
|
+
provider: str
|
|
43
|
+
|
|
44
|
+
# TODO(Lev): Consider renaming? # noqa: FIX002
|
|
45
|
+
solver_job_info: str | None = None
|
|
46
|
+
|
|
47
|
+
is_cancelable: bool
|
|
48
|
+
is_cancellation_requested: bool
|
|
49
|
+
|
|
50
|
+
metadata: dict[str, Any] | None = None
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
from dateutil.parser import parse
|
|
7
|
+
from pydantic import BeforeValidator
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def validate_datetime(date_string: str | datetime) -> datetime:
|
|
11
|
+
"""Validate an ISO date string and return it in the local timezone.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
date_string : str
|
|
16
|
+
The ISO date string
|
|
17
|
+
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
datetime
|
|
21
|
+
The datetime in the user's local timezone
|
|
22
|
+
|
|
23
|
+
Raises
|
|
24
|
+
------
|
|
25
|
+
ValueError
|
|
26
|
+
If `date_string` does not have a valid format.
|
|
27
|
+
"""
|
|
28
|
+
dt = date_string if isinstance(date_string, datetime) else parse(date_string)
|
|
29
|
+
return dt.astimezone()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
PydanticDatetimeWrapper = Annotated[datetime, BeforeValidator(validate_datetime)]
|
|
File without changes
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from luna_quantum.client.schemas.qpu_token.qpu_token import (
|
|
4
|
+
QpuToken,
|
|
5
|
+
QpuTokenSource,
|
|
6
|
+
TokenProvider,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class QpuTokenUtils:
|
|
11
|
+
"""Utilities for QPU tokens."""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def patch_qpu_tokens_from_env(
|
|
15
|
+
qpu_token: TokenProvider = TokenProvider(),
|
|
16
|
+
) -> TokenProvider | None:
|
|
17
|
+
"""
|
|
18
|
+
Add QPU tokens from environment variables.
|
|
19
|
+
|
|
20
|
+
If a token is not found in the environment, it will be set to None.
|
|
21
|
+
If no token-provider is provided, a new one will be created.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
qpu_token: TokenProvider
|
|
26
|
+
Token-provider to update. If no token-provider is provided,
|
|
27
|
+
a new one will be created.
|
|
28
|
+
|
|
29
|
+
Returns
|
|
30
|
+
-------
|
|
31
|
+
Optional[TokenProvider]
|
|
32
|
+
Returns the updated token-provider. If the token-provider is empty,
|
|
33
|
+
returns None.
|
|
34
|
+
"""
|
|
35
|
+
qpu_token.dwave = QpuTokenUtils.get_token_from_provider_or_env(
|
|
36
|
+
token=qpu_token.dwave, env_key="LUNA_DWAVE_TOKEN"
|
|
37
|
+
)
|
|
38
|
+
qpu_token.ibm = QpuTokenUtils.get_token_from_provider_or_env(
|
|
39
|
+
token=qpu_token.ibm, env_key="LUNA_IBM_TOKEN"
|
|
40
|
+
)
|
|
41
|
+
qpu_token.qctrl = QpuTokenUtils.get_token_from_provider_or_env(
|
|
42
|
+
token=qpu_token.qctrl, env_key="LUNA_QCTRL_TOKEN"
|
|
43
|
+
)
|
|
44
|
+
qpu_token.fujitsu = QpuTokenUtils.get_token_from_provider_or_env(
|
|
45
|
+
token=qpu_token.fujitsu, env_key="LUNA_FUJITSU_TOKEN"
|
|
46
|
+
)
|
|
47
|
+
qpu_token.aws_access_key = QpuTokenUtils.get_token_from_provider_or_env(
|
|
48
|
+
token=qpu_token.aws_access_key, env_key="LUNA_AWS_ACCESS_KEY"
|
|
49
|
+
)
|
|
50
|
+
qpu_token.aws_secret_access_key = QpuTokenUtils.get_token_from_provider_or_env(
|
|
51
|
+
token=qpu_token.aws_secret_access_key, env_key="LUNA_AWS_SECRET_ACCESS_KEY"
|
|
52
|
+
)
|
|
53
|
+
qpu_token.aws_session_token = QpuTokenUtils.get_token_from_provider_or_env(
|
|
54
|
+
token=qpu_token.aws_session_token, env_key="LUNA_AWS_SESSION_TOKEN"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if QpuTokenUtils.is_token_provider_empty(qpu_token):
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
return qpu_token
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def is_qpu_token_empty(qpu_token: QpuToken) -> bool:
|
|
64
|
+
"""
|
|
65
|
+
Check if the QpuToken object is empty.
|
|
66
|
+
|
|
67
|
+
An empty QpuToken is defined as having both its `name` and `token`
|
|
68
|
+
attributes set to `None`.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
qpu_token : QpuToken
|
|
73
|
+
The QpuToken object to check for emptiness.
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
bool
|
|
78
|
+
True if the QpuToken is empty, otherwise False.
|
|
79
|
+
|
|
80
|
+
"""
|
|
81
|
+
return qpu_token.name is None and qpu_token.token is None
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def is_token_provider_empty(qpu_token: TokenProvider) -> bool:
|
|
85
|
+
"""
|
|
86
|
+
Check if the token provider is empty.
|
|
87
|
+
|
|
88
|
+
The function checks whether all attributes of the provided token provider are
|
|
89
|
+
None, indicating that it is empty.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
qpu_token : TokenProvider
|
|
94
|
+
The token provider object containing various token attributes.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
bool
|
|
99
|
+
True if all token attributes are None, otherwise False.
|
|
100
|
+
"""
|
|
101
|
+
if qpu_token is None:
|
|
102
|
+
return True
|
|
103
|
+
for field in [
|
|
104
|
+
qpu_token.dwave,
|
|
105
|
+
qpu_token.ibm,
|
|
106
|
+
qpu_token.qctrl,
|
|
107
|
+
qpu_token.fujitsu,
|
|
108
|
+
qpu_token.aws_access_key,
|
|
109
|
+
qpu_token.aws_secret_access_key,
|
|
110
|
+
qpu_token.aws_session_token,
|
|
111
|
+
]:
|
|
112
|
+
if field is not None and not QpuTokenUtils.is_qpu_token_empty(field):
|
|
113
|
+
return False
|
|
114
|
+
return True
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def get_token_from_provider_or_env(
|
|
118
|
+
token: QpuToken | None, env_key: str
|
|
119
|
+
) -> QpuToken | None:
|
|
120
|
+
"""
|
|
121
|
+
Get token from provider or environment variable.
|
|
122
|
+
|
|
123
|
+
If a token is provided and not empty, return it. Otherwise, attempt to retrieve
|
|
124
|
+
a token from the specified environment variable. If no token is found, return
|
|
125
|
+
None.
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
token : Optional[QpuToken]
|
|
130
|
+
Token provided by the caller.
|
|
131
|
+
env_key : str
|
|
132
|
+
The key for the environment variable to look for a token.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
Optional[QpuToken]
|
|
137
|
+
The token retrieved either from the provided input or the environment.
|
|
138
|
+
"""
|
|
139
|
+
if token is None or QpuTokenUtils.is_qpu_token_empty(token):
|
|
140
|
+
env_value = os.environ.get(env_key, None)
|
|
141
|
+
if env_value is not None:
|
|
142
|
+
return QpuToken(
|
|
143
|
+
source=QpuTokenSource.INLINE,
|
|
144
|
+
token=env_value,
|
|
145
|
+
)
|
|
146
|
+
return None
|
|
147
|
+
return token
|
luna_quantum/config.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Decorators."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import Any, Generic, TypeAlias, TypeVar
|
|
5
|
+
|
|
6
|
+
from typing_extensions import override
|
|
7
|
+
|
|
8
|
+
from . import Model, Solution
|
|
9
|
+
from .transformations import (
|
|
10
|
+
ActionType,
|
|
11
|
+
AnalysisCache,
|
|
12
|
+
AnalysisPass,
|
|
13
|
+
BasePass,
|
|
14
|
+
MetaAnalysisPass,
|
|
15
|
+
TransformationOutcome,
|
|
16
|
+
TransformationPass,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
T = TypeVar("T")
|
|
20
|
+
|
|
21
|
+
AnalysisSignature: TypeAlias = Callable[[Model, AnalysisCache], T]
|
|
22
|
+
|
|
23
|
+
MetaAnalysisSignature: TypeAlias = Callable[[list[BasePass], AnalysisCache], T]
|
|
24
|
+
|
|
25
|
+
Outcome: TypeAlias = (
|
|
26
|
+
TransformationOutcome | tuple[Model, ActionType] | tuple[Model, ActionType, Any]
|
|
27
|
+
)
|
|
28
|
+
TransformationSignature: TypeAlias = Callable[
|
|
29
|
+
[Model, AnalysisCache],
|
|
30
|
+
Outcome,
|
|
31
|
+
]
|
|
32
|
+
BackwardsSignature: TypeAlias = Callable[[Solution, AnalysisCache], Solution]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def __identity_backwards(solution: Solution, _: AnalysisCache) -> Solution:
|
|
36
|
+
return solution
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class DynamicAnalysisPass(AnalysisPass, Generic[T]):
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
name: str,
|
|
43
|
+
requires: list[str],
|
|
44
|
+
func: AnalysisSignature[T],
|
|
45
|
+
) -> None:
|
|
46
|
+
self._name = name
|
|
47
|
+
self._requires = requires
|
|
48
|
+
self._func = func
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def name(self) -> str:
|
|
52
|
+
return self._name
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def requires(self) -> list[str]:
|
|
56
|
+
return self._requires
|
|
57
|
+
|
|
58
|
+
def __repr__(self) -> str:
|
|
59
|
+
return f'FunctionAnalysis(name="{self.name}")'
|
|
60
|
+
|
|
61
|
+
@override
|
|
62
|
+
def run(self, model: Model, cache: AnalysisCache) -> T:
|
|
63
|
+
return self._func(model, cache)
|
|
64
|
+
|
|
65
|
+
def __call__(self, model: Model, cache: AnalysisCache) -> T:
|
|
66
|
+
return self._func(model, cache)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class DynamicMetaAnalysisPass(MetaAnalysisPass, Generic[T]):
|
|
70
|
+
def __init__(
|
|
71
|
+
self,
|
|
72
|
+
name: str,
|
|
73
|
+
requires: list[str],
|
|
74
|
+
func: MetaAnalysisSignature[T],
|
|
75
|
+
) -> None:
|
|
76
|
+
self._name = name
|
|
77
|
+
self._requires = requires
|
|
78
|
+
self._func = func
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def name(self) -> str:
|
|
82
|
+
return self._name
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def requires(self) -> list[str]:
|
|
86
|
+
return self._requires
|
|
87
|
+
|
|
88
|
+
def __repr__(self) -> str:
|
|
89
|
+
return f'FunctionMetaAnalysis(name="{self.name}")'
|
|
90
|
+
|
|
91
|
+
@override
|
|
92
|
+
def run(self, passes: list[BasePass], cache: AnalysisCache) -> T:
|
|
93
|
+
return self._func(passes, cache)
|
|
94
|
+
|
|
95
|
+
def __call__(self, passes: list[BasePass], cache: AnalysisCache) -> T:
|
|
96
|
+
return self._func(passes, cache)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class DynamicTransformationPass(TransformationPass):
|
|
100
|
+
def __init__(
|
|
101
|
+
self,
|
|
102
|
+
name: str,
|
|
103
|
+
requires: list[str],
|
|
104
|
+
invalidates: list[str],
|
|
105
|
+
func: TransformationSignature,
|
|
106
|
+
backwards: BackwardsSignature,
|
|
107
|
+
) -> None:
|
|
108
|
+
self._name = name
|
|
109
|
+
self._requires = requires
|
|
110
|
+
self._invalidates = invalidates
|
|
111
|
+
self._func = func
|
|
112
|
+
self._backwards = backwards
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def name(self) -> str:
|
|
116
|
+
return self._name
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def requires(self) -> list[str]:
|
|
120
|
+
return self._requires
|
|
121
|
+
|
|
122
|
+
@override
|
|
123
|
+
def run(self, model: Model, cache: AnalysisCache) -> Outcome:
|
|
124
|
+
return self._func(model, cache)
|
|
125
|
+
|
|
126
|
+
@override
|
|
127
|
+
def backwards(self, solution: Solution, cache: AnalysisCache) -> Solution:
|
|
128
|
+
return self._backwards(solution, cache)
|
|
129
|
+
|
|
130
|
+
def __call__(self, model: Model, cache: AnalysisCache) -> Outcome:
|
|
131
|
+
return self._func(model, cache)
|
|
132
|
+
|
|
133
|
+
def __repr__(self) -> str:
|
|
134
|
+
return f'FunctionTransformation(name="{self.name}")'
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def analyse(
|
|
138
|
+
name: str | None = None, requires: list[str] | None = None
|
|
139
|
+
) -> Callable[[AnalysisSignature[T]], DynamicAnalysisPass[T]]:
|
|
140
|
+
"""Create an AnalysisPass instance from a function.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
name: str | None
|
|
145
|
+
The name of the analysis pass. If no name provided, uses the function name.
|
|
146
|
+
requires: list[str] | None
|
|
147
|
+
List of required analysis passes (defaults to empty list)
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
Callable[[Callable[[Model, AnalysisCache], Any]], AnalysisPass]
|
|
152
|
+
An instance of a dynamically created AnalysisPass subclass
|
|
153
|
+
"""
|
|
154
|
+
if requires is None:
|
|
155
|
+
requires = []
|
|
156
|
+
|
|
157
|
+
_T = TypeVar("_T")
|
|
158
|
+
|
|
159
|
+
def _decorator(
|
|
160
|
+
func: AnalysisSignature[_T],
|
|
161
|
+
) -> DynamicAnalysisPass[_T]:
|
|
162
|
+
loc_name = name or func.__name__.replace("_", "-")
|
|
163
|
+
|
|
164
|
+
return DynamicAnalysisPass(name=loc_name, requires=requires, func=func)
|
|
165
|
+
|
|
166
|
+
return _decorator
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def meta_analyse(
|
|
170
|
+
name: str | None = None, requires: list[str] | None = None
|
|
171
|
+
) -> Callable[[MetaAnalysisSignature[T]], DynamicMetaAnalysisPass[T]]:
|
|
172
|
+
"""Create an MetaAnalysisPass instance from a function.
|
|
173
|
+
|
|
174
|
+
Parameters
|
|
175
|
+
----------
|
|
176
|
+
name: str | None
|
|
177
|
+
The name of the analysis pass. If no name provided, uses the function name.
|
|
178
|
+
requires: list[str] | None
|
|
179
|
+
List of required analysis passes (defaults to empty list)
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
Callable[[Callable[[list[BasePass], AnalysisCache], Any]], MetaAnalysisPass]
|
|
184
|
+
An instance of a dynamically created AnalysisPass subclass
|
|
185
|
+
"""
|
|
186
|
+
if requires is None:
|
|
187
|
+
requires = []
|
|
188
|
+
|
|
189
|
+
_T = TypeVar("_T")
|
|
190
|
+
|
|
191
|
+
def _decorator(
|
|
192
|
+
func: MetaAnalysisSignature[_T],
|
|
193
|
+
) -> DynamicMetaAnalysisPass[_T]:
|
|
194
|
+
loc_name = name or func.__name__.replace("_", "-")
|
|
195
|
+
|
|
196
|
+
return DynamicMetaAnalysisPass(name=loc_name, requires=requires, func=func)
|
|
197
|
+
|
|
198
|
+
return _decorator
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def transform(
|
|
202
|
+
name: str | None = None,
|
|
203
|
+
requires: list[str] | None = None,
|
|
204
|
+
invalidates: list[str] | None = None,
|
|
205
|
+
backwards: BackwardsSignature | None = None,
|
|
206
|
+
) -> Callable[[TransformationSignature], DynamicTransformationPass]:
|
|
207
|
+
"""Create an TransformationPass instance from a function.
|
|
208
|
+
|
|
209
|
+
Parameters
|
|
210
|
+
----------
|
|
211
|
+
name: str | None = None
|
|
212
|
+
The name of the analysis pass. If no name provided, uses the function name.
|
|
213
|
+
requires: list[str] | None = None
|
|
214
|
+
List of required analysis passes (defaults to empty list)
|
|
215
|
+
invalidates: list[str] | None = None
|
|
216
|
+
List of analysis results to invalidate (defaults to empty list)
|
|
217
|
+
backwards: BackwardsSignature | None = None,
|
|
218
|
+
Solution backwards mapping function. If none provided, pass solution upstream
|
|
219
|
+
without modification.
|
|
220
|
+
|
|
221
|
+
Returns
|
|
222
|
+
-------
|
|
223
|
+
Callable[[TransformationSignature], DynamicTransformationPass]
|
|
224
|
+
An instance of a dynamically created TransformationPass subclass
|
|
225
|
+
"""
|
|
226
|
+
if requires is None:
|
|
227
|
+
requires = []
|
|
228
|
+
if invalidates is None:
|
|
229
|
+
invalidates = []
|
|
230
|
+
|
|
231
|
+
if backwards is None:
|
|
232
|
+
backwards = __identity_backwards
|
|
233
|
+
|
|
234
|
+
def _decorator(func: TransformationSignature) -> DynamicTransformationPass:
|
|
235
|
+
loc_name = name or func.__name__.replace("_", "-")
|
|
236
|
+
|
|
237
|
+
return DynamicTransformationPass(
|
|
238
|
+
name=loc_name,
|
|
239
|
+
requires=requires,
|
|
240
|
+
invalidates=invalidates,
|
|
241
|
+
func=func,
|
|
242
|
+
backwards=backwards,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
return _decorator
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
__all__ = ["analyse", "transform"]
|
luna_quantum/errors.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Define error types for validation, failures, and runtime evaluation issues.
|
|
3
|
+
|
|
4
|
+
This module defines the set of custom exception classes used throughout the system
|
|
5
|
+
to handle errors related to model translation, environment management, solution
|
|
6
|
+
evaluation, and sampling.
|
|
7
|
+
|
|
8
|
+
The exceptions are categorized as follows:
|
|
9
|
+
|
|
10
|
+
1. **Model Errors**:
|
|
11
|
+
- Raised when a model does not meet certain structural or semantic requirements,
|
|
12
|
+
such as being quadratic, unconstrained, or having the correct variable types.
|
|
13
|
+
|
|
14
|
+
2. **Translation Errors**:
|
|
15
|
+
- Raised when issues occur during translation between formats, including both
|
|
16
|
+
model and solution translation failures.
|
|
17
|
+
|
|
18
|
+
3. **Variable and Constraint Errors**:
|
|
19
|
+
- Raised when there are issues related to variable creation, lookup, duplication,
|
|
20
|
+
or constraint naming.
|
|
21
|
+
|
|
22
|
+
4. **Environment Errors**:
|
|
23
|
+
- Raised when conflicts or inconsistencies occur in managing active environments,
|
|
24
|
+
such as having multiple active environments or none at all.
|
|
25
|
+
|
|
26
|
+
5. **Sampling and Evaluation Errors**:
|
|
27
|
+
- Raised during post-processing or evaluation of samples, particularly when the
|
|
28
|
+
sample does not conform to expected formats or contains incompatible data.
|
|
29
|
+
|
|
30
|
+
These error classes enable precise and meaningful error handling, helping developers
|
|
31
|
+
diagnose and respond to failures consistently and effectively.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from ._core.errors import * # type: ignore[reportMissingImports] # noqa: F403
|