classiq 0.38.0__py3-none-any.whl → 0.65.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -3,12 +3,10 @@ import functools
3
3
  import itertools
4
4
  import logging
5
5
  import time
6
+ from collections.abc import AsyncGenerator, Awaitable, Iterable
6
7
  from typing import (
7
8
  Any,
8
- AsyncGenerator,
9
- Awaitable,
10
9
  Callable,
11
- Iterable,
12
10
  Optional,
13
11
  SupportsFloat,
14
12
  TypeVar,
@@ -1,20 +1,36 @@
1
1
  import urllib.parse
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, Optional, Union
3
+ from typing import Any, Optional, Union
4
4
 
5
5
  from httpx import AsyncClient, Response, codes
6
- from pydantic import BaseSettings, Field
6
+ from pydantic import Field
7
+ from pydantic_settings import BaseSettings, SettingsConfigDict
7
8
 
8
- from classiq.exceptions import ClassiqAuthenticationError
9
+ from classiq.interface.exceptions import ClassiqAuthenticationError
9
10
 
10
11
 
11
12
  class AuthSettings(BaseSettings):
12
- domain: str = Field(default="auth.classiq.io", env="CLASSIQ_AUTH_DOMAIN")
13
- audience: str = Field(default="https://cadmium-be", env="CLASSIQ_AUTH_AUDIENCE")
13
+ domain: str = Field(
14
+ default="auth.classiq.io", validation_alias="CLASSIQ_AUTH_DOMAIN"
15
+ )
16
+ audience: str = Field(
17
+ default="https://cadmium-be", validation_alias="CLASSIQ_AUTH_AUDIENCE"
18
+ )
14
19
  client_id: str = Field(
15
- default="f6721qMOVoDAOVkzrv8YaWassRKSFX6Y", env="CLASSIQ_AUTH_CLIENT_ID"
20
+ default="f6721qMOVoDAOVkzrv8YaWassRKSFX6Y",
21
+ validation_alias="CLASSIQ_AUTH_CLIENT_ID",
16
22
  )
17
23
 
24
+ model_config = SettingsConfigDict(extra="allow")
25
+
26
+ def __init__(self, **data: Any) -> None:
27
+ initial_data = {
28
+ field: data[field] for field in data if field in self.model_fields
29
+ }
30
+ super().__init__(**data)
31
+ for field, value in initial_data.items():
32
+ setattr(self, field, value)
33
+
18
34
 
19
35
  @dataclass
20
36
  class Tokens:
@@ -40,9 +56,9 @@ class Auth0:
40
56
  async def _make_request(
41
57
  self,
42
58
  url: str,
43
- payload: Dict[str, str],
59
+ payload: dict[str, str],
44
60
  allow_error: Union[bool, int] = False,
45
- ) -> Dict[str, Any]:
61
+ ) -> dict[str, Any]:
46
62
  encoded_payload = urllib.parse.urlencode(payload)
47
63
  client: AsyncClient
48
64
  async with AsyncClient(
@@ -60,7 +76,7 @@ class Auth0:
60
76
  f"Request to Auth0 failed with error code {code}: {data.get('error')}"
61
77
  )
62
78
 
63
- async def get_device_data(self, get_refresh_token: bool = True) -> Dict[str, Any]:
79
+ async def get_device_data(self, get_refresh_token: bool = True) -> dict[str, Any]:
64
80
  payload = {
65
81
  "client_id": self._auth_settings.client_id,
66
82
  "audience": self._auth_settings.audience,
@@ -73,7 +89,7 @@ class Auth0:
73
89
  payload=payload,
74
90
  )
75
91
 
76
- async def poll_tokens(self, device_code: str) -> Dict[str, Any]:
92
+ async def poll_tokens(self, device_code: str) -> dict[str, Any]:
77
93
  payload = {
78
94
  "client_id": self._client_id,
79
95
  "device_code": device_code,
@@ -3,6 +3,17 @@ from classiq._internals.client import client
3
3
 
4
4
 
5
5
  def authenticate(overwrite: bool = False) -> None:
6
+ """
7
+
8
+ Authenticate to access the Classiq platform.
9
+
10
+ Args:
11
+ overwrite: A flag indicating whether to overwrite the existing
12
+ authentication tokens. Defaults to `False`.
13
+
14
+ If you are not registered, please visit the Classiq platform
15
+ to complete registration: https://platform.classiq.io/
16
+ """
6
17
  async_utils.run(authenticate_async(overwrite))
7
18
 
8
19
 
@@ -1,11 +1,16 @@
1
1
  import asyncio
2
2
  import webbrowser
3
+ from collections.abc import Iterable
3
4
  from datetime import timedelta
4
- from typing import Any, Dict, Iterable, Optional, TypeVar
5
+ from typing import Any, Optional, TypeVar
6
+
7
+ from classiq.interface.exceptions import (
8
+ ClassiqAuthenticationError,
9
+ ClassiqExpiredTokenError,
10
+ )
5
11
 
6
12
  from classiq._internals.async_utils import poll_for
7
13
  from classiq._internals.authentication.auth0 import Auth0, Tokens
8
- from classiq.exceptions import ClassiqAuthenticationError, ClassiqExpiredTokenError
9
14
 
10
15
  T = TypeVar("T")
11
16
 
@@ -22,7 +27,7 @@ class DeviceRegistrar:
22
27
  cls, get_refresh_token: bool = True, text_only: bool = False
23
28
  ) -> Tokens:
24
29
  auth0_client = Auth0()
25
- data: Dict[str, Any] = await auth0_client.get_device_data(
30
+ data: dict[str, Any] = await auth0_client.get_device_data(
26
31
  get_refresh_token=get_refresh_token
27
32
  )
28
33
 
@@ -44,7 +49,7 @@ class DeviceRegistrar:
44
49
 
45
50
  @classmethod
46
51
  def _handle_ready_data(
47
- cls, data: Dict[str, Any], get_refresh_token: bool
52
+ cls, data: dict[str, Any], get_refresh_token: bool
48
53
  ) -> Tokens:
49
54
  access_token: Optional[str] = data.get("access_token")
50
55
  # If refresh token was not requested, this would be None
@@ -68,7 +73,7 @@ class DeviceRegistrar:
68
73
  timeout: float,
69
74
  get_refresh_token: bool = True,
70
75
  ) -> Tokens:
71
- async def poller() -> Dict[str, Any]:
76
+ async def poller() -> dict[str, Any]:
72
77
  nonlocal device_code
73
78
  return await auth0_client.poll_tokens(device_code=device_code)
74
79
 
@@ -5,23 +5,35 @@ import os
5
5
  import pathlib
6
6
  import platform
7
7
  import stat
8
- from typing import Dict, Optional
8
+ from typing import Any, Optional
9
9
 
10
10
  import keyring
11
11
  from keyring.backends import fail
12
- from pydantic import BaseSettings, Field
12
+ from pydantic import Field
13
+ from pydantic_settings import BaseSettings, SettingsConfigDict
13
14
 
14
15
  _logger = logging.getLogger(__name__)
15
16
 
16
17
 
17
18
  class PasswordManagerSettings(BaseSettings):
18
19
  ACCESS_TOKEN_KEY: str = Field(
19
- default="classiqTokenAccount", env="CLASSIQ_ACCESS_TOKEN_ACCOUNT"
20
+ default="classiqTokenAccount", validation_alias="CLASSIQ_ACCESS_TOKEN_ACCOUNT"
20
21
  )
21
22
  REFRESH_TOKEN_KEY: str = Field(
22
- default="classiqRefershTokenAccount", env="CLASSIQ_REFRESH_TOKEN_ACCOUNT"
23
+ default="classiqRefershTokenAccount",
24
+ validation_alias="CLASSIQ_REFRESH_TOKEN_ACCOUNT",
23
25
  )
24
26
 
27
+ model_config = SettingsConfigDict(extra="allow")
28
+
29
+ def __init__(self, **data: Any) -> None:
30
+ initial_data = {
31
+ field: data[field] for field in data if field in self.model_fields
32
+ }
33
+ super().__init__(**data)
34
+ for field, value in initial_data.items():
35
+ setattr(self, field, value)
36
+
25
37
 
26
38
  class PasswordManager(abc.ABC):
27
39
  _SERVICE_NAME: str = "classiqTokenService"
@@ -112,12 +124,12 @@ class FilePasswordManager(PasswordManager):
112
124
  super().__init__()
113
125
  self.credentials_file = pathlib.Path(self._CLASSIQ_CREDENTIALS_FILE_PATH)
114
126
 
115
- def _update_file(self, token_dict: Dict) -> None:
127
+ def _update_file(self, token_dict: dict) -> None:
116
128
  self.credentials_file.touch()
117
129
  self.credentials_file.chmod(stat.S_IRUSR | stat.S_IWUSR)
118
130
  self.credentials_file.write_text(json.dumps(token_dict))
119
131
 
120
- def _get_token_dict(self) -> Dict:
132
+ def _get_token_dict(self) -> dict:
121
133
  if self.credentials_file.exists():
122
134
  return json.loads(self.credentials_file.read_text())
123
135
  return {}
@@ -2,18 +2,23 @@ import argparse
2
2
  import logging
3
3
  import threading
4
4
  import warnings
5
+ from collections.abc import Sequence
5
6
  from typing import Optional
6
7
 
8
+ from classiq.interface.exceptions import (
9
+ ClassiqAuthenticationError,
10
+ ClassiqPasswordManagerSelectionError,
11
+ )
12
+
7
13
  from classiq._internals.authentication import password_manager as pm
8
14
  from classiq._internals.authentication.auth0 import Auth0
9
15
  from classiq._internals.authentication.device import DeviceRegistrar, Tokens
10
16
  from classiq._internals.config import Configuration
11
- from classiq.exceptions import (
12
- ClassiqAuthenticationError,
13
- ClassiqPasswordManagerSelectionError,
14
- )
15
17
 
16
- PASSWORD_MANAGERS = [pm.KeyringPasswordManager, pm.FilePasswordManager]
18
+ PASSWORD_MANAGERS: Sequence[type[pm.PasswordManager]] = [
19
+ pm.KeyringPasswordManager,
20
+ pm.FilePasswordManager,
21
+ ]
17
22
  _logger = logging.getLogger(__name__)
18
23
 
19
24
 
@@ -1,23 +1,26 @@
1
1
  import asyncio
2
+ import contextlib
2
3
  import functools
3
4
  import inspect
4
5
  import logging
5
6
  import os
6
7
  import platform
7
- import ssl
8
8
  import sys
9
- from typing import Any, Awaitable, Callable, Dict, NoReturn, Optional, TypeVar, Union
9
+ import time
10
+ from collections.abc import Awaitable
11
+ from types import TracebackType
12
+ from typing import Any, Callable, NoReturn, Optional, TypeVar, Union
10
13
 
11
14
  import httpx
12
- from packaging.version import Version
13
15
  from typing_extensions import ParamSpec
14
16
 
15
17
  from classiq.interface._version import VERSION as _VERSION
18
+ from classiq.interface.exceptions import ClassiqAPIError, ClassiqExpiredTokenError
19
+ from classiq.interface.interface_version import INTERFACE_VERSION
16
20
 
17
21
  from classiq._internals import config
18
22
  from classiq._internals.authentication import token_manager
19
23
  from classiq._internals.host_checker import HostChecker
20
- from classiq.exceptions import ClassiqAPIError, ClassiqExpiredTokenError
21
24
 
22
25
  _FRONTEND_VARIANT: str = "classiq-sdk"
23
26
  _INTERFACE_VARIANT: str = "classiq-interface-sdk"
@@ -27,7 +30,7 @@ _logger = logging.getLogger(__name__)
27
30
 
28
31
  _RETRY_COUNT = 2
29
32
 
30
- Headers = Dict[str, str]
33
+ Headers = dict[str, str]
31
34
 
32
35
  APPROVED_API_ERROR_MESSAGES_FOR_RESTART = [
33
36
  "Call to API failed with code 502",
@@ -135,28 +138,42 @@ def try_again_on_failure(
135
138
  return wrapper
136
139
 
137
140
 
141
+ class _AsyncNullContext(contextlib.AbstractAsyncContextManager):
142
+ """
143
+ This class is meant to replace `contextlib.nullcontext`, which hadn't supported
144
+ async context manager until python 3.10.
145
+ """
146
+
147
+ def __init__(self, enter_result: Any = None) -> None:
148
+ self._enter_result = enter_result
149
+
150
+ async def __aenter__(self) -> Any:
151
+ return self._enter_result
152
+
153
+ async def __aexit__(
154
+ self,
155
+ exc_type: Optional[type[BaseException]],
156
+ exc_val: Optional[BaseException],
157
+ exc_tb: Optional[TracebackType],
158
+ ) -> None:
159
+ pass
160
+
161
+
138
162
  class Client:
139
163
  _UNKNOWN_VERSION = HostChecker._UNKNOWN_VERSION
140
164
  _SESSION_HEADER = "Classiq-Session"
141
165
  _WARNINGS_HEADER = "X-Classiq-Warnings"
142
- _LATEST_VERSION_API_PREFIX = "/api/v1"
166
+ _HTTP_TIMEOUT_SECONDS = 3600 # Needs to be synced with load-balancer timeout
143
167
 
144
168
  def __init__(self, conf: config.Configuration) -> None:
145
169
  self._config = conf
146
170
  self._token_manager = token_manager.TokenManager(config=self._config)
147
- self._ssl_context = ssl.create_default_context()
148
- self._HTTP_TIMEOUT_SECONDS = (
149
- 3600 # Needs to be synced with load-balancer timeout
150
- )
151
171
  self._api_prefix = self._make_api_prefix()
152
172
  self._session_id: Optional[str] = None
153
173
 
154
- @classmethod
155
- def _make_api_prefix(cls) -> str:
156
- if _VERSION == cls._UNKNOWN_VERSION:
157
- return cls._LATEST_VERSION_API_PREFIX
158
- parsed_version = Version(_VERSION)
159
- return f"/api/v{parsed_version.major}-{parsed_version.minor}"
174
+ @staticmethod
175
+ def _make_api_prefix() -> str:
176
+ return f"/api/v{INTERFACE_VERSION}"
160
177
 
161
178
  def make_versioned_url(self, url_postfix: str) -> str:
162
179
  return self._api_prefix + url_postfix
@@ -196,46 +213,90 @@ class Client:
196
213
  message += f": {detail}"
197
214
  except Exception: # noqa: S110
198
215
  pass
199
- raise ClassiqAPIError(message)
216
+ raise ClassiqAPIError(message, response.status_code)
200
217
 
201
- def _make_client_args(self) -> Dict[str, Any]:
218
+ @try_again_on_failure
219
+ async def request(
220
+ self,
221
+ http_client: httpx.AsyncClient,
222
+ method: str,
223
+ url: str,
224
+ json: Optional[dict] = None,
225
+ params: Optional[dict] = None,
226
+ headers: Optional[dict[str, str]] = None,
227
+ ) -> httpx.Response:
228
+ http_client.headers.update(self._get_headers())
229
+
230
+ _logger.debug("HTTP request: %s %s", method.upper(), url)
231
+ start_time = time.monotonic()
232
+ response = await http_client.request(
233
+ method=method,
234
+ url=url,
235
+ json=json,
236
+ params=params,
237
+ headers=headers,
238
+ )
239
+ _logger.debug(
240
+ "HTTP response: %s %s %d (%.0fms)",
241
+ method.upper(),
242
+ url,
243
+ response.status_code,
244
+ (time.monotonic() - start_time) * 1000,
245
+ )
246
+ self.handle_response(response)
247
+ return response
248
+
249
+ def _make_client_args(self) -> dict[str, Any]:
202
250
  return {
203
- "base_url": self._config.host,
251
+ "base_url": str(self._config.host),
204
252
  "timeout": self._HTTP_TIMEOUT_SECONDS,
205
- "headers": self.get_headers(),
253
+ "headers": self._get_headers(),
206
254
  }
207
255
 
208
- @try_again_on_failure
209
256
  async def call_api(
210
257
  self,
211
258
  http_method: str,
212
259
  url: str,
213
- body: Optional[Dict] = None,
214
- params: Optional[Dict] = None,
260
+ body: Optional[dict] = None,
261
+ params: Optional[dict] = None,
215
262
  use_versioned_url: bool = True,
216
- headers: Optional[Dict[str, str]] = None,
217
- ) -> Union[Dict, str]:
263
+ headers: Optional[dict[str, str]] = None,
264
+ http_client: Optional[httpx.AsyncClient] = None,
265
+ ) -> Union[dict, list, str]:
218
266
  if use_versioned_url:
219
267
  url = self.make_versioned_url(url)
220
- async with self.async_client() as async_client:
221
- response = await async_client.request(
268
+ async with self.use_client_or_create(http_client) as async_client:
269
+ response = await self.request(
270
+ http_client=async_client,
222
271
  method=http_method,
223
272
  url=url,
224
273
  json=body,
225
274
  params=params,
226
275
  headers=headers,
227
276
  )
228
- self.handle_response(response)
229
277
  return response.json()
230
278
 
279
+ def use_client_or_create(
280
+ self, http_client: Optional[httpx.AsyncClient]
281
+ ) -> contextlib.AbstractAsyncContextManager[httpx.AsyncClient]:
282
+ if http_client is None:
283
+ return self.async_client()
284
+ else:
285
+ if sys.version_info[0:2] < (3, 10):
286
+ # remove this `if` and the `_AsyncNullContext` class when we stop
287
+ # supporting python 3.9
288
+ return _AsyncNullContext(enter_result=http_client)
289
+ else:
290
+ return contextlib.nullcontext(enter_result=http_client)
291
+
231
292
  def sync_call_api(
232
293
  self,
233
294
  http_method: str,
234
295
  url: str,
235
- body: Optional[Dict] = None,
236
- headers: Optional[Dict] = None,
296
+ body: Optional[dict] = None,
297
+ headers: Optional[dict] = None,
237
298
  use_versioned_url: bool = True,
238
- ) -> Union[Dict, str]:
299
+ ) -> Union[dict, str]:
239
300
  if use_versioned_url:
240
301
  url = self.make_versioned_url(url)
241
302
  with httpx.Client(**self._make_client_args()) as sync_client:
@@ -248,7 +309,7 @@ class Client:
248
309
  def async_client(self) -> httpx.AsyncClient:
249
310
  return httpx.AsyncClient(**self._make_client_args())
250
311
 
251
- def get_headers(self) -> Headers:
312
+ def _get_headers(self) -> Headers:
252
313
  headers = dict()
253
314
  access_token = self._token_manager.get_access_token()
254
315
  if access_token is not None:
@@ -262,7 +323,7 @@ class Client:
262
323
  await self._token_manager.update_expired_access_token()
263
324
 
264
325
  def get_backend_uri(self) -> str:
265
- return self._config.host
326
+ return self._config.host.unicode_string()
266
327
 
267
328
  def check_host(self) -> None:
268
329
  # This function is NOT async (despite the fact that it can be) because it's called from a non-async context.
@@ -2,16 +2,15 @@
2
2
 
3
3
  import os
4
4
  import pathlib
5
- from typing import List, Optional, Union
5
+ from typing import Optional, Union
6
6
 
7
7
  import configargparse # type: ignore[import]
8
8
  import pydantic
9
9
  from pydantic import BaseModel
10
10
 
11
+ from classiq.interface.enum_utils import StrEnum
11
12
  from classiq.interface.server.routes import DEFAULT_IDE_FE_APP
12
13
 
13
- from classiq._internals.enum_utils import StrEnum
14
-
15
14
  DEFAULT_HOST = "https://api.classiq.io"
16
15
 
17
16
 
@@ -54,7 +53,7 @@ if os.name == "posix":
54
53
  ] + _DEFAULT_CONFIG_FILES
55
54
 
56
55
 
57
- def init(args: Optional[Union[str, List[str]]] = None) -> Configuration:
56
+ def init(args: Optional[Union[str, list[str]]] = None) -> Configuration:
58
57
  """Initialize the configuration object.
59
58
 
60
59
  Args:
@@ -1,6 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
+ import warnings
5
+ from datetime import datetime
4
6
  from typing import TYPE_CHECKING, Optional
5
7
 
6
8
  import httpx
@@ -8,10 +10,10 @@ import pydantic
8
10
  from packaging.version import Version
9
11
  from pydantic import BaseModel
10
12
 
13
+ from classiq.interface.exceptions import ClassiqAPIError, ClassiqDeprecationWarning
14
+ from classiq.interface.interface_version import INTERFACE_VERSION
11
15
  from classiq.interface.server.global_versions import DeprecationInfo, GlobalVersions
12
16
 
13
- from classiq.exceptions import ClassiqAPIError
14
-
15
17
  if TYPE_CHECKING:
16
18
  from classiq._internals.client import Client
17
19
 
@@ -26,16 +28,32 @@ class HostVersions(BaseModel):
26
28
  class HostChecker:
27
29
  _UNKNOWN_VERSION = "0.0.0"
28
30
 
29
- def __init__(self, client: Client, client_version: str) -> None:
31
+ def __init__(
32
+ self,
33
+ client: Client,
34
+ client_version: str,
35
+ interface_version: str = INTERFACE_VERSION,
36
+ ) -> None:
30
37
  self._client = client
31
38
  self._client_version = client_version
39
+ self._interface_version = interface_version
40
+
41
+ def _get_interface_version(self) -> Optional[str]:
42
+ global_interfaces = GlobalVersions.model_validate(
43
+ self._client.sync_call_api(
44
+ "get", "/interface_versions", use_versioned_url=False
45
+ )
46
+ )
47
+ return global_interfaces.deployed.get(self._interface_version, None)
32
48
 
33
49
  def _get_host_version(self) -> str:
34
- host = HostVersions.parse_obj(self._client.sync_call_api("get", "/versions"))
50
+ host = HostVersions.model_validate(
51
+ self._client.sync_call_api("get", "/versions")
52
+ )
35
53
  return host.classiq_interface
36
54
 
37
55
  def _get_deprecation_info(self) -> Optional[DeprecationInfo]:
38
- global_versions = GlobalVersions.parse_obj(
56
+ global_versions = GlobalVersions.model_validate(
39
57
  self._client.sync_call_api("get", "/versions", use_versioned_url=False)
40
58
  )
41
59
  return global_versions.deprecated.get(self._client_version, None)
@@ -56,18 +74,16 @@ class HostChecker:
56
74
 
57
75
  def check_host_version(self) -> None:
58
76
  try:
59
- raw_host_version = self._get_host_version()
77
+ interface_version = self._get_interface_version()
60
78
  except httpx.ConnectError:
61
79
  _logger.warning(
62
80
  "Version check failed - host unavailable.",
63
81
  )
64
82
  else:
65
- if not self._check_matching_versions(
66
- raw_host_version, self._client_version
67
- ):
83
+ if interface_version is None:
68
84
  raise ClassiqAPIError(
69
- f"Classiq API version mismatch: 'classiq' version is "
70
- f"{self._client_version}, backend version is {raw_host_version}. {_VERSION_UPDATE_SUGGESTION}"
85
+ f"You are using an unsupported version of Classiq SDK - {self._client_version}. "
86
+ f"{_VERSION_UPDATE_SUGGESTION}"
71
87
  )
72
88
 
73
89
  def check_deprecated_version(self) -> None:
@@ -80,8 +96,15 @@ class HostChecker:
80
96
  else:
81
97
  if deprecation_info is None:
82
98
  return
83
- _logger.warning(
84
- "The current version of 'classiq' has been deprecated, and will not be supported as of %s. %s",
85
- deprecation_info.removal_date.date(),
86
- _VERSION_UPDATE_SUGGESTION,
99
+ removal_date = (
100
+ deprecation_info.removal_date.date()
101
+ if isinstance(deprecation_info.removal_date, datetime)
102
+ else deprecation_info.removal_date
103
+ )
104
+ warnings.warn(
105
+ f"The current version of 'classiq' has been deprecated, and"
106
+ f" will not be supported as of {removal_date}. "
107
+ f"{_VERSION_UPDATE_SUGGESTION}",
108
+ ClassiqDeprecationWarning,
109
+ stacklevel=2,
87
110
  )