qall 0.1.0__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.
qall-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.3
2
+ Name: qall
3
+ Version: 0.1.0
4
+ Summary: A python tool for modern hybrid and quantum workflows.
5
+ Requires-Dist: cloudpickle==3.1.2
6
+ Requires-Dist: dataclasses-json>=0.6.7
7
+ Requires-Dist: docker>=7.1.0
8
+ Requires-Dist: grpcio>=1.81.1
9
+ Requires-Dist: keyring>=25.7.0
10
+ Requires-Dist: matplotlib>=3.11.0
11
+ Requires-Dist: pyan3>=2.5.0
12
+ Requires-Dist: pyyaml>=6.0.3
13
+ Requires-Dist: qio>=0.2.2
14
+ Requires-Dist: rustworkx==0.17.1
15
+ Requires-Dist: typer>=0.26.7
16
+ Requires-Dist: lmdb>=2.3.0
17
+ Requires-Dist: retry==0.9.2
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Hybrid computing as a Service
22
+
23
+ ## Protobuf
24
+
25
+ To re-generate registry client/server API:
26
+
27
+ ```bash
28
+ cd protobuf/
29
+
30
+ make registry
31
+ ```
32
+
33
+ To re-generate daemon client/server API:
34
+
35
+ ```bash
36
+ cd protobuf/
37
+
38
+ make daemon
39
+ ```
40
+
41
+ ## Registry server
42
+
43
+ To test registry server:
44
+ ```bash
45
+ cd qall-registry-server/
46
+
47
+ make test
48
+ ```
49
+
50
+ To build registry server:
51
+ ```bash
52
+ cd qall-registry-server/
53
+
54
+ make build
55
+ ```
56
+
57
+ To start local instructure
58
+ ```bash
59
+ cd infrastructure/local/
60
+
61
+ make start
62
+ ```
63
+
64
+ ## Registry client
65
+
66
+ To install registry client:
67
+ ```bash
68
+ cd qall-registry-client/
69
+
70
+ pip install .
71
+ ```
72
+
73
+ To test registry client:
74
+ ```bash
75
+ cd qall-registry-client/
76
+
77
+ export qall_REGISTRY_URL=localhost:50051; pytest -vvv tests/
78
+ ```
79
+
80
+ ## Daemon server
81
+
82
+ To run daemon server:
83
+ ```bash
84
+ make build
85
+
86
+ qall daemon start
87
+ ```
88
+
89
+ ## Daemon client
90
+
91
+ To install daemon client:
92
+ ```bash
93
+ cd qall-daemon-client/
94
+
95
+ pip install .
96
+ ```
97
+
98
+ ## Scaleway HCaaS client
99
+ TODO
100
+
101
+ ## qall (SDK)
102
+
103
+ To install qall sdk:
104
+ ```bash
105
+ cd qall/
106
+
107
+ pip install .
108
+ ```
109
+
110
+ To push a project to the registry:
111
+ ```bash
112
+ cd qall/
113
+
114
+ pip install .
115
+
116
+ qall registry push examples/basic_hierarchy/my_worflow.py
117
+
118
+ qall daemon start
119
+
120
+ qall daemon run <root hash>
121
+ ```
qall-0.1.0/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Hybrid computing as a Service
2
+
3
+ ## Protobuf
4
+
5
+ To re-generate registry client/server API:
6
+
7
+ ```bash
8
+ cd protobuf/
9
+
10
+ make registry
11
+ ```
12
+
13
+ To re-generate daemon client/server API:
14
+
15
+ ```bash
16
+ cd protobuf/
17
+
18
+ make daemon
19
+ ```
20
+
21
+ ## Registry server
22
+
23
+ To test registry server:
24
+ ```bash
25
+ cd qall-registry-server/
26
+
27
+ make test
28
+ ```
29
+
30
+ To build registry server:
31
+ ```bash
32
+ cd qall-registry-server/
33
+
34
+ make build
35
+ ```
36
+
37
+ To start local instructure
38
+ ```bash
39
+ cd infrastructure/local/
40
+
41
+ make start
42
+ ```
43
+
44
+ ## Registry client
45
+
46
+ To install registry client:
47
+ ```bash
48
+ cd qall-registry-client/
49
+
50
+ pip install .
51
+ ```
52
+
53
+ To test registry client:
54
+ ```bash
55
+ cd qall-registry-client/
56
+
57
+ export qall_REGISTRY_URL=localhost:50051; pytest -vvv tests/
58
+ ```
59
+
60
+ ## Daemon server
61
+
62
+ To run daemon server:
63
+ ```bash
64
+ make build
65
+
66
+ qall daemon start
67
+ ```
68
+
69
+ ## Daemon client
70
+
71
+ To install daemon client:
72
+ ```bash
73
+ cd qall-daemon-client/
74
+
75
+ pip install .
76
+ ```
77
+
78
+ ## Scaleway HCaaS client
79
+ TODO
80
+
81
+ ## qall (SDK)
82
+
83
+ To install qall sdk:
84
+ ```bash
85
+ cd qall/
86
+
87
+ pip install .
88
+ ```
89
+
90
+ To push a project to the registry:
91
+ ```bash
92
+ cd qall/
93
+
94
+ pip install .
95
+
96
+ qall registry push examples/basic_hierarchy/my_worflow.py
97
+
98
+ qall daemon start
99
+
100
+ qall daemon run <root hash>
101
+ ```
@@ -0,0 +1,44 @@
1
+ [project]
2
+ name = "qall"
3
+ version = "0.1.0"
4
+ description = "A python tool for modern hybrid and quantum workflows."
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "cloudpickle==3.1.2",
9
+ "dataclasses-json>=0.6.7",
10
+ "docker>=7.1.0",
11
+ "grpcio>=1.81.1",
12
+ "keyring>=25.7.0",
13
+ "matplotlib>=3.11.0",
14
+ "pyan3>=2.5.0",
15
+ "pyyaml>=6.0.3",
16
+ "qio>=0.2.2",
17
+ "rustworkx==0.17.1",
18
+ "typer>=0.26.7",
19
+ "lmdb>=2.3.0",
20
+ "retry==0.9.2",
21
+ ]
22
+
23
+ ### Dependencies ###
24
+ [dependency-groups]
25
+ dev = [
26
+ "black>=26.1.0",
27
+ ]
28
+ test = [
29
+ "pytest>=9.1.0",
30
+ "pytest-progress>=1.4.0",
31
+ ]
32
+
33
+ ### CLI Tool ###
34
+ [project.scripts]
35
+ qall = "qall.cli.main:cli"
36
+
37
+ [build-system]
38
+ requires = ["uv_build>=0.11.29,<0.12"]
39
+ build-backend = "uv_build"
40
+
41
+ [tool.uv.build-backend]
42
+ module-name = "qall"
43
+ module-root = ""
44
+ data = ["qall/data"]
@@ -0,0 +1,35 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import logging
16
+
17
+ formatter = logging.Formatter(
18
+ fmt="[%(asctime)s] %(levelname)s | %(name)s | %(message)s",
19
+ datefmt="%Y-%m-%d %H:%M:%S",
20
+ )
21
+
22
+ console_handler = logging.StreamHandler()
23
+ console_handler.setFormatter(formatter)
24
+
25
+ logger = logging.getLogger(__name__)
26
+ logger.setLevel(logging.INFO)
27
+ logger.addHandler(console_handler)
28
+
29
+ # Optional: Prevent logs from propagating to the global root logger
30
+ # to avoid duplicate logs if the end-user also configures logging.
31
+ logger.propagate = False
32
+
33
+ from qorus.sdk import task, workflow, run
34
+
35
+ __all__ = ["task", "workflow", "run"]
@@ -0,0 +1,13 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
@@ -0,0 +1,53 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import typer
15
+
16
+ from qorus.core import artifact
17
+
18
+ artifact_cli = typer.Typer(
19
+ name="artifact",
20
+ help="Inspect and download generated execution artifacts.",
21
+ no_args_is_help=True,
22
+ )
23
+
24
+
25
+ @artifact_cli.command("ls")
26
+ def list_artifacts(
27
+ workflow_run_id: str = typer.Argument(
28
+ ..., help="The ID of the workflow run to list artifacts for."
29
+ )
30
+ ):
31
+ typer.echo("Available artifacts:")
32
+
33
+ artifacts = artifact.list_artifacts(workflow_run_id)
34
+
35
+ if not artifacts:
36
+ typer.echo(" No artifacts found.")
37
+ return
38
+
39
+ for name in artifacts:
40
+ typer.echo(f"- {typer.style(name, bold=True)}")
41
+
42
+
43
+ @artifact_cli.command("info")
44
+ def artifact_info(
45
+ artifact_id: str = typer.Argument(
46
+ ..., help="The unique identifier tracking hash of the generated asset."
47
+ )
48
+ ):
49
+ """Display download links, sizing, and origin execution contexts for a specific task artifact."""
50
+ art = artifact.get_artifact(artifact_id=artifact_id)
51
+ typer.echo(
52
+ f"Artifact Name: {art.name} | Task Run Origin: {art.task_run_id} | URL: {art.url}"
53
+ )
@@ -0,0 +1,22 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import typer
15
+
16
+ import qorus.core as core
17
+
18
+ checkpoint_cli = typer.Typer(
19
+ name="checkpoint",
20
+ help="Inspect generated execution task checkpoints.",
21
+ no_args_is_help=True,
22
+ )
@@ -0,0 +1,44 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import typer
15
+
16
+ from typing import Optional
17
+
18
+ import qorus.core as core
19
+
20
+ config_cli = typer.Typer(
21
+ name="config",
22
+ help="Manage local configuration profile configurations.",
23
+ no_args_is_help=True,
24
+ )
25
+
26
+
27
+ @config_cli.command("init")
28
+ def config_init(
29
+ provider: Optional[str] = typer.Option(
30
+ "scaleway", "--provider", help="Default target cloud provider name."
31
+ ),
32
+ erase: bool = typer.Option(
33
+ False, "--erase", help="Overwrite existing configuration files if present."
34
+ ),
35
+ ):
36
+ """Initialize a default .qorus.yml project layout file inside the current directory boundary."""
37
+ res = core.init_config(provider_name=provider, erase_exists=erase)
38
+
39
+ if res is None:
40
+ typer.echo("Configuration file already exists. Use --erase to force overwrite.")
41
+ else:
42
+ typer.echo(
43
+ "Project workspace configuration initialized successfully (.qorus.yml)."
44
+ )
@@ -0,0 +1,217 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import typer
16
+
17
+ from typing import Optional
18
+
19
+ from qorus.core.daemon import (
20
+ start_daemon,
21
+ run_task,
22
+ get_daemon_status,
23
+ stop_daemon,
24
+ restart_daemon,
25
+ )
26
+
27
+ daemon_cli = typer.Typer(
28
+ name="daemon",
29
+ help="Manage daemon",
30
+ no_args_is_help=True,
31
+ )
32
+
33
+
34
+ @daemon_cli.command("start")
35
+ def daemon_start(
36
+ port: int = typer.Option(50053, "--port", "-p", help="gRPC port for the daemon"),
37
+ image: str = typer.Option(
38
+ None,
39
+ "--image",
40
+ "-i",
41
+ help="Daemon Docker image to use",
42
+ ),
43
+ block_registry: str = typer.Option(
44
+ None,
45
+ "--block-dir",
46
+ "-b",
47
+ help="Path to block registry directory",
48
+ ),
49
+ artifact_registry: str = typer.Option(
50
+ None,
51
+ "--artifact-dir",
52
+ "-a",
53
+ help="Path to artifact registry directory",
54
+ ),
55
+ worker_provider: str = typer.Option(
56
+ None,
57
+ "--worker-provider",
58
+ "-w",
59
+ help="Name of the worker provider",
60
+ ),
61
+ ):
62
+ """
63
+ Start a local Qorus daemon in a Docker container.
64
+ """
65
+ try:
66
+ start_daemon(
67
+ port=port,
68
+ block_registry_path=block_registry,
69
+ artifact_registry_path=artifact_registry,
70
+ image=image,
71
+ worker_provider=worker_provider,
72
+ )
73
+ except KeyboardInterrupt:
74
+ typer.echo("Daemon stopped.")
75
+ except Exception as e:
76
+ typer.echo(f"Error: {e}", err=True)
77
+ raise typer.Exit(code=1)
78
+
79
+
80
+ @daemon_cli.command("stop")
81
+ def daemon_stop(
82
+ port: int = typer.Option(50053, "--port", "-p", help="gRPC port for the daemon"),
83
+ ):
84
+ try:
85
+ stop_daemon(port)
86
+ except Exception as e:
87
+ typer.echo(f"Error: {e}", err=True)
88
+ raise typer.Exit(code=1)
89
+
90
+
91
+ @daemon_cli.command("restart")
92
+ def daemon_restart(
93
+ port: int = typer.Option(50053, "--port", "-p", help="gRPC port for the daemon"),
94
+ ):
95
+ try:
96
+ restart_daemon(port)
97
+ except Exception as e:
98
+ typer.echo(f"Error: {e}", err=True)
99
+ raise typer.Exit(code=1)
100
+
101
+
102
+ @daemon_cli.command("run")
103
+ def daemon_run(
104
+ task_hash: str = typer.Argument(
105
+ ..., help="Hash of the task stored in registry to execute."
106
+ ),
107
+ artifact_hash: str = typer.Option(
108
+ None,
109
+ "--artifact-hash",
110
+ "-a",
111
+ help="Hash of the input artifact stored in registry for the task execution.",
112
+ ),
113
+ daemon_image: str = typer.Option(
114
+ None,
115
+ "--daemon-image",
116
+ "-i",
117
+ help="Daemon Docker image to use",
118
+ ),
119
+ daemon_address: Optional[str] = typer.Option(
120
+ None,
121
+ "--daemon-address",
122
+ "-d",
123
+ help="Daemon gRPC address (default: QORUS_DAEMON_ADDRESS env var or localhost:50053)",
124
+ ),
125
+ block_registry: str = typer.Option(
126
+ None,
127
+ "--block-dir",
128
+ "-b",
129
+ help="Path to block registry directory",
130
+ ),
131
+ artifact_registry: str = typer.Option(
132
+ None,
133
+ "--artifact-dir",
134
+ "-a",
135
+ help="Path to artifact registry directory",
136
+ ),
137
+ worker_provider: str = typer.Option(
138
+ None,
139
+ "--worker-provider",
140
+ "-w",
141
+ help="Name of the worker provider",
142
+ ),
143
+ timeout: int = typer.Option(
144
+ 300, "--timeout", "-t", help="Timeout for the task execution."
145
+ ),
146
+ ):
147
+ """
148
+ Orders a local Daemon instance to start and execute a given task.
149
+ """
150
+ try:
151
+ artifacts = run_task(
152
+ task_hash=task_hash,
153
+ input_artifact_hash=artifact_hash,
154
+ daemon_address=daemon_address,
155
+ block_registry=block_registry,
156
+ artifact_registry=artifact_registry,
157
+ daemon_image=daemon_image,
158
+ timeout=timeout,
159
+ worker_provider=worker_provider,
160
+ )
161
+
162
+ if artifacts:
163
+ typer.echo(f"Task completed successfully!")
164
+ typer.echo(f"Output artifacts: {len(artifacts)}")
165
+
166
+ for artifact in artifacts:
167
+ typer.echo(f" - {artifact.hash}")
168
+
169
+ except Exception as e:
170
+ typer.echo(f"Error: {e}", err=True)
171
+ raise typer.Exit(code=1)
172
+
173
+
174
+ @daemon_cli.command("status")
175
+ def daemon_status(
176
+ daemon_image: str = typer.Option(
177
+ None,
178
+ "--daemon-image",
179
+ "-i",
180
+ help="Daemon Docker image to use",
181
+ ),
182
+ daemon_address: Optional[str] = typer.Option(
183
+ None,
184
+ "--daemon-address",
185
+ "-d",
186
+ help="Daemon gRPC address (default: QORUS_DAEMON_ADDRESS env var or localhost:50053)",
187
+ ),
188
+ block_registry: str = typer.Option(
189
+ None,
190
+ "--block-dir",
191
+ "-b",
192
+ help="Path to block registry directory",
193
+ ),
194
+ artifact_registry: str = typer.Option(
195
+ None,
196
+ "--artifact-dir",
197
+ "-a",
198
+ help="Path to artifact registry directory",
199
+ ),
200
+ ):
201
+ """
202
+ Check the status of the local daemon container.
203
+ """
204
+ try:
205
+ status = get_daemon_status(
206
+ daemon_image=daemon_image,
207
+ daemon_address=daemon_address,
208
+ block_registry=block_registry,
209
+ artifact_registry=artifact_registry,
210
+ )
211
+
212
+ if status:
213
+ typer.echo(f"status: {status}")
214
+
215
+ except Exception as e:
216
+ typer.echo(f"Error: {e}", err=True)
217
+ raise typer.Exit(code=1)
@@ -0,0 +1,22 @@
1
+ # Copyright 2026 Scaleway
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import typer
15
+
16
+ import qorus.core as core
17
+
18
+ log_cli = typer.Typer(
19
+ name="logs",
20
+ help="Manage workflow and task logs generation.",
21
+ no_args_is_help=True,
22
+ )