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.
@@ -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,3 @@
1
+ # IQCC Cloud client
2
+
3
+ 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
+ ]
@@ -0,0 +1,5 @@
1
+ from iqcc_cloud_client.computers import IQCC_Cloud
2
+ from iqcc_cloud_client.qmm_cloud import CloudQuantumMachinesManager
3
+
4
+ __version__ = "0.14.0"
5
+ __all__ = [IQCC_Cloud, CloudQuantumMachinesManager]
@@ -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()