From 40a5217f25bb505dee5316d96f94e764d01f3ec6 Mon Sep 17 00:00:00 2001 From: Kevin Tian Date: Thu, 21 Sep 2023 11:58:24 -0400 Subject: [PATCH] Only return channel strategy supported backends (#1095) * Q-CTRL Backend filters * add reno * fix unit tests --- qiskit_ibm_runtime/api/clients/runtime.py | 10 ++++++++-- qiskit_ibm_runtime/api/rest/runtime.py | 14 +++++++++++--- qiskit_ibm_runtime/qiskit_runtime_service.py | 2 +- ...l-strategy-backend-filter-a4fe5248d9aea9c1.yaml | 6 ++++++ test/unit/mock/fake_runtime_client.py | 5 ++++- 5 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/channel-strategy-backend-filter-a4fe5248d9aea9c1.yaml diff --git a/qiskit_ibm_runtime/api/clients/runtime.py b/qiskit_ibm_runtime/api/clients/runtime.py index 71058eac8..4b3fa51c4 100644 --- a/qiskit_ibm_runtime/api/clients/runtime.py +++ b/qiskit_ibm_runtime/api/clients/runtime.py @@ -345,13 +345,19 @@ def close_session(self, session_id: str) -> None: """ self._api.runtime_session(session_id=session_id).close() - def list_backends(self, hgp: Optional[str] = None) -> List[str]: + def list_backends( + self, hgp: Optional[str] = None, channel_strategy: Optional[str] = None + ) -> List[str]: """Return IBM backends available for this service instance. + Args: + hgp: Filter by hub/group/project. + channel_strategy: Filter by channel strategy. + Returns: IBM backends available for this service instance. """ - return self._api.backends(hgp=hgp)["devices"] + return self._api.backends(hgp=hgp, channel_strategy=channel_strategy)["devices"] def backend_configuration(self, backend_name: str) -> Dict[str, Any]: """Return the configuration of the IBM backend. diff --git a/qiskit_ibm_runtime/api/rest/runtime.py b/qiskit_ibm_runtime/api/rest/runtime.py index 86c97bb69..a21c7a3e9 100644 --- a/qiskit_ibm_runtime/api/rest/runtime.py +++ b/qiskit_ibm_runtime/api/rest/runtime.py @@ -271,17 +271,25 @@ def backend(self, backend_name: str) -> CloudBackend: return CloudBackend(self.session, backend_name) def backends( - self, hgp: Optional[str] = None, timeout: Optional[float] = None + self, + hgp: Optional[str] = None, + timeout: Optional[float] = None, + channel_strategy: Optional[str] = None, ) -> Dict[str, List[str]]: """Return a list of IBM backends. Args: + hgp: The service instance to use, only for ``ibm_quantum`` channel, in h/g/p format. timeout: Number of seconds to wait for the request. + channel_strategy: Error mitigation strategy. Returns: JSON response. """ url = self.get_url("backends") + params = {} if hgp: - return self.session.get(url, params={"provider": hgp}).json() - return self.session.get(url, timeout=timeout).json() + params["provider"] = hgp + if channel_strategy: + params["channel_strategy"] = channel_strategy + return self.session.get(url, params=params, timeout=timeout).json() diff --git a/qiskit_ibm_runtime/qiskit_runtime_service.py b/qiskit_ibm_runtime/qiskit_runtime_service.py index ba22c8c9f..a3d4bc146 100644 --- a/qiskit_ibm_runtime/qiskit_runtime_service.py +++ b/qiskit_ibm_runtime/qiskit_runtime_service.py @@ -315,7 +315,7 @@ def _discover_cloud_backends(self) -> Dict[str, "ibm_backend.IBMBackend"]: A dict of the remote backend instances, keyed by backend name. """ ret = OrderedDict() # type: ignore[var-annotated] - backends_list = self._api_client.list_backends() + backends_list = self._api_client.list_backends(channel_strategy=self._channel_strategy) for backend_name in backends_list: raw_config = self._api_client.backend_configuration(backend_name=backend_name) config = configuration_from_server_data( diff --git a/releasenotes/notes/channel-strategy-backend-filter-a4fe5248d9aea9c1.yaml b/releasenotes/notes/channel-strategy-backend-filter-a4fe5248d9aea9c1.yaml new file mode 100644 index 000000000..58c7cf712 --- /dev/null +++ b/releasenotes/notes/channel-strategy-backend-filter-a4fe5248d9aea9c1.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + If using a ``channel_strategy``, only backends that support that ``channel_strategy`` + will be accessible to the user. + diff --git a/test/unit/mock/fake_runtime_client.py b/test/unit/mock/fake_runtime_client.py index ab5daa13c..91e64252e 100644 --- a/test/unit/mock/fake_runtime_client.py +++ b/test/unit/mock/fake_runtime_client.py @@ -514,7 +514,10 @@ def _get_job(self, job_id: str, exclude_params: bool = None) -> Any: raise RequestsApiError("Job not found", status_code=404) return self._jobs[job_id] - def list_backends(self, hgp: Optional[str] = None) -> List[str]: + # pylint: disable=unused-argument + def list_backends( + self, hgp: Optional[str] = None, channel_strategy: Optional[str] = None + ) -> List[str]: """Return IBM backends available for this service instance.""" return [back.name for back in self._backends if back.has_access(hgp)]