iqm-client 31.1.0__py3-none-any.whl → 31.3.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.
@@ -58,7 +58,7 @@ class IQMSampler(cirq.work.Sampler):
58
58
  calibration_set_id: UUID | None = None,
59
59
  run_sweep_timeout: int | None = None,
60
60
  compiler_options: CircuitCompilationOptions | None = None,
61
- **user_auth_args, # contains keyword args auth_server_url, username and password
61
+ **user_auth_args, # contains keyword args token or tokens_file
62
62
  ):
63
63
  self._client = IQMClient(url, **user_auth_args)
64
64
  dqa = self._client.get_dynamic_quantum_architecture(calibration_set_id)
@@ -21,7 +21,6 @@ import time
21
21
  from typing import Any
22
22
 
23
23
  from iqm.iqm_client.errors import ClientAuthenticationError, ClientConfigurationError
24
- import requests
25
24
 
26
25
  AUTH_CLIENT_ID = "iqm_client"
27
26
  AUTH_REALM = "cortex"
@@ -35,13 +34,10 @@ class TokenManager:
35
34
  Args:
36
35
  token: Long-lived IQM token in plain text format
37
36
  tokens_file: Path to a tokens file used for authentication
38
- auth_server_url: Base URL of the authentication server
39
- username: Username to log in to authentication server
40
- password: Password to log in to authentication server
41
37
 
42
- The parameters can also be read from the environment variables IQM_TOKEN, IQM_TOKENS_FILE,
43
- IQM_AUTH_SERVER, IQM_AUTH_USERNAME, IQM_AUTH_PASSWORD. Environment variables can not be
44
- mixed with initialisation arguments. All parameters must come from the same source.
38
+ The parameters can also be read from the environment variables IQM_TOKEN or IQM_TOKENS_FILE.
39
+ Environment variables can not be mixed with initialisation arguments.
40
+ All parameters must come from the same source.
45
41
 
46
42
  """
47
43
 
@@ -66,36 +62,17 @@ class TokenManager:
66
62
  except (UnicodeDecodeError, json.decoder.JSONDecodeError, ValueError, TypeError):
67
63
  return 0
68
64
 
69
- def __init__(
70
- self,
71
- token: str | None = None,
72
- tokens_file: str | None = None,
73
- auth_server_url: str | None = None,
74
- username: str | None = None,
75
- password: str | None = None,
76
- ):
65
+ def __init__(self, token: str | None = None, tokens_file: str | None = None):
77
66
  def _format_names(variable_names: list[str]) -> str:
78
67
  """Format a list of variable names"""
79
68
  return ", ".join(f'"{name}"' for name in variable_names)
80
69
 
81
70
  auth_parameters: dict[str, str] = {}
82
71
 
83
- init_parameters = {
84
- "token": token,
85
- "tokens_file": tokens_file,
86
- "auth_server_url": auth_server_url,
87
- "username": username,
88
- "password": password,
89
- }
72
+ init_parameters = {"token": token, "tokens_file": tokens_file}
90
73
  init_params_given = [key for key, value in init_parameters.items() if value]
91
74
 
92
- env_variables = {
93
- "token": "IQM_TOKEN",
94
- "tokens_file": "IQM_TOKENS_FILE",
95
- "auth_server_url": "IQM_AUTH_SERVER",
96
- "username": "IQM_AUTH_USERNAME",
97
- "password": "IQM_AUTH_PASSWORD",
98
- }
75
+ env_variables = {"token": "IQM_TOKEN", "tokens_file": "IQM_TOKENS_FILE"}
99
76
  env_vars_given = [name for name in env_variables.values() if os.environ.get(name)]
100
77
 
101
78
  if init_params_given and env_vars_given:
@@ -121,17 +98,9 @@ class TokenManager:
121
98
  self._token_provider = ExternalToken(auth_parameters["token"])
122
99
  elif set(auth_parameters) == {"tokens_file"}:
123
100
  self._token_provider = TokensFileReader(auth_parameters["tokens_file"])
124
- elif set(auth_parameters) == {"auth_server_url", "username", "password"}:
125
- self._token_provider = TokenClient(
126
- auth_parameters["auth_server_url"],
127
- AUTH_REALM,
128
- auth_parameters["username"],
129
- auth_parameters["password"],
130
- )
131
101
  else:
132
102
  raise ClientConfigurationError(
133
- f"""Invalid combination of authentication parameters specified: {list(auth_parameters)},
134
- Use either ['token'] or ['username', 'password'].""",
103
+ f"Missing authentication parameters, neither token or tokens_file is available, {list(auth_parameters)}"
135
104
  )
136
105
 
137
106
  def get_bearer_token(self, retries: int = 1) -> str | None:
@@ -238,78 +207,3 @@ class TokensFileReader(TokenProviderInterface):
238
207
  def close(self) -> None:
239
208
  self._path = None
240
209
  raise ClientAuthenticationError("Can not close externally managed auth session")
241
-
242
-
243
- class TokenClient(TokenProviderInterface):
244
- """Requests new token from an authentication server"""
245
-
246
- PASSWORD_GRANT_TYPE = "password"
247
- REFRESH_TOKEN_GRANT_TYPE = "refresh_token"
248
-
249
- def __init__(self, auth_server_url: str, realm: str, username: str, password: str):
250
- """Initialize the client"""
251
- self._token_url = f"{auth_server_url}/realms/{realm}/protocol/openid-connect/token"
252
- self._logout_url = f"{auth_server_url}/realms/{realm}/protocol/openid-connect/logout"
253
- self._username = username
254
- self._password = password
255
- self._refresh_token: str | None = None
256
-
257
- def _get_access_token_from_server(self, grant_type: str) -> str | None:
258
- """Get new access token from the server and update refresh token."""
259
- if grant_type == TokenClient.REFRESH_TOKEN_GRANT_TYPE:
260
- # Update tokens using existing refresh_token
261
- data = {
262
- "client_id": AUTH_CLIENT_ID,
263
- "grant_type": TokenClient.REFRESH_TOKEN_GRANT_TYPE,
264
- "refresh_token": str(self._refresh_token),
265
- }
266
- else:
267
- # There is no valid refresh token or refresh token has expired, start a new session
268
- data = {
269
- "client_id": AUTH_CLIENT_ID,
270
- "grant_type": TokenClient.PASSWORD_GRANT_TYPE,
271
- "username": self._username,
272
- "password": self._password,
273
- }
274
-
275
- # Request new tokens from the server
276
- access_token: str | None = None
277
- result = requests.post(self._token_url, data=data, timeout=AUTH_REQUESTS_TIMEOUT)
278
- if result.status_code == 200:
279
- tokens = result.json()
280
- self._refresh_token = tokens.get("refresh_token")
281
- if TokenManager.time_left_seconds(self._refresh_token) <= 0:
282
- self._refresh_token = None
283
- access_token = tokens.get("access_token")
284
- if TokenManager.time_left_seconds(access_token) <= 0:
285
- access_token = None
286
- return access_token
287
-
288
- def get_token(self) -> str:
289
- """Get new access token and refresh token from the server"""
290
- if not self._token_url:
291
- raise ClientConfigurationError("No auth server configured")
292
-
293
- access_token: str | None = None
294
- if TokenManager.time_left_seconds(self._refresh_token) > REFRESH_MARGIN_SECONDS:
295
- # There is a valid refresh token, try to update tokens using it
296
- access_token = self._get_access_token_from_server(TokenClient.REFRESH_TOKEN_GRANT_TYPE)
297
- if access_token is None:
298
- # Failed to get valid access token using refresh token, start a new session
299
- access_token = self._get_access_token_from_server(TokenClient.PASSWORD_GRANT_TYPE)
300
- if access_token is None:
301
- # Failed to get valid access token using username and password, raise an error
302
- raise ClientAuthenticationError("Getting access token from auth server failed")
303
- return str(access_token) # access token can not be None here
304
-
305
- def close(self) -> None:
306
- """Close authentication session"""
307
- if not self._refresh_token:
308
- raise ClientAuthenticationError("No auth session active")
309
-
310
- data = {"client_id": AUTH_CLIENT_ID, "refresh_token": self._refresh_token}
311
- self._refresh_token = None
312
-
313
- result = requests.post(self._logout_url, data=data, timeout=AUTH_REQUESTS_TIMEOUT)
314
- if result.status_code not in [200, 204]:
315
- raise ClientAuthenticationError(f"Logout failed, {result.text}")
@@ -94,39 +94,22 @@ class IQMClient:
94
94
  If ``token`` is given no other user authentication parameters should be given.
95
95
  tokens_file: Path to a tokens file used for authentication.
96
96
  If ``tokens_file`` is given no other user authentication parameters should be given.
97
- auth_server_url: Base URL of the authentication server.
98
- If ``auth_server_url`` is given also ``username`` and ``password`` must be given.
99
- username: Username to log in to authentication server.
100
- password: Password to log in to authentication server.
101
97
 
102
98
  Alternatively, the user authentication related keyword arguments can also be given in
103
- environment variables :envvar:`IQM_TOKEN`, :envvar:`IQM_TOKENS_FILE`, :envvar:`IQM_AUTH_SERVER`,
104
- :envvar:`IQM_AUTH_USERNAME` and :envvar:`IQM_AUTH_PASSWORD`. All parameters must be given either
105
- as keyword arguments or as environment variables. Same combination restrictions apply
106
- for values given as environment variables as for keyword arguments.
99
+ environment variables :envvar:`IQM_TOKEN`, :envvar:`IQM_TOKENS_FILE`.
100
+
101
+ All parameters must be given either as keyword arguments or as environment variables.
102
+ Same combination restrictions apply for values given as environment variables as for
103
+ keyword arguments.
107
104
 
108
105
  """
109
106
 
110
107
  def __init__(
111
- self,
112
- url: str,
113
- *,
114
- client_signature: str | None = None,
115
- token: str | None = None,
116
- tokens_file: str | None = None,
117
- auth_server_url: str | None = None,
118
- username: str | None = None,
119
- password: str | None = None,
108
+ self, url: str, *, client_signature: str | None = None, token: str | None = None, tokens_file: str | None = None
120
109
  ):
121
110
  if not url.startswith(("http:", "https:")):
122
111
  raise ClientConfigurationError(f"The URL schema has to be http or https. Incorrect schema in URL: {url}")
123
- self._token_manager = TokenManager(
124
- token,
125
- tokens_file,
126
- auth_server_url,
127
- username,
128
- password,
129
- )
112
+ self._token_manager = TokenManager(token, tokens_file)
130
113
  version_string = "iqm-client"
131
114
  self._signature = f"{platform.platform(terse=True)}"
132
115
  self._signature += f", python {platform.python_version()}"
@@ -366,7 +366,7 @@ class IQMProvider:
366
366
 
367
367
  """
368
368
 
369
- def __init__(self, url: str, **user_auth_args): # contains keyword args auth_server_url, username, password
369
+ def __init__(self, url: str, **user_auth_args): # contains keyword args token or tokens_file
370
370
  self.url = url
371
371
  self.user_auth_args = user_auth_args
372
372
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-client
3
- Version: 31.1.0
3
+ Version: 31.3.0
4
4
  Summary: Client library for accessing an IQM quantum computer
5
5
  Author-email: IQM Finland Oy <developers@meetiqm.com>
6
6
  License: Apache License
@@ -217,7 +217,7 @@ Description-Content-Type: text/x-rst
217
217
  License-File: LICENSE.txt
218
218
  License-File: AUTHORS.rst
219
219
  Requires-Dist: iqm-station-control-client <11,>=10
220
- Requires-Dist: iqm-exa-common <27,>=26
220
+ Requires-Dist: iqm-exa-common <28,>=27
221
221
  Requires-Dist: iqm-pulse <13,>=12
222
222
  Requires-Dist: numpy <3.0,>=1.26.4
223
223
  Requires-Dist: packaging ==24.1
@@ -225,7 +225,7 @@ Requires-Dist: pydantic <3.0,>=2.9.2
225
225
  Requires-Dist: requests ==2.32.3
226
226
  Provides-Extra: cirq
227
227
  Requires-Dist: iqm-station-control-client <11,>=10 ; extra == 'cirq'
228
- Requires-Dist: iqm-exa-common <27,>=26 ; extra == 'cirq'
228
+ Requires-Dist: iqm-exa-common <28,>=27 ; extra == 'cirq'
229
229
  Requires-Dist: iqm-pulse <13,>=12 ; extra == 'cirq'
230
230
  Requires-Dist: cirq-core[contrib] ~=1.2 ; extra == 'cirq'
231
231
  Requires-Dist: ply ==3.11 ; extra == 'cirq'
@@ -233,7 +233,7 @@ Requires-Dist: llvmlite >=0.44.0 ; extra == 'cirq'
233
233
  Requires-Dist: numba >=0.61.0 ; extra == 'cirq'
234
234
  Provides-Extra: cli
235
235
  Requires-Dist: iqm-station-control-client <11,>=10 ; extra == 'cli'
236
- Requires-Dist: iqm-exa-common <27,>=26 ; extra == 'cli'
236
+ Requires-Dist: iqm-exa-common <28,>=27 ; extra == 'cli'
237
237
  Requires-Dist: iqm-pulse <13,>=12 ; extra == 'cli'
238
238
  Requires-Dist: click <9,>=8.1.6 ; extra == 'cli'
239
239
  Requires-Dist: jsonschema >=4.6.0 ; extra == 'cli'
@@ -242,7 +242,7 @@ Requires-Dist: types-psutil ; extra == 'cli'
242
242
  Requires-Dist: python-daemon >=2.3.0 ; extra == 'cli'
243
243
  Provides-Extra: qiskit
244
244
  Requires-Dist: iqm-station-control-client <11,>=10 ; extra == 'qiskit'
245
- Requires-Dist: iqm-exa-common <27,>=26 ; extra == 'qiskit'
245
+ Requires-Dist: iqm-exa-common <28,>=27 ; extra == 'qiskit'
246
246
  Requires-Dist: iqm-pulse <13,>=12 ; extra == 'qiskit'
247
247
  Requires-Dist: qiskit <=1.4.2,>=1.0 ; extra == 'qiskit'
248
248
  Requires-Dist: qiskit-aer <0.18,>=0.13.1 ; extra == 'qiskit'
@@ -1,7 +1,7 @@
1
1
  iqm/cirq_iqm/__init__.py,sha256=1zTyxtF39OD11D00ZujgqciJ_9GBDYe-PVBLqZp4NaA,831
2
2
  iqm/cirq_iqm/extended_qasm_parser.py,sha256=csDzfHLhy_9maGbappLbnFo2NHQjQeyd-1F8P380Mbk,1917
3
3
  iqm/cirq_iqm/iqm_gates.py,sha256=xnZex5ZfNOk_WSsFjVCRybc14FlGNbmwOs3mIfOE_F8,2488
4
- iqm/cirq_iqm/iqm_sampler.py,sha256=uDlxd1cU7yKVYsj-wxfsUDkK9lDdHQzzN4mKonRFow8,11472
4
+ iqm/cirq_iqm/iqm_sampler.py,sha256=LSR-2Wa1rGNUtkH8BNZLBVlAoEOwmTy2gziI5Zm6wl8,11454
5
5
  iqm/cirq_iqm/optimizers.py,sha256=Jcb6W7-M9wYa5mZztq33jQpWuIzD5ulE16ZperIc-wU,8566
6
6
  iqm/cirq_iqm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  iqm/cirq_iqm/serialize.py,sha256=UwW9plc_qHwxa0DOVB8nSEx7wmzSZ4NgtUTlm77joYc,8516
@@ -19,9 +19,9 @@ iqm/cirq_iqm/examples/demo_iqm_execution.py,sha256=I9hh1DfveBky-ngJlLmuxucIzlGtR
19
19
  iqm/cirq_iqm/examples/usage.ipynb,sha256=Kyfyu_MwqzTavHVNjgrWJo1tZPeJwTw7ExcU0MFYNRk,34208
20
20
  iqm/iqm_client/__init__.py,sha256=D-8W54EcQIxk_1JZo_86GYlR1YitHhPIiFwwLJ2IfGE,1411
21
21
  iqm/iqm_client/api.py,sha256=_c6OVuv2dyzBF7J2XlK_qxisTSPyOiI4gYokZPsuaJY,3083
22
- iqm/iqm_client/authentication.py,sha256=kHFqPI6w3OAk9k5ioPxi-FrD2EP-vjn8Z_wZYccJVyE,12259
22
+ iqm/iqm_client/authentication.py,sha256=4V-rYUZKFMvMOVsroiKB61voHKX_6t7S847NDCdNbQE,7582
23
23
  iqm/iqm_client/errors.py,sha256=ty2P-sg80zlAoL3_kC3PlprgDUv4PI-KFhmmxaaapS0,1429
24
- iqm/iqm_client/iqm_client.py,sha256=LtfznCt9RPvYn45mcVnfIWT8vekoZ548iWwl5iS318U,41798
24
+ iqm/iqm_client/iqm_client.py,sha256=oX_wu7aIJCdwc-DZy8iF43n4t7mphtp7ha5Ec38kOkM,41160
25
25
  iqm/iqm_client/models.py,sha256=hvnJYLOiycaXluWQgsip9CAnyb5l8i4xFYHt2qqUg7A,41831
26
26
  iqm/iqm_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  iqm/iqm_client/transpile.py,sha256=2hDxQK8F4eMgpJC06XMIA8YbguFnRVNMlE1iKQNiTZk,37268
@@ -39,7 +39,7 @@ iqm/qiskit_iqm/iqm_circuit_validation.py,sha256=9pneZKs-KjBDGeDI6RHj6lB-ACqugbnY
39
39
  iqm/qiskit_iqm/iqm_job.py,sha256=YLkAF4oqQ44dOLWbsqMiYCyj7pd3Rk6NIZ_TI1XtcQ8,11700
40
40
  iqm/qiskit_iqm/iqm_move_layout.py,sha256=ECf1BcRmXKeClc7AL0lHedvJbqtwV5rEHcOOFR8shKU,10534
41
41
  iqm/qiskit_iqm/iqm_naive_move_pass.py,sha256=jhTfvhrNDKt6NhhJg_3Y-5x6E1HRNzC_n4A27ZQTuvQ,12962
42
- iqm/qiskit_iqm/iqm_provider.py,sha256=gpQ8RLdjc0iyp1nSowiu7VoUrH3wZ9AgeJCHFKnu150,18232
42
+ iqm/qiskit_iqm/iqm_provider.py,sha256=hpruU1jwz7sPod2vugQGf4TYtbmMvzCPgQCwv7q8Hlo,18217
43
43
  iqm/qiskit_iqm/iqm_target.py,sha256=UyULiGMn6UJsyILBQiriso9KbhlmzP9TZItS2URaXWg,15832
44
44
  iqm/qiskit_iqm/iqm_transpilation.py,sha256=6_6Mri01_HQBV_GTX94WSvIbu-pDMLMzEU6zVMEt6Gc,9153
45
45
  iqm/qiskit_iqm/move_gate.py,sha256=UbrQSfrpVV3QKGJ93TelxEfZkl1wY4uWL8IH_QDpGUw,2840
@@ -57,10 +57,10 @@ iqm/qiskit_iqm/fake_backends/fake_apollo.py,sha256=eT2vd3kQBi1rrvxCpePymBCfFK84d
57
57
  iqm/qiskit_iqm/fake_backends/fake_deneb.py,sha256=RzQXmLXmBARDiMKVxk5Aw9fVbc6IYlW0A5jibk9iYD0,3156
58
58
  iqm/qiskit_iqm/fake_backends/fake_garnet.py,sha256=GI0xafTCj1Um09qVuccO6GPOGBm6ygul_O40Wu220Ys,5555
59
59
  iqm/qiskit_iqm/fake_backends/iqm_fake_backend.py,sha256=wJtfsxjPYbDKmzaz5R4AuaXvvPHa21WyPtRgNctL9eY,16785
60
- iqm_client-31.1.0.dist-info/AUTHORS.rst,sha256=qsxeK5A3-B_xK3hNbhFHEIkoHNpo7sdzYyRTs7Bdtm8,795
61
- iqm_client-31.1.0.dist-info/LICENSE.txt,sha256=2DXrmQtVVUV9Fc9RBFJidMiTEaQlG2oAtlC9PMrEwTk,11333
62
- iqm_client-31.1.0.dist-info/METADATA,sha256=hEG2wANHjcQrrGk3v9sTahl1E6DguwJozpTok8e7Ts0,17887
63
- iqm_client-31.1.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
64
- iqm_client-31.1.0.dist-info/entry_points.txt,sha256=Kk2qfRwk8vbIJ7qCAvmaUogfRRn6t92_hBFhe6kqAE4,1317
65
- iqm_client-31.1.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
66
- iqm_client-31.1.0.dist-info/RECORD,,
60
+ iqm_client-31.3.0.dist-info/AUTHORS.rst,sha256=qsxeK5A3-B_xK3hNbhFHEIkoHNpo7sdzYyRTs7Bdtm8,795
61
+ iqm_client-31.3.0.dist-info/LICENSE.txt,sha256=2DXrmQtVVUV9Fc9RBFJidMiTEaQlG2oAtlC9PMrEwTk,11333
62
+ iqm_client-31.3.0.dist-info/METADATA,sha256=YEwLjAvqshg7n3NNk6-JARHOvH6Vrz1kDl2Xlaj87CQ,17887
63
+ iqm_client-31.3.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
64
+ iqm_client-31.3.0.dist-info/entry_points.txt,sha256=Kk2qfRwk8vbIJ7qCAvmaUogfRRn6t92_hBFhe6kqAE4,1317
65
+ iqm_client-31.3.0.dist-info/top_level.txt,sha256=NB4XRfyDS6_wG9gMsyX-9LTU7kWnTQxNvkbzIxGv3-c,4
66
+ iqm_client-31.3.0.dist-info/RECORD,,