iqm-client 32.0.0__py3-none-any.whl → 33.0.0__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.
- iqm/cirq_iqm/devices/iqm_device_metadata.py +2 -1
- iqm/cirq_iqm/examples/demo_common.py +1 -1
- iqm/cirq_iqm/examples/demo_iqm_execution.py +3 -3
- iqm/cirq_iqm/iqm_sampler.py +47 -29
- iqm/cirq_iqm/serialize.py +1 -1
- iqm/cirq_iqm/transpiler.py +3 -1
- iqm/iqm_client/__init__.py +0 -2
- iqm/iqm_client/errors.py +6 -17
- iqm/iqm_client/iqm_client.py +199 -602
- iqm/iqm_client/models.py +20 -611
- iqm/iqm_client/transpile.py +11 -8
- iqm/iqm_client/validation.py +18 -9
- iqm/iqm_server_client/__init__.py +14 -0
- iqm/iqm_server_client/errors.py +6 -0
- iqm/iqm_server_client/iqm_server_client.py +755 -0
- iqm/iqm_server_client/models.py +179 -0
- iqm/iqm_server_client/py.typed +0 -0
- iqm/qiskit_iqm/__init__.py +8 -0
- iqm/qiskit_iqm/examples/bell_measure.py +2 -2
- iqm/qiskit_iqm/examples/transpile_example.py +9 -4
- iqm/qiskit_iqm/fake_backends/fake_adonis.py +2 -1
- iqm/qiskit_iqm/fake_backends/fake_aphrodite.py +2 -1
- iqm/qiskit_iqm/fake_backends/fake_apollo.py +2 -1
- iqm/qiskit_iqm/fake_backends/fake_deneb.py +2 -1
- iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py +8 -7
- iqm/qiskit_iqm/iqm_backend.py +3 -4
- iqm/qiskit_iqm/iqm_circuit_validation.py +8 -7
- iqm/qiskit_iqm/iqm_job.py +106 -88
- iqm/qiskit_iqm/iqm_move_layout.py +2 -1
- iqm/qiskit_iqm/iqm_naive_move_pass.py +115 -56
- iqm/qiskit_iqm/iqm_provider.py +49 -36
- iqm/qiskit_iqm/iqm_target.py +12 -8
- iqm/qiskit_iqm/iqm_transpilation.py +219 -26
- iqm/qiskit_iqm/qiskit_to_iqm.py +150 -41
- iqm/qiskit_iqm/transpiler_plugins.py +11 -8
- {iqm_client-32.0.0.dist-info → iqm_client-33.0.0.dist-info}/METADATA +4 -14
- iqm_client-33.0.0.dist-info/RECORD +63 -0
- iqm/iqm_client/api.py +0 -90
- iqm/iqm_client/authentication.py +0 -206
- iqm_client-32.0.0.dist-info/RECORD +0 -60
- {iqm_client-32.0.0.dist-info → iqm_client-33.0.0.dist-info}/AUTHORS.rst +0 -0
- {iqm_client-32.0.0.dist-info → iqm_client-33.0.0.dist-info}/LICENSE.txt +0 -0
- {iqm_client-32.0.0.dist-info → iqm_client-33.0.0.dist-info}/WHEEL +0 -0
- {iqm_client-32.0.0.dist-info → iqm_client-33.0.0.dist-info}/entry_points.txt +0 -0
- {iqm_client-32.0.0.dist-info → iqm_client-33.0.0.dist-info}/top_level.txt +0 -0
iqm/iqm_client/authentication.py
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
# Copyright 2024 IQM client developers
|
|
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
|
-
# http://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
|
-
"""This module contains user authentication related classes and functions required by IQMClient."""
|
|
15
|
-
|
|
16
|
-
from abc import ABC, abstractmethod
|
|
17
|
-
from base64 import b64decode
|
|
18
|
-
import json
|
|
19
|
-
import os
|
|
20
|
-
import time
|
|
21
|
-
from typing import Any
|
|
22
|
-
|
|
23
|
-
from iqm.iqm_client.errors import ClientAuthenticationError, ClientConfigurationError
|
|
24
|
-
|
|
25
|
-
REFRESH_MARGIN_SECONDS = 60
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class TokenManager:
|
|
29
|
-
"""TokenManager manages the access token required for user authentication.
|
|
30
|
-
|
|
31
|
-
Args:
|
|
32
|
-
token: Long-lived IQM token in plain text format
|
|
33
|
-
tokens_file: Path to a tokens file used for authentication
|
|
34
|
-
|
|
35
|
-
The parameters can also be read from the environment variables IQM_TOKEN or IQM_TOKENS_FILE.
|
|
36
|
-
Environment variables can not be mixed with initialisation arguments.
|
|
37
|
-
All parameters must come from the same source.
|
|
38
|
-
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
@staticmethod
|
|
42
|
-
def time_left_seconds(token: Any) -> int:
|
|
43
|
-
"""Check how much time is left until the token expires.
|
|
44
|
-
|
|
45
|
-
Returns:
|
|
46
|
-
Time left on token in seconds.
|
|
47
|
-
|
|
48
|
-
"""
|
|
49
|
-
if not token or not isinstance(token, str):
|
|
50
|
-
return 0
|
|
51
|
-
parts = token.split(".", 2)
|
|
52
|
-
if len(parts) != 3:
|
|
53
|
-
return 0
|
|
54
|
-
# Add padding to adjust body length to a multiple of 4 chars as required by base64 decoding
|
|
55
|
-
try:
|
|
56
|
-
body = parts[1] + ("=" * (-len(parts[1]) % 4))
|
|
57
|
-
exp_time = int(json.loads(b64decode(body)).get("exp", "0"))
|
|
58
|
-
return max(0, exp_time - int(time.time()))
|
|
59
|
-
except (UnicodeDecodeError, json.decoder.JSONDecodeError, ValueError, TypeError):
|
|
60
|
-
return 0
|
|
61
|
-
|
|
62
|
-
def __init__(self, token: str | None = None, tokens_file: str | None = None):
|
|
63
|
-
def _format_names(variable_names: list[str]) -> str:
|
|
64
|
-
"""Format a list of variable names"""
|
|
65
|
-
return ", ".join(f'"{name}"' for name in variable_names)
|
|
66
|
-
|
|
67
|
-
auth_parameters: dict[str, str] = {}
|
|
68
|
-
|
|
69
|
-
init_parameters = {"token": token, "tokens_file": tokens_file}
|
|
70
|
-
init_params_given = [key for key, value in init_parameters.items() if value]
|
|
71
|
-
|
|
72
|
-
env_variables = {"token": "IQM_TOKEN", "tokens_file": "IQM_TOKENS_FILE"}
|
|
73
|
-
env_vars_given = [name for name in env_variables.values() if os.environ.get(name)]
|
|
74
|
-
|
|
75
|
-
if init_params_given and env_vars_given:
|
|
76
|
-
raise ClientConfigurationError(
|
|
77
|
-
"Authentication parameters given both as initialisation args and as environment variables: "
|
|
78
|
-
+ f"initialisation args {_format_names(init_params_given)}, "
|
|
79
|
-
+ f"environment variables {_format_names(env_vars_given)}."
|
|
80
|
-
+ " Parameter sources must not be mixed."
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
if env_vars_given:
|
|
84
|
-
auth_parameters = {key: value for key, name in env_variables.items() if (value := os.environ.get(name))}
|
|
85
|
-
else:
|
|
86
|
-
auth_parameters = {key: str(value) for key, value in init_parameters.items() if value}
|
|
87
|
-
|
|
88
|
-
self._token_provider: TokenProviderInterface | None = None
|
|
89
|
-
self._access_token: str | None = None
|
|
90
|
-
|
|
91
|
-
if not auth_parameters:
|
|
92
|
-
self._token_provider = None
|
|
93
|
-
elif set(auth_parameters) == {"token"}:
|
|
94
|
-
# This is not necessarily a JWT token
|
|
95
|
-
self._token_provider = ExternalToken(auth_parameters["token"])
|
|
96
|
-
elif set(auth_parameters) == {"tokens_file"}:
|
|
97
|
-
self._token_provider = TokensFileReader(auth_parameters["tokens_file"])
|
|
98
|
-
else:
|
|
99
|
-
raise ClientConfigurationError(
|
|
100
|
-
f"Missing authentication parameters, neither token or tokens_file is available, {list(auth_parameters)}"
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
def get_bearer_token(self, retries: int = 1) -> str | None:
|
|
104
|
-
"""Returns a valid bearer token, or None if no user authentication has been configured.
|
|
105
|
-
|
|
106
|
-
Raises:
|
|
107
|
-
ClientAuthenticationError: getting the token failed
|
|
108
|
-
|
|
109
|
-
"""
|
|
110
|
-
if self._token_provider is None:
|
|
111
|
-
return None # Authentication is not used
|
|
112
|
-
|
|
113
|
-
# Use the existing access token if it is still valid
|
|
114
|
-
if TokenManager.time_left_seconds(self._access_token) > REFRESH_MARGIN_SECONDS:
|
|
115
|
-
return f"Bearer {self._access_token}"
|
|
116
|
-
|
|
117
|
-
# Otherwise, get a new access token from token provider
|
|
118
|
-
try:
|
|
119
|
-
self._access_token = self._token_provider.get_token()
|
|
120
|
-
return f"Bearer {self._access_token}"
|
|
121
|
-
except ClientAuthenticationError:
|
|
122
|
-
if retries < 1:
|
|
123
|
-
raise
|
|
124
|
-
|
|
125
|
-
# Try again
|
|
126
|
-
return self.get_bearer_token(retries - 1)
|
|
127
|
-
|
|
128
|
-
def close(self) -> bool:
|
|
129
|
-
"""Close the configured token provider.
|
|
130
|
-
|
|
131
|
-
Returns:
|
|
132
|
-
True if closing was successful
|
|
133
|
-
|
|
134
|
-
Raises:
|
|
135
|
-
ClientAuthenticationError: closing failed
|
|
136
|
-
|
|
137
|
-
"""
|
|
138
|
-
if self._token_provider is None:
|
|
139
|
-
return False
|
|
140
|
-
|
|
141
|
-
self._token_provider.close()
|
|
142
|
-
self._token_provider = None
|
|
143
|
-
return True
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
class TokenProviderInterface(ABC):
|
|
147
|
-
"""Interface to token provider"""
|
|
148
|
-
|
|
149
|
-
@abstractmethod
|
|
150
|
-
def get_token(self) -> str:
|
|
151
|
-
"""Returns a valid access token.
|
|
152
|
-
|
|
153
|
-
Raises:
|
|
154
|
-
ClientAuthenticationError: acquiring the token failed
|
|
155
|
-
|
|
156
|
-
"""
|
|
157
|
-
|
|
158
|
-
@abstractmethod
|
|
159
|
-
def close(self) -> None:
|
|
160
|
-
"""Closes authentication session.
|
|
161
|
-
|
|
162
|
-
Raises:
|
|
163
|
-
ClientAuthenticationError: closing the session failed
|
|
164
|
-
|
|
165
|
-
"""
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
class ExternalToken(TokenProviderInterface):
|
|
169
|
-
"""Holds an external token"""
|
|
170
|
-
|
|
171
|
-
def __init__(self, token: str):
|
|
172
|
-
self._token: str | None = token
|
|
173
|
-
|
|
174
|
-
def get_token(self) -> str:
|
|
175
|
-
if self._token is None:
|
|
176
|
-
raise ClientAuthenticationError("No external token available")
|
|
177
|
-
return self._token
|
|
178
|
-
|
|
179
|
-
def close(self) -> None:
|
|
180
|
-
self._token = None
|
|
181
|
-
raise ClientAuthenticationError("Can not close externally managed auth session")
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
class TokensFileReader(TokenProviderInterface):
|
|
185
|
-
"""Reads token from a file"""
|
|
186
|
-
|
|
187
|
-
def __init__(self, tokens_file: str):
|
|
188
|
-
self._path: str | None = tokens_file
|
|
189
|
-
|
|
190
|
-
def get_token(self) -> str:
|
|
191
|
-
try:
|
|
192
|
-
if self._path is None:
|
|
193
|
-
raise ClientAuthenticationError("No tokens file available")
|
|
194
|
-
with open(self._path, encoding="utf-8") as file:
|
|
195
|
-
raw_data = file.read()
|
|
196
|
-
json_data = json.loads(raw_data)
|
|
197
|
-
token = json_data.get("access_token")
|
|
198
|
-
if TokenManager.time_left_seconds(token) <= 0:
|
|
199
|
-
raise ClientAuthenticationError("Access token in file has expired or is not valid")
|
|
200
|
-
except (FileNotFoundError, IsADirectoryError, json.decoder.JSONDecodeError) as e:
|
|
201
|
-
raise ClientAuthenticationError(rf"Failed to read access token from file '{self._path}': {e}") from e
|
|
202
|
-
return token
|
|
203
|
-
|
|
204
|
-
def close(self) -> None:
|
|
205
|
-
self._path = None
|
|
206
|
-
raise ClientAuthenticationError("Can not close externally managed auth session")
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
iqm/cirq_iqm/__init__.py,sha256=1zTyxtF39OD11D00ZujgqciJ_9GBDYe-PVBLqZp4NaA,831
|
|
2
|
-
iqm/cirq_iqm/extended_qasm_parser.py,sha256=csDzfHLhy_9maGbappLbnFo2NHQjQeyd-1F8P380Mbk,1917
|
|
3
|
-
iqm/cirq_iqm/iqm_gates.py,sha256=xnZex5ZfNOk_WSsFjVCRybc14FlGNbmwOs3mIfOE_F8,2488
|
|
4
|
-
iqm/cirq_iqm/iqm_sampler.py,sha256=LSR-2Wa1rGNUtkH8BNZLBVlAoEOwmTy2gziI5Zm6wl8,11454
|
|
5
|
-
iqm/cirq_iqm/optimizers.py,sha256=Jcb6W7-M9wYa5mZztq33jQpWuIzD5ulE16ZperIc-wU,8566
|
|
6
|
-
iqm/cirq_iqm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
iqm/cirq_iqm/serialize.py,sha256=UwW9plc_qHwxa0DOVB8nSEx7wmzSZ4NgtUTlm77joYc,8516
|
|
8
|
-
iqm/cirq_iqm/transpiler.py,sha256=c3-KE4c-4WenbdOcBMnCS30Ynm4Wt35i-bl4iG8pKAs,2112
|
|
9
|
-
iqm/cirq_iqm/devices/__init__.py,sha256=WxbvNAqmeoV4mNy9M9IpjwmyNDpAP7ec1XFdjN7w_YA,840
|
|
10
|
-
iqm/cirq_iqm/devices/adonis.py,sha256=ZWaA4_OfO6fBcrLYHONTjtW8aSlVq2nwy9IiW529gQw,1390
|
|
11
|
-
iqm/cirq_iqm/devices/aphrodite.py,sha256=0K8zRo6gVVadQo7LJfs6laUVLzS3fNkrXMrPlwieyJ8,4018
|
|
12
|
-
iqm/cirq_iqm/devices/apollo.py,sha256=_k7L45zyHZnpdZWMMXO6zci3XY3UEnBj2RmvxM6D7Mg,2238
|
|
13
|
-
iqm/cirq_iqm/devices/iqm_device.py,sha256=CyAP0kU9vfovNWvF4CVX8Wp6_QLxLN8fy9I2YZkHHwM,15425
|
|
14
|
-
iqm/cirq_iqm/devices/iqm_device_metadata.py,sha256=MklkPEXfIkp9aTgsvqV9_fAAU6QZgfnYF6eNrUH2bSk,7138
|
|
15
|
-
iqm/cirq_iqm/examples/demo_adonis.py,sha256=rPd8VYqccYijG6t92hfvKsk8RAaMGHOmm4JelYjt3rw,1728
|
|
16
|
-
iqm/cirq_iqm/examples/demo_apollo.py,sha256=vnDwcEXqEyew0cf4SDDQ2budP-giizSNJU3dgOw15H0,1751
|
|
17
|
-
iqm/cirq_iqm/examples/demo_common.py,sha256=l47o574xzIo8Ri5j-RGjY2NRNJN4IU6d6l0dcwDWRtM,8731
|
|
18
|
-
iqm/cirq_iqm/examples/demo_iqm_execution.py,sha256=I9hh1DfveBky-ngJlLmuxucIzlGtRPwrI7sMUSro8eM,2463
|
|
19
|
-
iqm/cirq_iqm/examples/usage.ipynb,sha256=Kyfyu_MwqzTavHVNjgrWJo1tZPeJwTw7ExcU0MFYNRk,34208
|
|
20
|
-
iqm/iqm_client/__init__.py,sha256=D-8W54EcQIxk_1JZo_86GYlR1YitHhPIiFwwLJ2IfGE,1411
|
|
21
|
-
iqm/iqm_client/api.py,sha256=_c6OVuv2dyzBF7J2XlK_qxisTSPyOiI4gYokZPsuaJY,3083
|
|
22
|
-
iqm/iqm_client/authentication.py,sha256=VtndzZ-nxuaU7q2G8bXYctGThcTuFZW0PqMNE9k4OCA,7447
|
|
23
|
-
iqm/iqm_client/errors.py,sha256=ty2P-sg80zlAoL3_kC3PlprgDUv4PI-KFhmmxaaapS0,1429
|
|
24
|
-
iqm/iqm_client/iqm_client.py,sha256=oX_wu7aIJCdwc-DZy8iF43n4t7mphtp7ha5Ec38kOkM,41160
|
|
25
|
-
iqm/iqm_client/models.py,sha256=0i0jYI8G_mJlNGCbH9W89OBS3JeqbcD2n_kUcM1AqIs,41942
|
|
26
|
-
iqm/iqm_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
-
iqm/iqm_client/transpile.py,sha256=2hDxQK8F4eMgpJC06XMIA8YbguFnRVNMlE1iKQNiTZk,37268
|
|
28
|
-
iqm/iqm_client/util.py,sha256=obzh1g6PNEXOj7k3gUkiylNUhyqutbWlxlEpfyyU_fk,1505
|
|
29
|
-
iqm/iqm_client/validation.py,sha256=GAe5GQAEXyplbmS_ioIRLR4fhCYKSranB0vE06qMfe8,12192
|
|
30
|
-
iqm/qiskit_iqm/__init__.py,sha256=Mv9V_r8ZcmGC8Ke5S8-7yLOx02vjZ1qiVx8mtbOpwnY,1420
|
|
31
|
-
iqm/qiskit_iqm/iqm_backend.py,sha256=HddizT6yHHq-MOG_U48n6ftE9AqmzaqbXYayEC1ljso,5548
|
|
32
|
-
iqm/qiskit_iqm/iqm_circuit.py,sha256=jaPo3zc5FC0vAIumh5d56fr44fDaJXXwcquBzQEy1Yg,1400
|
|
33
|
-
iqm/qiskit_iqm/iqm_circuit_validation.py,sha256=9pneZKs-KjBDGeDI6RHj6lB-ACqugbnYr1BqkJwLcXg,1737
|
|
34
|
-
iqm/qiskit_iqm/iqm_job.py,sha256=YLkAF4oqQ44dOLWbsqMiYCyj7pd3Rk6NIZ_TI1XtcQ8,11700
|
|
35
|
-
iqm/qiskit_iqm/iqm_move_layout.py,sha256=ECf1BcRmXKeClc7AL0lHedvJbqtwV5rEHcOOFR8shKU,10534
|
|
36
|
-
iqm/qiskit_iqm/iqm_naive_move_pass.py,sha256=jhTfvhrNDKt6NhhJg_3Y-5x6E1HRNzC_n4A27ZQTuvQ,12962
|
|
37
|
-
iqm/qiskit_iqm/iqm_provider.py,sha256=KHF27Qk12-_OA7_UZ8Rd25qDfFq4np2jv11_9f4tchQ,18599
|
|
38
|
-
iqm/qiskit_iqm/iqm_target.py,sha256=UyULiGMn6UJsyILBQiriso9KbhlmzP9TZItS2URaXWg,15832
|
|
39
|
-
iqm/qiskit_iqm/iqm_transpilation.py,sha256=6_6Mri01_HQBV_GTX94WSvIbu-pDMLMzEU6zVMEt6Gc,9153
|
|
40
|
-
iqm/qiskit_iqm/move_gate.py,sha256=UbrQSfrpVV3QKGJ93TelxEfZkl1wY4uWL8IH_QDpGUw,2840
|
|
41
|
-
iqm/qiskit_iqm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
|
-
iqm/qiskit_iqm/qiskit_to_iqm.py,sha256=3Sm1gLELFLCLf6QiATZSiPzLzkjvzUakhU2N6KoBXC8,14948
|
|
43
|
-
iqm/qiskit_iqm/transpiler_plugins.py,sha256=iuReGL42fCe5aOoH-KMUsb6t7Ok9qmIIj2S4yotJJ-U,8749
|
|
44
|
-
iqm/qiskit_iqm/examples/__init__.py,sha256=M4ElQHCo-WxtVXK39bF3QiFT3IGXPtZ1khqexHiTBEc,20
|
|
45
|
-
iqm/qiskit_iqm/examples/bell_measure.py,sha256=vlayliApHU70a2zTnN_gs6iKSSdaB4Jip-iQHJNYN5M,3064
|
|
46
|
-
iqm/qiskit_iqm/examples/transpile_example.py,sha256=cQmXXx3lqvmhgWYFK_U5HmHzMOKQqXUXPYfQhkyHH14,2135
|
|
47
|
-
iqm/qiskit_iqm/fake_backends/__init__.py,sha256=fkw2UHT-3aJbAKvR1WYUN7_4N5Gdwpx9bm6vlWj1tm0,874
|
|
48
|
-
iqm/qiskit_iqm/fake_backends/fake_adonis.py,sha256=vdWaVB6Hsa-SYgMWuYBtRQH5x5Y1qVHvdomWT2bh5QQ,2225
|
|
49
|
-
iqm/qiskit_iqm/fake_backends/fake_aphrodite.py,sha256=78KL0sONOtYKsWjPFGdc-uIxRUguncBbRQ9CP6bD_FQ,15510
|
|
50
|
-
iqm/qiskit_iqm/fake_backends/fake_apollo.py,sha256=6YSaKtUc6zZ4m3iAREbmxL4tRs_DW0ulmZy2Sq7sPUc,6600
|
|
51
|
-
iqm/qiskit_iqm/fake_backends/fake_deneb.py,sha256=_xpo_NJdu9t4ER8p5be-xTRmApkFY6kQw1UEGUPizk0,3193
|
|
52
|
-
iqm/qiskit_iqm/fake_backends/fake_garnet.py,sha256=GI0xafTCj1Um09qVuccO6GPOGBm6ygul_O40Wu220Ys,5555
|
|
53
|
-
iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py,sha256=wJtfsxjPYbDKmzaz5R4AuaXvvPHa21WyPtRgNctL9eY,16785
|
|
54
|
-
iqm_client-32.0.0.dist-info/AUTHORS.rst,sha256=qsxeK5A3-B_xK3hNbhFHEIkoHNpo7sdzYyRTs7Bdtm8,795
|
|
55
|
-
iqm_client-32.0.0.dist-info/LICENSE.txt,sha256=2DXrmQtVVUV9Fc9RBFJidMiTEaQlG2oAtlC9PMrEwTk,11333
|
|
56
|
-
iqm_client-32.0.0.dist-info/METADATA,sha256=TNcHTh2I8F7zKgtU-Lh1QfNWpmUH1WwhO1SY0pJCyDo,17887
|
|
57
|
-
iqm_client-32.0.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
58
|
-
iqm_client-32.0.0.dist-info/entry_points.txt,sha256=Kk2qfRwk8vbIJ7qCAvmaUogfRRn6t92_hBFhe6kqAE4,1317
|
|
59
|
-
iqm_client-32.0.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
|
|
60
|
-
iqm_client-32.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|