From f6e315c671575e25ac4a3e424911928794c00d8f Mon Sep 17 00:00:00 2001 From: yao-cqc Date: Thu, 17 Oct 2024 15:09:32 +0100 Subject: [PATCH 1/4] Update docstrings in credential_storage.py --- docs/api.rst | 9 ++++-- .../quantinuum/backends/credential_storage.py | 29 ++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 60b00e08..edab795e 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -30,5 +30,10 @@ Consult the `notebooks None: """save user_name""" def save_tokens(self, id_token: str, refresh_token: str) -> None: + """Save ID token and refresh token""" self.save_id_token(id_token) self.save_refresh_token(refresh_token) @@ -75,6 +76,13 @@ def __init__( id_token_timedelt: timedelta = timedelta(minutes=55), refresh_token_timedelt: timedelta = timedelta(days=29), ) -> None: + """Construct a MemoryCredentialStorage instance. + + :param id_token_timedelt: The time duration for which the ID token is valid. + Defaults to 55 minutes. + :param refresh_token_timedelt: The time duration for which the refresh token is valid. + Defaults to 29 days. + """ super().__init__(id_token_timedelt, refresh_token_timedelt) self._user_name: Optional[str] = None self._password: Optional[str] = None @@ -141,13 +149,32 @@ def delete_credential(self) -> None: class QuantinuumConfigCredentialStorage(CredentialStorage): - """Store tokens in the default pytket configuration file.""" + """Store username and tokens in the default pytket configuration file. + + This storage option allows authentication status to persist beyond the current + session, and reducing the need to re-enter credentials when constructing new + backends. + + Example: + + >>> backend = QuantinuumBackend( + >>> device_name=machine, + >>> api_handler=QuantinuumAPI(token_store=QuantinuumConfigCredentialStorage()), + >>> ) + """ def __init__( self, id_token_timedelt: timedelta = timedelta(minutes=55), refresh_token_timedelt: timedelta = timedelta(days=29), ) -> None: + """Construct a QuantinuumConfigCredentialStorage instance. + + :param id_token_timedelt: The time duration for which the ID token is valid. + Defaults to 55 minutes. + :param refresh_token_timedelt: The time duration for which the refresh token is valid. + Defaults to 29 days. + """ super().__init__(id_token_timedelt, refresh_token_timedelt) def save_user_name(self, user_name: str) -> None: From 6dbc9800b42d3dbefde2e49b709096ad89b59095 Mon Sep 17 00:00:00 2001 From: yao-cqc Date: Thu, 17 Oct 2024 16:04:01 +0100 Subject: [PATCH 2/4] reformat --- .../extensions/quantinuum/backends/credential_storage.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pytket/extensions/quantinuum/backends/credential_storage.py b/pytket/extensions/quantinuum/backends/credential_storage.py index 3c32ef43..ffcb30cc 100644 --- a/pytket/extensions/quantinuum/backends/credential_storage.py +++ b/pytket/extensions/quantinuum/backends/credential_storage.py @@ -80,8 +80,8 @@ def __init__( :param id_token_timedelt: The time duration for which the ID token is valid. Defaults to 55 minutes. - :param refresh_token_timedelt: The time duration for which the refresh token is valid. - Defaults to 29 days. + :param refresh_token_timedelt: The time duration for which the refresh token + is valid. Defaults to 29 days. """ super().__init__(id_token_timedelt, refresh_token_timedelt) self._user_name: Optional[str] = None @@ -172,8 +172,8 @@ def __init__( :param id_token_timedelt: The time duration for which the ID token is valid. Defaults to 55 minutes. - :param refresh_token_timedelt: The time duration for which the refresh token is valid. - Defaults to 29 days. + :param refresh_token_timedelt: The time duration for which the refresh token + is valid. Defaults to 29 days. """ super().__init__(id_token_timedelt, refresh_token_timedelt) From c0b2d1114b74b520ff197e1e8d07995d344397d7 Mon Sep 17 00:00:00 2001 From: yao-cqc Date: Mon, 21 Oct 2024 12:29:18 +0100 Subject: [PATCH 3/4] Better doc for the base class --- docs/api.rst | 8 ++- .../quantinuum/backends/credential_storage.py | 58 ++++++++++++++----- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index edab795e..b21db0ff 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -30,10 +30,12 @@ Consult the `notebooks None: + """ + :param id_token_timedelt: The time duration for which the ID token is valid. + Defaults to 55 minutes. + :param refresh_token_timedelt: The time duration for which the refresh token + is valid. Defaults to 29 days. + """ self._id_timedelt = id_token_timedelt self._refresh_timedelt = refresh_token_timedelt @abstractmethod def save_refresh_token(self, refresh_token: str) -> None: - """save refresh token""" + """Save refresh token. + + :param refresh_token: refresh token. + """ @abstractmethod def save_id_token(self, id_token: str) -> None: - """save ID token""" + """Save ID token. + + :param id_token: ID token. + """ @abstractmethod def save_user_name(self, user_name: str) -> None: - """save user_name""" + """Save username. + + :param user_name: Quantinuum username. + """ def save_tokens(self, id_token: str, refresh_token: str) -> None: - """Save ID token and refresh token""" + """Save ID token and refresh token. + + :param id_token: ID token. + :param refresh_token: refresh token. + """ self.save_id_token(id_token) self.save_refresh_token(refresh_token) @abstractmethod def delete_credential(self) -> None: - """delete credential""" + """Delete credential.""" @property def id_token(self) -> Optional[str]: - """returns a ID token if valid""" + """Return the ID token if valid.""" @property def refresh_token(self) -> Optional[str]: - """returns a refresh token if valid""" + """Return the refresh token if valid.""" @property def user_name(self) -> Optional[str]: - """returns the user name""" + """Return the username if exists.""" class MemoryCredentialStorage(CredentialStorage): - """In memory credential storage. Intended use is only to store id tokens, - refresh tokens and user_name. Password storage is only included for debug - purposes.""" + """In-memory credential storage. + + This storage option allows credentials to be temporarily stored in memory during + the application's runtime. + """ def __init__( self, @@ -85,6 +116,7 @@ def __init__( """ super().__init__(id_token_timedelt, refresh_token_timedelt) self._user_name: Optional[str] = None + # Password storage is only included for debug purposes self._password: Optional[str] = None self._id_token: Optional[str] = None self._refresh_token: Optional[str] = None @@ -152,7 +184,7 @@ class QuantinuumConfigCredentialStorage(CredentialStorage): """Store username and tokens in the default pytket configuration file. This storage option allows authentication status to persist beyond the current - session, and reducing the need to re-enter credentials when constructing new + session, reducing the need to re-enter credentials when constructing new backends. Example: From 9474f8747efc3cc1f3710454968da3735cdfc9f1 Mon Sep 17 00:00:00 2001 From: yao-cqc Date: Mon, 21 Oct 2024 16:34:02 +0100 Subject: [PATCH 4/4] Expand example in index.rst --- docs/index.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index d539bc64..7b565b1d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -192,6 +192,8 @@ Following a successful login, the refresh token and the ID token, which are requ This means you won't need to re-enter your credentials until these tokens expire. By default, these tokens are only stored in memory and will be removed once the Python session ends or if you manually log out. For more persistent storage, consider using the ``QuantinuumConfigCredentialStorage``. This storage option saves your username and the authentication tokens to the ``pytket`` configuration file, ensuring they persist beyond the current session. +To enable this, pass ``QuantinuumConfigCredentialStorage`` as an argument to ``QuantinuumAPI``, which is then provided to ``QuantinuumBackend``. + :: from pytket.extensions.quantinuum.backends.api_wrappers import QuantinuumAPI @@ -202,6 +204,22 @@ For more persistent storage, consider using the ``QuantinuumConfigCredentialStor device_name=machine, api_handler=QuantinuumAPI(token_store=QuantinuumConfigCredentialStorage()), ) + backend.login() # username and tokens saved to the configuration file. + # A new QuantinuumAPI instance with QuantinuumConfigCredentialStorage + # will automatically load the credential from the configuration file. + backend2 = QuantinuumBackend( + device_name=machine, + api_handler=QuantinuumAPI(token_store=QuantinuumConfigCredentialStorage()), + ) + backend2.backend_info # No need to login again + +Class methods use in-memory credential storage by default, so you need to explicitly set the ``api_handler``: +:: + + QuantinuumBackend.available_devices( + api_handler=QuantinuumAPI(token_store=QuantinuumConfigCredentialStorage()) + ) + Partial Results Retrieval -------------------------