Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose new session details #1119

Merged
merged 19 commits into from
Oct 10, 2023
11 changes: 11 additions & 0 deletions qiskit_ibm_runtime/api/clients/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,17 @@ def close_session(self, session_id: str) -> None:
"""
self._api.runtime_session(session_id=session_id).close()

def session_details(self, session_id: str) -> Dict[str, Any]:
"""Get session details.

Args:
session_id: Session ID.

Returns:
Session details.
"""
return self._api.runtime_session(session_id=session_id).details()

def list_backends(
self, hgp: Optional[str] = None, channel_strategy: Optional[str] = None
) -> List[str]:
Expand Down
57 changes: 57 additions & 0 deletions qiskit_ibm_runtime/api/rest/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Base REST adapter."""

from ..session import RetrySession


class RestAdapterBase:
"""Base class for REST adapters."""

URL_MAP = {} # type: ignore[var-annotated]
"""Mapping between the internal name of an endpoint and the actual URL."""

_HEADER_JSON_CONTENT = {"Content-Type": "application/json"}

def __init__(self, session: RetrySession, prefix_url: str = "") -> None:
"""RestAdapterBase constructor.

Args:
session: Session to be used in the adapter.
prefix_url: String to be prepend to all URLs.
"""
self.session = session
self.prefix_url = prefix_url

def get_url(self, identifier: str) -> str:
"""Return the resolved URL for the specified identifier.

Args:
identifier: Internal identifier of the endpoint.

Returns:
The resolved URL of the endpoint (relative to the session base URL).
"""
return "{}{}".format(self.prefix_url, self.URL_MAP[identifier])

def get_prefixed_url(self, prefix: str, identifier: str) -> str:
"""Return an adjusted URL for the specified identifier.

Args:
prefix: string to be prepended to the URL.
identifier: Internal identifier of the endpoint.

Returns:
The resolved facade URL of the endpoint.
"""
return "{}{}{}".format(prefix, self.prefix_url, self.URL_MAP[identifier])
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/api/rest/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

from qiskit_ibm_provider.api.rest.base import RestAdapterBase
from qiskit_ibm_provider.api.rest.program_job import ProgramJob
from qiskit_ibm_provider.api.rest.runtime_session import RuntimeSession
from qiskit_ibm_provider.utils import local_to_utc

from .runtime_session import RuntimeSession
from .program import Program
from ...utils import RuntimeEncoder
from .cloud_backend import CloudBackend
Expand Down
53 changes: 53 additions & 0 deletions qiskit_ibm_runtime/api/rest/runtime_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Runtime Session REST adapter."""

from typing import Dict, Any
from .base import RestAdapterBase
from ..session import RetrySession


class RuntimeSession(RestAdapterBase):
"""Rest adapter for session related endpoints."""

URL_MAP = {
"self": "",
"close": "/close",
}

def __init__(self, session: RetrySession, session_id: str, url_prefix: str = "") -> None:
"""Job constructor.

Args:
session: RetrySession to be used in the adapter.
session_id: Job ID of the first job in a runtime session.
url_prefix: Prefix to use in the URL.
"""
super().__init__(session, "{}/sessions/{}".format(url_prefix, session_id))

def close(self) -> None:
"""Close this session."""
url = self.get_url("close")
self.session.delete(url)

def details(self) -> Dict[str, Any]:
"""Return the details of this session."""
try:
if "cloud" in self.session.base_url:
return self.session.get(self.get_url("self")).json()
else:
# TODO: remove this once "v2" is removed from the url path
return self.session.get(self.get_prefixed_url("/v2", "self")).json()
# return None if API is not supported
except: # pylint: disable=bare-except
return None
kt474 marked this conversation as resolved.
Show resolved Hide resolved
34 changes: 33 additions & 1 deletion qiskit_ibm_runtime/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

"""Qiskit Runtime flexible session."""

from typing import Dict, Optional, Type, Union, Callable
from typing import Dict, Optional, Type, Union, Callable, Any
from types import TracebackType
from functools import wraps
from contextvars import ContextVar
Expand Down Expand Up @@ -193,6 +193,38 @@ def backend(self) -> Optional[str]:
"""
return self._backend

def status(self) -> Optional[str]:
"""Return current session status."""
# TODO implement this when API changes are done
kt474 marked this conversation as resolved.
Show resolved Hide resolved
pass

def details(self) -> Optional[Dict[str, Any]]:
"""Return session details."""
if self._session_id:
response = self._service._api_client.session_details(self._session_id)
if response:
return {
"id": response.get("id"),
"backend_name": response.get("backend_name") or response.get("backend"),
"interactive_timeout": response.get("interactive_ttl")
or response.get("interactiveSessionTTL"),
"max_time": response.get("max_ttl") or response.get("maxSessionTTL"),
"active_ttl": response.get("active_ttl") or response.get("activeTTL"),
"state": response.get("state"),
"accepting_jobs": response.get("accepting_jobs")
or response.get("acceptingJobs"),
"root_job": response.get("rootJob"),
"root_job_started": response.get("rootJobStarted"),
"last_job": response.get("lastJob"),
"last_job_started": response.get("lastJobStarted")
or response.get("last_job_started"),
"last_job_completed": response.get("lastJobCompleted")
or response.get("last_job_completed"),
"activated_at": response.get("activatedAt") or response.get("started_at"),
"closed_at": response.get("closedAt") or response.get("closed_at"),
}
kt474 marked this conversation as resolved.
Show resolved Hide resolved
return None

@property
def session_id(self) -> str:
"""Return the session ID.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
features:
- |
Added a new method, :meth:`~qiskit_ibm_runtime.Session.details` that returns information
about a session, including: maximum session time, active time remaining, the current state,
and whether or not the session is accepting jobs.