iqcc-cloud-client 0.14.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.
- iqcc_cloud_client-0.14.0/.gitignore +17 -0
- iqcc_cloud_client-0.14.0/LICENSE +27 -0
- iqcc_cloud_client-0.14.0/PKG-INFO +40 -0
- iqcc_cloud_client-0.14.0/README.md +3 -0
- iqcc_cloud_client-0.14.0/pyproject.toml +162 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/__init__.py +5 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/accounting.py +0 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/cli.py +148 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/computers.py +756 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/interfaces.py +56 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/qmm_cloud.py +114 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/runtime.py +41 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/state.py +368 -0
- iqcc_cloud_client-0.14.0/src/iqcc_cloud_client/tokens.py +85 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
__pycache__
|
|
2
|
+
.venv
|
|
3
|
+
.mypy_cache
|
|
4
|
+
simulator.tar
|
|
5
|
+
/deployment/certs*
|
|
6
|
+
dist
|
|
7
|
+
/deployment_qolab
|
|
8
|
+
/test/with_qbridge
|
|
9
|
+
*_qolab*
|
|
10
|
+
.ruff_cache
|
|
11
|
+
/test/demo
|
|
12
|
+
playground
|
|
13
|
+
/test/with_qbridge
|
|
14
|
+
/test/with_compiler
|
|
15
|
+
*.ipynb
|
|
16
|
+
*.pdf
|
|
17
|
+
iqcc-cloud-client/test
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, IQCC and contributors
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
7
|
+
provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
10
|
+
and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
13
|
+
conditions and the following disclaimer in the documentation and/or other materials provided with
|
|
14
|
+
the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to
|
|
17
|
+
endorse or promote products derived from this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
|
20
|
+
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
21
|
+
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
22
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
23
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
25
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
26
|
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
27
|
+
POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iqcc-cloud-client
|
|
3
|
+
Version: 0.14.0
|
|
4
|
+
Summary: Access to IQCC quantum cloud
|
|
5
|
+
Author-email: Nikola Sibalic <nikola@quantum-machines.co>
|
|
6
|
+
License: BSD3
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Education
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: arrow>=1.3.0
|
|
18
|
+
Requires-Dist: cryptography>=44.0.2
|
|
19
|
+
Requires-Dist: deepdiff>=8.6.1
|
|
20
|
+
Requires-Dist: h11>=0.16.0
|
|
21
|
+
Requires-Dist: h2>=4.3.0
|
|
22
|
+
Requires-Dist: httpx>=0.23.3
|
|
23
|
+
Requires-Dist: ipywidgets>=8.1.5
|
|
24
|
+
Requires-Dist: jsonschema>=4.24.0
|
|
25
|
+
Requires-Dist: plotext>=5.3.2
|
|
26
|
+
Requires-Dist: protobuf>=4.25.8
|
|
27
|
+
Requires-Dist: pydantic-extra-types[pendulum]>=2.10.3
|
|
28
|
+
Requires-Dist: pydantic>=2.9.1
|
|
29
|
+
Requires-Dist: pyjwt>=2.10.1
|
|
30
|
+
Requires-Dist: qiskit>=1.4.1
|
|
31
|
+
Requires-Dist: qm-qua>=1.2.4
|
|
32
|
+
Requires-Dist: rich[jupyter]>=13.8.0
|
|
33
|
+
Requires-Dist: toml>=0.10.2
|
|
34
|
+
Requires-Dist: typer>=0.15.1
|
|
35
|
+
Requires-Dist: urllib3>=2.6.3
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# IQCC Cloud client
|
|
39
|
+
|
|
40
|
+
Client for remote (cloud) acccess to IQCC quantum and classical resources.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "iqcc-cloud-client"
|
|
3
|
+
version = "0.14.0"
|
|
4
|
+
description = "Access to IQCC quantum cloud"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Nikola Sibalic", email = "nikola@quantum-machines.co"},
|
|
7
|
+
]
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"arrow>=1.3.0",
|
|
11
|
+
"cryptography>=44.0.2",
|
|
12
|
+
"deepdiff>=8.6.1",
|
|
13
|
+
"httpx>=0.23.3",
|
|
14
|
+
"ipywidgets>=8.1.5",
|
|
15
|
+
"plotext>=5.3.2",
|
|
16
|
+
"pydantic-extra-types[pendulum]>=2.10.3",
|
|
17
|
+
"pydantic>=2.9.1",
|
|
18
|
+
"pyjwt>=2.10.1",
|
|
19
|
+
"qiskit>=1.4.1",
|
|
20
|
+
"qm-qua>=1.2.4",
|
|
21
|
+
"rich[jupyter]>=13.8.0",
|
|
22
|
+
"toml>=0.10.2",
|
|
23
|
+
"typer>=0.15.1",
|
|
24
|
+
"jsonschema>=4.24.0",
|
|
25
|
+
"h11>=0.16.0", # avoid CVEs in dependencies
|
|
26
|
+
"protobuf>=4.25.8", # avoid CVEs in dependencies
|
|
27
|
+
"h2>=4.3.0", # avoid CVEs in dependencies
|
|
28
|
+
"urllib3>=2.6.3", # avoid CVEs in dependencies
|
|
29
|
+
]
|
|
30
|
+
license = {text = "BSD3"}
|
|
31
|
+
classifiers = [
|
|
32
|
+
"Programming Language :: Python",
|
|
33
|
+
"Programming Language :: Python :: 3",
|
|
34
|
+
"Intended Audience :: Science/Research",
|
|
35
|
+
"Intended Audience :: Education",
|
|
36
|
+
"License :: OSI Approved :: BSD License",
|
|
37
|
+
"Topic :: Scientific/Engineering",
|
|
38
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
39
|
+
"Development Status :: 4 - Beta",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.readme]
|
|
43
|
+
file = "README.md"
|
|
44
|
+
content-type = "text/markdown"
|
|
45
|
+
|
|
46
|
+
[build-system]
|
|
47
|
+
requires = ["hatchling"]
|
|
48
|
+
build-backend = "hatchling.build"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build]
|
|
51
|
+
exclude = [
|
|
52
|
+
"test",
|
|
53
|
+
"tests",
|
|
54
|
+
"*/test",
|
|
55
|
+
"*/tests"
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
[tool.hatch.build.targets.sdist]
|
|
59
|
+
include = [
|
|
60
|
+
"*.py",
|
|
61
|
+
"*.pickle"
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[tool.uv]
|
|
65
|
+
prerelease = "allow"
|
|
66
|
+
|
|
67
|
+
[tool.uv.workspace]
|
|
68
|
+
members = [
|
|
69
|
+
"test/config_creator",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[project.scripts]
|
|
73
|
+
iqcc-cloud = "iqcc_cloud_client.cli:app"
|
|
74
|
+
|
|
75
|
+
[tool.ruff]
|
|
76
|
+
# Exclude a variety of commonly ignored directories.
|
|
77
|
+
exclude = [
|
|
78
|
+
".bzr",
|
|
79
|
+
".direnv",
|
|
80
|
+
".eggs",
|
|
81
|
+
".git",
|
|
82
|
+
".git-rewrite",
|
|
83
|
+
".hg",
|
|
84
|
+
".ipynb_checkpoints",
|
|
85
|
+
".mypy_cache",
|
|
86
|
+
".nox",
|
|
87
|
+
".pants.d",
|
|
88
|
+
".pyenv",
|
|
89
|
+
".pytest_cache",
|
|
90
|
+
".pytype",
|
|
91
|
+
".ruff_cache",
|
|
92
|
+
".svn",
|
|
93
|
+
".tox",
|
|
94
|
+
".venv",
|
|
95
|
+
".vscode",
|
|
96
|
+
"__pypackages__",
|
|
97
|
+
"_build",
|
|
98
|
+
"buck-datatypeout",
|
|
99
|
+
"build",
|
|
100
|
+
"dist",
|
|
101
|
+
"node_modules",
|
|
102
|
+
"site-packages",
|
|
103
|
+
"venv",
|
|
104
|
+
"demo",
|
|
105
|
+
"test"
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
# Same as Black.
|
|
109
|
+
line-length = 80
|
|
110
|
+
indent-width = 4
|
|
111
|
+
|
|
112
|
+
target-version = "py311"
|
|
113
|
+
|
|
114
|
+
[tool.ruff.lint.pydocstyle]
|
|
115
|
+
convention = "google"
|
|
116
|
+
|
|
117
|
+
[tool.ruff.lint]
|
|
118
|
+
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
|
119
|
+
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
|
120
|
+
# McCabe complexity (`C901`) by default.
|
|
121
|
+
select = ["E4", "E7", "E9", "F"]
|
|
122
|
+
ignore = []
|
|
123
|
+
|
|
124
|
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
125
|
+
fixable = ["ALL"]
|
|
126
|
+
unfixable = []
|
|
127
|
+
|
|
128
|
+
# Allow unused variables when underscore-prefixed.
|
|
129
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
130
|
+
|
|
131
|
+
[tool.ruff.format]
|
|
132
|
+
# Like Black, use double quotes for strings.
|
|
133
|
+
quote-style = "double"
|
|
134
|
+
|
|
135
|
+
# Like Black, indent with spaces, rather than tabs.
|
|
136
|
+
indent-style = "space"
|
|
137
|
+
|
|
138
|
+
# Like Black, respect magic trailing commas.
|
|
139
|
+
skip-magic-trailing-comma = false
|
|
140
|
+
|
|
141
|
+
# Like Black, automatically detect the appropriate line ending.
|
|
142
|
+
line-ending = "auto"
|
|
143
|
+
|
|
144
|
+
# Enable auto-formatting of code examples in docstrings. Markdown,
|
|
145
|
+
# reStructuredText code/literal blocks and doctests are all supported.
|
|
146
|
+
#
|
|
147
|
+
# This is currently disabled by default, but it is planned for this
|
|
148
|
+
# to be opt-out in the future.
|
|
149
|
+
docstring-code-format = true
|
|
150
|
+
|
|
151
|
+
# Set the line length limit used when formatting code snippets in
|
|
152
|
+
# docstrings.
|
|
153
|
+
#
|
|
154
|
+
# This only has an effect when the `docstring-code-format` setting is
|
|
155
|
+
# enabled.
|
|
156
|
+
docstring-code-line-length = "dynamic"
|
|
157
|
+
|
|
158
|
+
[dependency-groups]
|
|
159
|
+
dev = [
|
|
160
|
+
"pyvisa>=1.15.0",
|
|
161
|
+
"pyvisa-py>=0.8.1",
|
|
162
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
import toml
|
|
3
|
+
import os
|
|
4
|
+
from typing_extensions import Annotated
|
|
5
|
+
import iqcc_cloud_client
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import jwt
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from cryptography.hazmat.primitives import serialization as crypto_serialization
|
|
10
|
+
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
11
|
+
from cryptography.hazmat.backends import (
|
|
12
|
+
default_backend as crypto_default_backend,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
app = typer.Typer()
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_config_file():
|
|
20
|
+
Path(os.path.join(os.path.expanduser("~"), ".config", "iqcc_cloud")).mkdir(
|
|
21
|
+
parents=True, exist_ok=True
|
|
22
|
+
)
|
|
23
|
+
config_file = os.path.join(
|
|
24
|
+
os.path.expanduser("~"), ".config", "iqcc_cloud", "config.toml"
|
|
25
|
+
)
|
|
26
|
+
Path(config_file).touch(exist_ok=True)
|
|
27
|
+
|
|
28
|
+
return config_file
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.command()
|
|
32
|
+
def setup(
|
|
33
|
+
IQCC_API_token: Annotated[
|
|
34
|
+
str, typer.Option(prompt="Paste your IQCC API token and press enter")
|
|
35
|
+
],
|
|
36
|
+
):
|
|
37
|
+
"""Sets up a token for usage of the IQCC for current user
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
token (str): API token provided by the IQCC
|
|
41
|
+
"""
|
|
42
|
+
with open(get_config_file(), "r") as f:
|
|
43
|
+
data = toml.load(f)
|
|
44
|
+
if data == "":
|
|
45
|
+
data = {}
|
|
46
|
+
with open(
|
|
47
|
+
get_config_file(),
|
|
48
|
+
"w",
|
|
49
|
+
) as f:
|
|
50
|
+
if "tokens" not in data.keys():
|
|
51
|
+
data["tokens"] = {}
|
|
52
|
+
try:
|
|
53
|
+
decoded_data = jwt.decode(
|
|
54
|
+
IQCC_API_token, options={"verify_signature": False}
|
|
55
|
+
)
|
|
56
|
+
for backend in decoded_data["qpu"].keys():
|
|
57
|
+
data["tokens"][backend] = IQCC_API_token
|
|
58
|
+
|
|
59
|
+
console.print(
|
|
60
|
+
f":thumbs_up: Token for user [bold blue]{decoded_data['user_id']}[/bold blue] access to [bold blue]{backend}[/bold blue] provided"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
except Exception as _:
|
|
64
|
+
console.print("[bold red]:red_circle: Invalid JWT token passed")
|
|
65
|
+
exit()
|
|
66
|
+
toml.dump(data, f)
|
|
67
|
+
|
|
68
|
+
console.print(
|
|
69
|
+
"[bold green]:white_check_mark: Your access token is setup successfully.[/bold green]\n:rocket: Now you can use IQCC client without explicitly specifying the token."
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@app.command()
|
|
74
|
+
def provider(
|
|
75
|
+
backend_name: Annotated[
|
|
76
|
+
str, typer.Option(prompt="Enter name of backend you provide")
|
|
77
|
+
],
|
|
78
|
+
):
|
|
79
|
+
"""Generates a public and private key for backend provider
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
backend_name (str): name of backend for which you want to generate provider token
|
|
83
|
+
"""
|
|
84
|
+
key = rsa.generate_private_key(
|
|
85
|
+
backend=crypto_default_backend(), public_exponent=65537, key_size=2048
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
private_key = key.private_bytes(
|
|
89
|
+
crypto_serialization.Encoding.PEM,
|
|
90
|
+
crypto_serialization.PrivateFormat.PKCS8,
|
|
91
|
+
crypto_serialization.NoEncryption(),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
public_key = key.public_key().public_bytes(
|
|
95
|
+
crypto_serialization.Encoding.PEM,
|
|
96
|
+
crypto_serialization.PublicFormat.PKCS1,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
with open(get_config_file(), "r") as f:
|
|
100
|
+
data = toml.load(f)
|
|
101
|
+
if data == "":
|
|
102
|
+
data = {}
|
|
103
|
+
if (
|
|
104
|
+
"provider_private_keys" in data.keys()
|
|
105
|
+
and backend_name in data["provider_private_keys"].keys()
|
|
106
|
+
):
|
|
107
|
+
if not typer.confirm(
|
|
108
|
+
f"""You already have key registered for backend {backend_name}\nAre you sure you want to overwrite it?"""
|
|
109
|
+
):
|
|
110
|
+
console.print(
|
|
111
|
+
"Aborting creation of new backend key, since there is existing one."
|
|
112
|
+
)
|
|
113
|
+
return
|
|
114
|
+
with open(
|
|
115
|
+
get_config_file(),
|
|
116
|
+
"w",
|
|
117
|
+
) as f:
|
|
118
|
+
if "provider_private_keys" not in data.keys():
|
|
119
|
+
data["provider_private_keys"] = {}
|
|
120
|
+
|
|
121
|
+
data["provider_private_keys"][backend_name] = private_key.decode(
|
|
122
|
+
"utf-8"
|
|
123
|
+
)
|
|
124
|
+
toml.dump(data, f)
|
|
125
|
+
console.line()
|
|
126
|
+
console.print(
|
|
127
|
+
f":thumbs_up: Provider private key for backend [bold blue]{backend_name}[/bold blue] generated. [bold green]Please share the following public key with cloud server provider.[/bold green]"
|
|
128
|
+
)
|
|
129
|
+
console.line()
|
|
130
|
+
console.rule(
|
|
131
|
+
f"[bold green]Public key for cloud server [/bold green][bold blue]{backend_name}[/bold blue]"
|
|
132
|
+
)
|
|
133
|
+
print(public_key.decode("utf-8"))
|
|
134
|
+
console.rule()
|
|
135
|
+
console.line()
|
|
136
|
+
console.print(
|
|
137
|
+
":rocket: Once the cloud server has this key set for your backend, you will be able to issue tokens to your users using iqcc_cloud.tokens functions"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@app.command()
|
|
142
|
+
def version():
|
|
143
|
+
"""Prints version information"""
|
|
144
|
+
print(f"iqcc-cloud-client version {iqcc_cloud_client.__version__}")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
if __name__ == "__main__":
|
|
148
|
+
app()
|