qctrl-workflow-client 5.2.0__tar.gz → 5.3.1__tar.gz

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.
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: qctrl-workflow-client
3
- Version: 5.2.0
3
+ Version: 5.3.1
4
4
  Summary: Q-CTRL Workflow Client
5
- Home-page: https://q-ctrl.com
6
5
  License: https://q-ctrl.com/terms
7
6
  Keywords: black opal,boulder opal,fire opal,nisq,open controls,q control,q ctrl,q-control,q-ctrl,qcontrol,qctrl,quantum,quantum algorithms,quantum circuits,quantum coding,quantum coding software,quantum computing,quantum control,quantum control software,quantum control theory,quantum engineering,quantum error correction,quantum firmware,quantum fundamentals,quantum sensing,qubit,qudit
8
7
  Author: Q-CTRL
@@ -35,10 +34,11 @@ Requires-Dist: qctrl-client (>=10.1.0,<11.0.0)
35
34
  Requires-Dist: qctrl-commons (==23.3.0)
36
35
  Requires-Dist: requests (>=2.32.0,<3.0.0)
37
36
  Requires-Dist: tenacity (>=8.1.0,<9.0.0)
38
- Requires-Dist: tomli (>=2.0.1,<3.0.0)
37
+ Requires-Dist: tomli (>=2.2.1,<3.0.0)
39
38
  Project-URL: Documentation, https://docs.q-ctrl.com
40
39
  Project-URL: Facebook, https://www.facebook.com/qctrl
41
40
  Project-URL: GitHub, https://github.com/qctrl
41
+ Project-URL: Homepage, https://q-ctrl.com
42
42
  Project-URL: LinkedIn, https://www.linkedin.com/company/q-ctrl/
43
43
  Project-URL: X, https://x.com/qctrlHQ
44
44
  Project-URL: YouTube, https://www.youtube.com/qctrl
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "qctrl-workflow-client"
3
- version = "5.2.0"
3
+ version = "5.3.1"
4
4
  description = "Q-CTRL Workflow Client"
5
5
  license = "https://q-ctrl.com/terms"
6
6
  authors = ["Q-CTRL <support@q-ctrl.com>"]
@@ -75,7 +75,7 @@ priority = "supplemental"
75
75
 
76
76
  [tool.poetry.dependencies]
77
77
  python = ">=3.9, <3.13"
78
- tomli = "^2.0.1"
78
+ tomli = "^2.2.1"
79
79
  importlib-metadata = "^6.8.0"
80
80
  gql = "^3.4.0"
81
81
  tenacity = "^8.1.0"
@@ -85,15 +85,15 @@ qctrl-commons = { version = "23.3.0", source = "PyPI" }
85
85
  qctrl-client = { version = "^10.1.0", source = "PyPI" }
86
86
 
87
87
  [tool.poetry.group.dev.dependencies]
88
- black = "^24.3.0"
89
- isort = "^5.12.0"
90
- pre-commit = "^3.3.3"
91
- pylint = "^3.2.2"
92
- pytest = "^7.2.2"
93
- pytest-cov = "^4.0.0"
88
+ black = "^25.1.0"
89
+ isort = "^6.0.0"
90
+ pre-commit = "^4.1.0"
91
+ pylint = "^3.3.4"
92
+ pytest = "^8.3.4"
93
+ pytest-cov = "^6.0.0"
94
94
  pytest-mock = "^3.10.0"
95
95
  pytest-xdist = "^3.2.1"
96
- qctrl-core-workflow-manager = "^4.0.0"
96
+ qctrl-core-workflow-manager = "^5.0.0"
97
97
 
98
98
  [tool.isort]
99
99
  profile = "black"
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -11,7 +11,7 @@
11
11
  # distributed under the License is distributed on an "AS IS" BASIS. See the
12
12
  # License for the specific language.
13
13
 
14
- __version__ = "5.2.0"
14
+ __version__ = "5.3.1"
15
15
 
16
16
  from .defaults import get_authenticated_client_for_product
17
17
  from .functions import (
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -26,7 +26,10 @@ from qctrlworkflowclient.router.api import ApiRouter
26
26
 
27
27
 
28
28
  def core_workflow(
29
- get_config: Callable, workflow: str, formatter: Optional[Callable] = None
29
+ get_config: Callable,
30
+ workflow: str,
31
+ formatter: Optional[Callable] = None,
32
+ registry_selector: Optional[Callable] = None,
30
33
  ):
31
34
  """
32
35
  Decorator for a function which will execute a workflow.
@@ -55,6 +58,12 @@ def core_workflow(
55
58
  result. The callable should accept exactly one argument
56
59
  which is the raw result fo the workflow. If used, the
57
60
  decorated function will return the result of this callable.
61
+ registry_selector : Callable, optional
62
+ Optional callable which can be used to select the registry
63
+ to be used for the workflow. The callable should accept
64
+ exactly one argument which is the data returned by the
65
+ decorated function. If used, the decorated function will
66
+ return the result of this callable.
58
67
  """
59
68
 
60
69
  def decorator(func: Callable):
@@ -70,7 +79,16 @@ def core_workflow(
70
79
  router.set_async_state(kwargs.pop("is_async", False))
71
80
 
72
81
  data = func(*args, **kwargs)
73
- result = router(workflow, data)
82
+
83
+ # dynamically select the registry to be used if selector provided
84
+ # otherwise the default registry set in the router will be used
85
+ registry = registry_selector(data) if registry_selector else None
86
+
87
+ # if the router is an instance of the ApiRouter, pass the registry
88
+ if isinstance(router, ApiRouter):
89
+ result = router(workflow, data, registry=registry)
90
+ else:
91
+ result = router(workflow, data)
74
92
 
75
93
  if formatter:
76
94
  result = formatter(result)
@@ -83,7 +101,10 @@ def core_workflow(
83
101
 
84
102
 
85
103
  def async_core_workflow(
86
- get_config: Callable, workflow: str, formatter: Optional[Callable] = None
104
+ get_config: Callable,
105
+ workflow: str,
106
+ formatter: Optional[Callable] = None,
107
+ registry_selector: Optional[Callable] = None,
87
108
  ):
88
109
  """
89
110
  Decorator for a function which will execute asynchronously workflow.
@@ -112,6 +133,12 @@ def async_core_workflow(
112
133
  result. The callable should accept exactly one argument
113
134
  which is the raw result fo the workflow. If used, the
114
135
  decorated function will return the result of this callable.
136
+ registry_selector : Callable, optional
137
+ Optional callable which can be used to select the registry
138
+ to be used for the workflow. The callable should accept
139
+ exactly one argument which is the data returned by the
140
+ decorated function. If used, the decorated function will
141
+ return the result of this callable.
115
142
  """
116
143
 
117
144
  def decorator(func: Callable):
@@ -132,7 +159,16 @@ def async_core_workflow(
132
159
  )
133
160
 
134
161
  data = func(*args, **kwargs)
135
- result = router(workflow, data)
162
+
163
+ # dynamically select the registry to be used if selector provided
164
+ # otherwise the default registry set in the router will be used
165
+ registry = registry_selector(data) if registry_selector else None
166
+
167
+ # if the router is an instance of the ApiRouter, pass the registry
168
+ if isinstance(router, ApiRouter):
169
+ result = router(workflow, data, registry=registry)
170
+ else:
171
+ result = router(workflow, data)
136
172
 
137
173
  if formatter:
138
174
  result = formatter(result)
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -341,7 +341,19 @@ class ApiRouter(BaseRouter):
341
341
  self._parallel_task_collector = collector
342
342
  return collector
343
343
 
344
- def __call__(self, workflow, data=None):
344
+ def __call__(self, workflow, data=None, registry=None):
345
+ """
346
+ Executes the workflow through the API.
347
+
348
+ Parameters
349
+ ----------
350
+ workflow : str
351
+ Name of the workflow to be executed.
352
+ data : Dict[str, Any], optional
353
+ Any data required by the workflow for execution.
354
+ registry : str, optional
355
+ The registry to be used for the workflow execution.
356
+ """
345
357
  query = gql.gql(
346
358
  """
347
359
  mutation ($input: StartCoreWorkflowInput!) {
@@ -368,8 +380,13 @@ class ApiRouter(BaseRouter):
368
380
  )
369
381
 
370
382
  client_metadata = self._get_client_metadata()
383
+
384
+ # if registry is not provided, use the default registry
385
+ if registry is None:
386
+ registry = self._settings.product.value.registry
387
+
371
388
  input_ = {
372
- "registry": self._settings.product.value.registry,
389
+ "registry": registry,
373
390
  "workflow": workflow,
374
391
  "data": json.dumps(data, cls=DataTypeEncoder),
375
392
  "clientMetadata": json.dumps(client_metadata),
@@ -388,7 +405,7 @@ class ApiRouter(BaseRouter):
388
405
  raw_result=action_data["result"],
389
406
  errors=action_data["errors"],
390
407
  )
391
-
408
+ self._settings.event_dispatch("action.updated", action=action)
392
409
  if self._async:
393
410
  return {"async_result": action}
394
411
 
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -15,11 +15,7 @@ from abc import (
15
15
  ABC,
16
16
  abstractmethod,
17
17
  )
18
- from typing import (
19
- Any,
20
- Dict,
21
- Optional,
22
- )
18
+ from typing import Any
23
19
 
24
20
 
25
21
  class BaseRouter(ABC):
@@ -28,15 +24,12 @@ class BaseRouter(ABC):
28
24
  """
29
25
 
30
26
  @abstractmethod
31
- def __call__(self, workflow: str, data: Optional[Dict[str, Any]] = None) -> Any:
27
+ def __call__(
28
+ self,
29
+ *args,
30
+ **kwargs,
31
+ ) -> Any:
32
32
  """
33
33
  Given a workflow name and the corresponding data (if any),
34
34
  execute the workflow and returns the raw result.
35
-
36
- Parameters
37
- ----------
38
- workflow : str
39
- Name of the workflow to be executed.
40
- data : Dict[str, Any], optional
41
- Any data required by the workflow for execution.
42
35
  """
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -30,6 +30,16 @@ class LocalRouter(BaseRouter):
30
30
  self._resolver = resolver
31
31
 
32
32
  def __call__(self, workflow, data=None):
33
+ """
34
+ Executes the workflow locally.
35
+
36
+ Parameters
37
+ ----------
38
+ workflow : str
39
+ Name of the workflow to be executed.
40
+ data : Dict[str, Any], optional
41
+ Any data required by the workflow for execution.
42
+ """
33
43
  data = data or {}
34
44
  task = self._resolver.get_workflow_task_from_signature(workflow, **data)
35
45
  func = self._resolver(task)
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Q-CTRL. All rights reserved.
1
+ # Copyright 2025 Q-CTRL. All rights reserved.
2
2
  #
3
3
  # Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
4
4
  # copying or use of this file, via any medium, is strictly prohibited.