Source code for yc_lockbox._lockbox
import logging
-from typing import Type, Optional, Callable, Iterator
+from typing import Any, AsyncGenerator, Coroutine, Type, Optional, Callable, Iterator
from yc_lockbox._abc import AbstractYandexAuthClient, AbstractYandexLockboxClient, AbstractHTTPAdapter
-from yc_lockbox._adapters import HTTPAdapter
+from yc_lockbox._adapters import HTTPAdapter, AsyncHTTPAdapter
from yc_lockbox._auth import YandexAuthClient
from yc_lockbox._models import (
Secret,
@@ -728,26 +728,587 @@ Source code for yc_lockbox._lockbox
-# TODO: implement
+
+[docs]
class AsyncYandexLockboxClient(AbstractYandexLockboxClient):
- """The same as :class:`YandexLockboxClient` but async."""
+ """
+ Yandex Lockbox secrets vault client.
+ The same as :class:`YandexLockboxClient` but async.
+
+ :param credentials: Credentials for authenticate requests.
+ Allowed types: service account key, OAuth token, IAM token.
+ :param auth_client: Optional client implementation for authenticate requests.
+ Defaults to ``YandexAuthClient``.
+ :param adapter: HTTP adapter for communicate with Yandex Cloud API.
+ :param lockbox_base_url: Lockbox base URL without resource path.
+ :param payload_lockbox_base_url: Lockbox payload base URL without resource path.
+ :param auth_base_url: IAM base URL without resource path.
+
+ .. note::
+
+ All the values of the secrets are masked, i.e. looks like ``***********``.
+ To get the real value of the secret, you need to call the injected methods
+ :func:`reveal_text_value()` or :func:`reveal_binary_value()`.
+
+ Usage::
+
+ from yc_lockbox import AsyncYandexLockboxClient, Secret
+
+ lockbox = AsyncYandexLockboxClient("y0_AgAEXXXXXXXXXXXXXXXXXXXXXXXXX") # OAuth or IAM token
+
+ secret: Secret = await lockbox.get_secret("e6xxxxxxxxxxxxxxxx")
+ print(secret.name, secret.status, secret.description)
+
+ secret_versions = await secret.list_versions()
+ async for version in secret_versions:
+ print(version)
+ if version.id != secret.current_version.id:
+ await version.schedule_version_destruction()
+
+ payload = await secret.payload()
+
+ try:
+ value = payload["mykey"]
+ print(value.reveal_text_value())
+ except KeyError:
+ print("Invalid key!")
+
+ print(payload.get("foo")) # None if not exists without raising exception
+ entry = payload[0] # similar to payload.entries[0]
+
+ Authenticate via service account key::
+
+ import json
+
+ # generate json key for your SA
+ # yc iam key create --service-account-name my-sa --output key.json
+
+ with open("./key.json", "r") as infile:
+ credentials = json.load(infile)
+
+ lockbox = AsyncYandexLockboxClient(credentials)
+
+ """
+
+ enable_async = True
+
+ def __init__(
+ self,
+ credentials,
+ *,
+ auth_client: Optional[Type[AbstractYandexAuthClient]] = YandexAuthClient,
+ adapter: Optional[Type[AbstractHTTPAdapter]] = AsyncHTTPAdapter,
+ lockbox_base_url: str | None = None,
+ payload_lockbox_base_url: str | None = None,
+ ) -> None:
+ super().__init__(
+ lockbox_base_url=lockbox_base_url,
+ payload_lockbox_base_url=payload_lockbox_base_url,
+ )
+ self.auth: AbstractYandexAuthClient = auth_client(credentials)
+ self.adapter: AbstractHTTPAdapter = adapter
+
+ @property
+ def auth_headers(self) -> dict[str, str]:
+ """Returns headers for authenticate."""
+ return self.auth.get_auth_headers()
+
+ def _inject_client_to_items(self, items: list[T]) -> list[T]:
+ """Inject this client to each response model."""
+ return list(map(lambda item: item.inject_client(self), items))
+
+ async def _seekable_response(
+ self, func: Callable[..., BasePaginatedResponse], entrypoint: str, *args, **kwargs
+ ) -> AsyncGenerator[Any, T]:
+ """
+ Requests all data from the API using the generators, instead of a page-by-page response.
+ This method does not works with dict. Be careful.
+ Returns list of objects from model entrypoint.
+
+ :param func: Adapter func to get data from API.
+ :param entrypoint: Response attribute that contains list of useful data items.
+ :param args: Arguments for func. Will be passed when called inside.
+ :param kwargs: Keyword arguments for func. Similar to ``args``.
+ """
+
+ if kwargs.get("params") is None:
+ raise TypeError(
+ "This method works only with query string parameters. Check keyword arguments to resolve it."
+ )
+
+ next_token = "" # nosec B105
+
+ while next_token is not None:
+ # There could potentially be a problem if some request doesn't have a 'pageToken' in query string params.
+ # However, this is already a question for a non-consistent API, I think.
+ # An unlikely story, but worth keeping in mind.
+ kwargs["params"]["pageToken"] = next_token
+
+ response = await func(*args, **kwargs)
+ next_token = response.next_page_token # None or a new token from the API
+
+ if not hasattr(response, entrypoint):
+ raise AttributeError(f"Entrypoint {entrypoint} not exists in response model.")
+
+ for item in getattr(response, entrypoint):
+ if not hasattr(item, "inject_client"):
+ raise AttributeError(
+ f"Incorrect item. Method 'inject_client' is not exists in {item.__class__} {type(item)}"
+ )
+ item.inject_client(self)
+ yield item
+
+
+[docs]
+ async def activate_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Activates the specified secret.
+
+ :param secret_id: Secret indentifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:activate"
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+
+[docs]
+ async def add_secret_version(
+ self, secret_id: str, version: INewSecretVersion, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Adds new version based on a previous one.
+
+ :param secret_id: Secret indentifier.
+ :param version: A new version object.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:addVersion"
+ payload = version.model_dump_json(by_alias=True, exclude_none=True)
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ data=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+
+[docs]
+ async def create_secret(
+ self, secret: INewSecret, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Creates a secret in the specified folder.
+
+ :param secret: A new secret object.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets"
+ payload = secret.model_dump_json(by_alias=True, exclude_none=True)
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ data=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+
+[docs]
+ async def cancel_secret_version_destruction(
+ self, secret_id: str, version_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Cancels previously scheduled version destruction, if the version hasn't been destroyed yet.
+
+ :param secret_id: Secret indentifier.
+ :param version_id: Secret version id to cancel destruction.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:cancelVersionDestruction"
+ payload = {"versionId": version_id}
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ json=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+
+[docs]
+ async def deactivate_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Deactivate a secret.
+
+ :param secret_id: Secret indentifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:deactivate"
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
- def __init__(self, *args, **kwargs) -> None:
- raise NotImplementedError # pragma: no cover
+
+[docs]
+ async def delete_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Deletes the specified secret.
-# TODO: implement
-class YandexLockbox:
+ :param secret_id: Secret indentifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}"
+ response = await self.adapter.request(
+ "DELETE",
+ url,
+ headers=self.auth_headers,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+
+[docs]
+ async def get_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Secret | YandexCloudError]:
+ """
+ Get lockbox secret by ID.
+
+ :param secret_id: Secret identifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}"
+ response = await self.adapter.request(
+ "GET",
+ url,
+ headers=self.auth_headers,
+ response_model=Secret,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+
+[docs]
+ async def get_secret_payload(
+ self,
+ secret_id: str,
+ version_id: str | None = None,
+ raise_for_status: bool = True,
+ ) -> Coroutine[Any, Any, SecretPayload | YandexCloudError]:
+ """
+ Get lockbox secret payload by ID and optional version.
+
+ :param secret_id: Secret identifier.
+ :param version_id: Secret version. Optional.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.payload_lockbox_base_url}/secrets/{secret_id}/payload"
+ params = {"version_id": version_id} if version_id else None
+ return await self.adapter.request(
+ "GET",
+ url,
+ headers=self.auth_headers,
+ response_model=SecretPayload,
+ raise_for_status=raise_for_status,
+ params=params,
+ )
+
+
+
+[docs]
+ async def list_secrets(
+ self,
+ folder_id: str,
+ page_size: int = 100,
+ page_token: str | None = None,
+ raise_for_status: bool = True,
+ iterator: bool = False,
+ ) -> Coroutine[Any, Any, SecretsList | YandexCloudError] | AsyncGenerator[Any, Secret]:
+ """
+ Retrieves the list of secrets in the specified folder.
+
+ :param folder_id: ID of the folder to list secrets in.
+ :param page_size: The maximum number of results per page to return.
+ If the number of available results is larger than ``page_size``,
+ the service returns a ``next_page_token`` that can be used to get
+ the next page of results in subsequent list requests.
+ Default value: ``100``.
+ The maximum value is ``1000``.
+ :param page_token: Page token. To get the next page of results, set ``page_token``
+ to the ``next_page_token`` returned by a previous list request.
+ :param iterator: Returns all data as iterator (generator) instead paginated result.
+ """
+ args = (
+ "GET",
+ f"{self.lockbox_base_url}/secrets",
+ )
+ kwargs = {
+ "headers": self.auth_headers,
+ "params": {"folderId": folder_id, "pageSize": page_size, "pageToken": page_token},
+ "response_model": SecretsList,
+ "raise_for_status": raise_for_status,
+ }
+
+ if iterator:
+ return self._seekable_response(self.adapter.request, "secrets", *args, **kwargs)
+
+ response = await self.adapter.request(*args, **kwargs)
+ self._inject_client_to_items(response.secrets)
+ return response
+
+
+ # TODO: implement
+
+[docs]
+ async def list_secret_access_bindings(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+
+ # TODO: implement
+
+[docs]
+ async def list_secret_operations(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+
+
+[docs]
+ async def list_secret_versions(
+ self,
+ secret_id: str,
+ page_size: int = 100,
+ page_token: str | None = None,
+ raise_for_status: bool = True,
+ iterator: bool = False,
+ ) -> Coroutine[Any, Any, SecretVersionsList | YandexCloudError] | AsyncGenerator[Any, SecretVersion]:
+ """
+ Retrieves the list of versions of the specified secret.
+
+ :param secret_id: Secret identifier.
+ :param page_size: The maximum number of results per page to return.
+ If the number of available results is larger than ``page_size``,
+ the service returns a ``next_page_token`` that can be used to get
+ the next page of results in subsequent list requests.
+ Default value: ``100``.
+ The maximum value is ``1000``.
+ :param page_token: Page token. To get the next page of results, set ``page_token``
+ to the ``next_page_token`` returned by a previous list request.
+ :param iterator: Returns all data as iterator (generator) instead paginated result.
+ """
+ args = (
+ "GET",
+ f"{self.lockbox_base_url}/secrets/{secret_id}/versions",
+ )
+ kwargs = {
+ "headers": self.auth_headers,
+ "params": {"pageSize": page_size, "pageToken": page_token},
+ "response_model": SecretVersionsList,
+ "raise_for_status": raise_for_status,
+ }
+
+ if iterator:
+ print("IMA ITERATOR IMA ITERATOR IMA ITERATOR IMA ITERATOR")
+ return self._seekable_response(self.adapter.request, "versions", *args, **kwargs)
+
+ response = await self.adapter.request(*args, **kwargs)
+ self._inject_client_to_items(response.versions)
+ return response
+
+
+
+[docs]
+ async def schedule_secret_version_destruction(
+ self, secret_id: str, version_id: str, pending_period: int = 604800, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Schedules the specified version for destruction.
+ Scheduled destruction can be cancelled with the :func:`cancel_secret_version_destruction()` method.
+
+ :param secret_id: Secret indentifier.
+ :param version_id: ID of the version to be destroyed.
+ :param pending_period: Time interval in seconds between the version destruction request and actual destruction.
+ Default value: ``604800`` (i.e. 7 days).
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ if isinstance(pending_period, int):
+ if pending_period <= 0:
+ raise ValueError("The ``pending_period`` value must be greater than 0.")
+ # protobuf duration compat
+ # https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/duration.proto
+ pending_period = str(pending_period) + "s"
+ else:
+ raise ValueError("The ``pending_period`` value must be integer.")
+
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:scheduleVersionDestruction"
+ payload = {"versionId": version_id, "pendingPeriod": pending_period}
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ json=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+ # TODO: implement
+
+[docs]
+ async def set_secret_access_bindings(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+
+
+[docs]
+ async def update_secret(
+ self, secret_id: str, data: IUpdateSecret, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Updates the specified secret.
+
+ :param secret_id: Secret identifier.
+ :param data: A new data for the secret as object.
+ Important. Field mask that specifies which attributes of the secret are going to be updated.
+ A comma-separated names off ALL fields to be updated. Only the specified fields will be changed.
+ The others will be left untouched. If the field is specified in updateMask and no value for
+ that field was sent in the request, the field's value will be reset to the default.
+ The default value for most fields is null or 0.
+ If ``updateMask`` is not sent in the request, all fields values will be updated.
+ Fields specified in the request will be updated to provided values. The rest of the fields will be reset to the default.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}"
+ payload = data.model_dump_json(by_alias=True)
+ response = await self.adapter.request(
+ "PATCH",
+ url,
+ headers=self.auth_headers,
+ data=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+
+ # TODO: implement
+
+[docs]
+ async def update_secret_access_bindings(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+
+
+
+
+[docs]
+class YandexLockboxFacade: # pragma: no cover
"""
A facade for encapsulating the logic of synchronous and asynchronous client operations,
providing uniform methods.
"""
- def __init__(self) -> None:
- raise NotImplementedError # pragma: no cover
+ _client: AbstractYandexLockboxClient
+
+ def __init__(
+ self,
+ credentials,
+ *,
+ auth_client: Optional[Type[AbstractYandexAuthClient]] = YandexAuthClient,
+ lockbox_base_url: str | None = None,
+ payload_lockbox_base_url: str | None = None,
+ enable_async: bool = False,
+ ) -> None:
+ if enable_async:
+ self._client = AsyncYandexLockboxClient(
+ credentials,
+ auth_client=auth_client,
+ lockbox_base_url=lockbox_base_url,
+ payload_lockbox_base_url=payload_lockbox_base_url,
+ )
+ else:
+ self._client = YandexLockboxClient(
+ credentials,
+ auth_client=auth_client,
+ lockbox_base_url=lockbox_base_url,
+ payload_lockbox_base_url=payload_lockbox_base_url,
+ )
+
+ @property
+ def client(self) -> AbstractYandexLockboxClient:
+ """Returns initialized Lockbox client."""
+ return self._client
+
+ def __getattr__(self, name):
+ """Dynamically delegate method calls to the appropriate client."""
+
+ if name == "_client":
+ return self._client
+
+ if not hasattr(self._client, name):
+ raise AttributeError
+
+ return getattr(self._client, name)
+
-__all__ = ["AsyncYandexLockboxClient", "YandexLockboxClient", "YandexLockbox"]
+__all__ = ["AsyncYandexLockboxClient", "YandexLockboxClient", "YandexLockboxFacade"]
Source code for yc_lockbox._lockbox
Source code for yc_lockbox._models
import logging
-from typing import Any, Iterator, Union
+from typing import Any, AsyncGenerator, Iterator, Union
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, SecretStr, SecretBytes, computed_field
from yc_lockbox._constants import RpcError
from yc_lockbox._abc import AbstractYandexLockboxClient
-from yc_lockbox._types import T
+from yc_lockbox._types import T, SecretVersionsResponse
from yc_lockbox._exceptions import LockboxError
@@ -500,18 +500,32 @@ Source code for yc_lockbox._models
return self.client.delete_secret(self.id, **kwargs)
+ async def _async_refresh(self, **kwargs) -> "Secret":
+ data = await self.client.get_secret(self.id, **kwargs)
+ self._update_attributes(data)
+ return self
+
+ def _sync_refresh(self, **kwargs) -> "Secret":
+ data = self.client.get_secret(self.id, **kwargs)
+ self._update_attributes(data)
+ return self
+
+ def _update_attributes(self, data) -> None:
+ """Method for update model attributes after refresh."""
+ for attr, value in data.model_dump().items():
+ if value != getattr(self, attr, None):
+ setattr(self, attr, value)
+
[docs]
def refresh(self, **kwargs) -> "Secret":
"""Shortcut for refresh attributes for this secret."""
self._raise_when_empty_client()
- data = self.client.get_secret(self.id, **kwargs)
- for attr, value in data.model_dump().items():
- if value != getattr(self, attr):
- setattr(self, attr, value)
+ if hasattr(self.client, "enable_async") and self.client.enable_async:
+ return self._async_refresh(**kwargs)
- return data
+ return self._sync_refresh(**kwargs)
Source code for yc_lockbox._models
[docs]
def list_versions(
self, page_size: int = 100, page_token: str | None = None, iterator: bool = False, **kwargs
- ) -> Union["SecretVersionsList", Iterator["SecretVersion"], "YandexCloudError"]:
+ ) -> SecretVersionsResponse:
"""Shortcut for list all available versions of the current secret."""
self._raise_when_empty_client()
return self.client.list_secret_versions(
@@ -664,7 +678,7 @@ Source code for yc_lockbox._models
-
A
B
C
Y
- + diff --git a/docs/index.html b/docs/index.html index a355a27..ea79914 100644 --- a/docs/index.html +++ b/docs/index.html @@ -199,7 +199,7 @@Yandex Lockbox Python client documentation#
-Release v0.1.3
+Release v0.2.0
@@ -370,12 +370,54 @@Other operations with secret
+Async mode#
+The client supports asynchronous mode using the aiohttp library. The signature of the methods does not differ from the synchronous implementation.
+Just import async client:
+from yc_lockbox import AsyncYandexLockboxClient
+
+lockbox = AsyncYandexLockboxClient("oauth_or_iam_token")
+
+
+Alternative:
+from yc_lockbox import YandexLockboxFacade
+
+lockbox = YandexLockboxFacade("oauth_or_iam_token", enable_async=True).client
+
+
+Example usage:
+secret: Secret = await lockbox.get_secret("e6qxxxxxxxxxx")
+payload = await secret.payload()
+print(payload.entries) # list of SecretPayloadEntry objects
+
+# Direct access
+
+entry = payload["secret_entry_1"] # or payload.get("secret_entry_1")
+
+print(entry.text_value) # return MASKED value like ***********
+print(entry.reveal_text_value()) # similar to entry.text_value.get_secret_value()
+
+# Async iterators
+
+secret_versions = await secret.list_versions(iterator=True)
+
+async for version in secret_versions:
+ if version.id != secret.current_version.id:
+ await version.schedule_version_destruction()
+ await version.cancel_version_destruction()
+
+
+
from yc_lockbox import AsyncYandexLockboxClient
+
+lockbox = AsyncYandexLockboxClient("oauth_or_iam_token")
+
from yc_lockbox import YandexLockboxFacade
+
+lockbox = YandexLockboxFacade("oauth_or_iam_token", enable_async=True).client
+
secret: Secret = await lockbox.get_secret("e6qxxxxxxxxxx")
+payload = await secret.payload()
+print(payload.entries) # list of SecretPayloadEntry objects
+
+# Direct access
+
+entry = payload["secret_entry_1"] # or payload.get("secret_entry_1")
+
+print(entry.text_value) # return MASKED value like ***********
+print(entry.reveal_text_value()) # similar to entry.text_value.get_secret_value()
+
+# Async iterators
+
+secret_versions = await secret.list_versions(iterator=True)
+
+async for version in secret_versions:
+ if version.id != secret.current_version.id:
+ await version.schedule_version_destruction()
+ await version.cancel_version_destruction()
+
Modules#
- Client
-
+
YandexLockboxFacade
+YandexLockboxClient
+AsyncYandexLockboxClient
-
+
AsyncYandexLockboxClient.activate_secret()
+AsyncYandexLockboxClient.add_secret_version()
+AsyncYandexLockboxClient.auth_headers
+AsyncYandexLockboxClient.cancel_secret_version_destruction()
+AsyncYandexLockboxClient.create_secret()
+AsyncYandexLockboxClient.deactivate_secret()
+AsyncYandexLockboxClient.delete_secret()
+AsyncYandexLockboxClient.enable_async
+AsyncYandexLockboxClient.get_secret()
+AsyncYandexLockboxClient.get_secret_payload()
+AsyncYandexLockboxClient.list_secret_access_bindings()
+AsyncYandexLockboxClient.list_secret_operations()
+AsyncYandexLockboxClient.list_secret_versions()
+AsyncYandexLockboxClient.list_secrets()
+AsyncYandexLockboxClient.schedule_secret_version_destruction()
+AsyncYandexLockboxClient.set_secret_access_bindings()
+AsyncYandexLockboxClient.update_secret()
+AsyncYandexLockboxClient.update_secret_access_bindings()
+
YandexAuthClient
YandexAuthClient.adapter
YandexAuthClient.get_iam_token()
@@ -495,6 +558,7 @@
Indices and tablesOther operations with secret
+ - Async mode
- Modules
- Indices and tables
Indices and tables +
Abstracts
+
diff --git a/docs/pages/adapters.html b/docs/pages/adapters.html
index 047f04e..e419d5e 100644
--- a/docs/pages/adapters.html
+++ b/docs/pages/adapters.html
@@ -251,7 +251,7 @@ Adapters
-
+
diff --git a/docs/pages/clients.html b/docs/pages/clients.html
index 124a88b..cf4c51d 100644
--- a/docs/pages/clients.html
+++ b/docs/pages/clients.html
@@ -199,6 +199,20 @@
Client#
+
+-
+class yc_lockbox.YandexLockboxFacade(credentials, *, auth_client=<class 'yc_lockbox._auth.YandexAuthClient'>, lockbox_base_url=None, payload_lockbox_base_url=None, enable_async=False)[source]#
+Bases: object
+A facade for encapsulating the logic of synchronous and asynchronous client operations,
+providing uniform methods.
+
+-
+property client: AbstractYandexLockboxClient#
+Returns initialized Lockbox client.
+
+
+
+
-
class yc_lockbox.YandexLockboxClient(credentials, *, auth_client=<class 'yc_lockbox._auth.YandexAuthClient'>, adapter=<class 'yc_lockbox._adapters.HTTPAdapter'>, lockbox_base_url=None, payload_lockbox_base_url=None)[source]#
@@ -533,6 +547,352 @@ Client#
+
+-
+class yc_lockbox.AsyncYandexLockboxClient(credentials, *, auth_client=<class 'yc_lockbox._auth.YandexAuthClient'>, adapter=<class 'yc_lockbox._adapters.AsyncHTTPAdapter'>, lockbox_base_url=None, payload_lockbox_base_url=None)[source]#
+Bases: AbstractYandexLockboxClient
+Yandex Lockbox secrets vault client.
+The same as YandexLockboxClient
but async.
+
+- Parameters:
+
+credentials – Credentials for authenticate requests.
+Allowed types: service account key, OAuth token, IAM token.
+auth_client (Optional
[Type
[AbstractYandexAuthClient
]]) – Optional client implementation for authenticate requests.
+Defaults to YandexAuthClient
.
+adapter (Optional
[Type
[AbstractHTTPAdapter
]]) – HTTP adapter for communicate with Yandex Cloud API.
+lockbox_base_url (Optional
[str
]) – Lockbox base URL without resource path.
+payload_lockbox_base_url (Optional
[str
]) – Lockbox payload base URL without resource path.
+auth_base_url – IAM base URL without resource path.
+
+
+
+
+Note
+All the values of the secrets are masked, i.e. looks like ***********
.
+To get the real value of the secret, you need to call the injected methods
+reveal_text_value()
or reveal_binary_value()
.
+
+Usage:
+from yc_lockbox import AsyncYandexLockboxClient, Secret
+
+lockbox = AsyncYandexLockboxClient("y0_AgAEXXXXXXXXXXXXXXXXXXXXXXXXX") # OAuth or IAM token
+
+secret: Secret = await lockbox.get_secret("e6xxxxxxxxxxxxxxxx")
+print(secret.name, secret.status, secret.description)
+
+secret_versions = await secret.list_versions()
+async for version in secret_versions:
+ print(version)
+ if version.id != secret.current_version.id:
+ await version.schedule_version_destruction()
+
+payload = await secret.payload()
+
+try:
+ value = payload["mykey"]
+ print(value.reveal_text_value())
+except KeyError:
+ print("Invalid key!")
+
+print(payload.get("foo")) # None if not exists without raising exception
+entry = payload[0] # similar to payload.entries[0]
+
+
+Authenticate via service account key:
+import json
+
+# generate json key for your SA
+# yc iam key create --service-account-name my-sa --output key.json
+
+with open("./key.json", "r") as infile:
+ credentials = json.load(infile)
+
+lockbox = AsyncYandexLockboxClient(credentials)
+
+
+
+-
+async activate_secret(secret_id, raise_for_status=True)[source]#
+Activates the specified secret.
+
+- Parameters:
+
+secret_id (str
) – Secret indentifier.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+async add_secret_version(secret_id, version, raise_for_status=True)[source]#
+Adds new version based on a previous one.
+
+- Parameters:
+
+secret_id (str
) – Secret indentifier.
+version (INewSecretVersion
) – A new version object.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+property auth_headers: dict[str, str]#
+Returns headers for authenticate.
+
+
+
+-
+async cancel_secret_version_destruction(secret_id, version_id, raise_for_status=True)[source]#
+Cancels previously scheduled version destruction, if the version hasn’t been destroyed yet.
+
+- Parameters:
+
+secret_id (str
) – Secret indentifier.
+version_id (str
) – Secret version id to cancel destruction.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+async create_secret(secret, raise_for_status=True)[source]#
+Creates a secret in the specified folder.
+
+- Parameters:
+
+secret (INewSecret
) – A new secret object.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+async deactivate_secret(secret_id, raise_for_status=True)[source]#
+Deactivate a secret.
+
+- Parameters:
+
+secret_id (str
) – Secret indentifier.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+async delete_secret(secret_id, raise_for_status=True)[source]#
+Deletes the specified secret.
+
+- Parameters:
+
+secret_id (str
) – Secret indentifier.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+enable_async = True#
+
+
+
+-
+async get_secret(secret_id, raise_for_status=True)[source]#
+Get lockbox secret by ID.
+
+- Parameters:
+
+secret_id (str
) – Secret identifier.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Secret
| YandexCloudError
]
+
+
+
+
+
+-
+async get_secret_payload(secret_id, version_id=None, raise_for_status=True)[source]#
+Get lockbox secret payload by ID and optional version.
+
+- Parameters:
+
+secret_id (str
) – Secret identifier.
+version_id (Optional
[str
]) – Secret version. Optional.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, SecretPayload
| YandexCloudError
]
+
+
+
+
+
+-
+async list_secret_access_bindings(*args, **kwargs)[source]#
+Not ready yet.
+
+
+
+-
+async list_secret_operations(*args, **kwargs)[source]#
+Not ready yet.
+
+
+
+-
+async list_secret_versions(secret_id, page_size=100, page_token=None, raise_for_status=True, iterator=False)[source]#
+Retrieves the list of versions of the specified secret.
+
+- Parameters:
+
+secret_id (str
) – Secret identifier.
+page_size (int
) – The maximum number of results per page to return.
+If the number of available results is larger than page_size
,
+the service returns a next_page_token
that can be used to get
+the next page of results in subsequent list requests.
+Default value: 100
.
+The maximum value is 1000
.
+page_token (Optional
[str
]) – Page token. To get the next page of results, set page_token
+to the next_page_token
returned by a previous list request.
+iterator (bool
) – Returns all data as iterator (generator) instead paginated result.
+
+
+- Return type:
+Union
[Coroutine
[Any
, Any
, SecretVersionsList
| YandexCloudError
], AsyncGenerator
[Any
, SecretVersion
]]
+
+
+
+
+
+-
+async list_secrets(folder_id, page_size=100, page_token=None, raise_for_status=True, iterator=False)[source]#
+Retrieves the list of secrets in the specified folder.
+
+- Parameters:
+
+folder_id (str
) – ID of the folder to list secrets in.
+page_size (int
) – The maximum number of results per page to return.
+If the number of available results is larger than page_size
,
+the service returns a next_page_token
that can be used to get
+the next page of results in subsequent list requests.
+Default value: 100
.
+The maximum value is 1000
.
+page_token (Optional
[str
]) – Page token. To get the next page of results, set page_token
+to the next_page_token
returned by a previous list request.
+iterator (bool
) – Returns all data as iterator (generator) instead paginated result.
+
+
+- Return type:
+Union
[Coroutine
[Any
, Any
, SecretsList
| YandexCloudError
], AsyncGenerator
[Any
, Secret
]]
+
+
+
+
+
+-
+async schedule_secret_version_destruction(secret_id, version_id, pending_period=604800, raise_for_status=True)[source]#
+Schedules the specified version for destruction.
+Scheduled destruction can be cancelled with the cancel_secret_version_destruction()
method.
+
+- Parameters:
+
+secret_id (str
) – Secret indentifier.
+version_id (str
) – ID of the version to be destroyed.
+pending_period (int
) – Time interval in seconds between the version destruction request and actual destruction.
+Default value: 604800
(i.e. 7 days).
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+async set_secret_access_bindings(*args, **kwargs)[source]#
+Not ready yet.
+
+
+
+-
+async update_secret(secret_id, data, raise_for_status=True)[source]#
+Updates the specified secret.
+
+- Parameters:
+
+secret_id (str
) – Secret identifier.
+data (IUpdateSecret
) – A new data for the secret as object.
+Important. Field mask that specifies which attributes of the secret are going to be updated.
+A comma-separated names off ALL fields to be updated. Only the specified fields will be changed.
+The others will be left untouched. If the field is specified in updateMask and no value for
+that field was sent in the request, the field’s value will be reset to the default.
+The default value for most fields is null or 0.
+If updateMask
is not sent in the request, all fields values will be updated.
+Fields specified in the request will be updated to provided values. The rest of the fields will be reset to the default.
+raise_for_status (bool
) – If set to False
returns YandexCloudError
instead throw exception.
+Defaults to True
.
+
+
+- Return type:
+Coroutine
[Any
, Any
, Operation
| YandexCloudError
]
+
+
+
+
+
+-
+async update_secret_access_bindings(*args, **kwargs)[source]#
+Not ready yet.
+
+
+
+
-
class yc_lockbox._auth.YandexAuthClient(credentials, *, auth_base_url=None, **kwargs)[source]#
@@ -632,6 +992,10 @@ Client#
- Client
+AsyncYandexLockboxClient
+AsyncYandexLockboxClient.activate_secret()
+AsyncYandexLockboxClient.add_secret_version()
+AsyncYandexLockboxClient.auth_headers
+AsyncYandexLockboxClient.cancel_secret_version_destruction()
+AsyncYandexLockboxClient.create_secret()
+AsyncYandexLockboxClient.deactivate_secret()
+AsyncYandexLockboxClient.delete_secret()
+AsyncYandexLockboxClient.enable_async
+AsyncYandexLockboxClient.get_secret()
+AsyncYandexLockboxClient.get_secret_payload()
+AsyncYandexLockboxClient.list_secret_access_bindings()
+AsyncYandexLockboxClient.list_secret_operations()
+AsyncYandexLockboxClient.list_secret_versions()
+AsyncYandexLockboxClient.list_secrets()
+AsyncYandexLockboxClient.schedule_secret_version_destruction()
+AsyncYandexLockboxClient.set_secret_access_bindings()
+AsyncYandexLockboxClient.update_secret()
+AsyncYandexLockboxClient.update_secret_access_bindings()
+
+
YandexAuthClient
YandexAuthClient.adapter
YandexAuthClient.get_iam_token()
@@ -668,7 +1053,7 @@ Client#
-
+
diff --git a/docs/pages/exceptions.html b/docs/pages/exceptions.html
index fe8d6de..6e6ee71 100644
--- a/docs/pages/exceptions.html
+++ b/docs/pages/exceptions.html
@@ -251,7 +251,7 @@ Exceptions
+
diff --git a/docs/pages/models.html b/docs/pages/models.html
index 616a05f..fe6e3e3 100644
--- a/docs/pages/models.html
+++ b/docs/pages/models.html
@@ -363,7 +363,7 @@ Domain models
- Return type:
-Union
[SecretVersionsList
, Iterator
[SecretVersion
], YandexCloudError
]
+Union
[SecretVersionsList
, Iterator
[SecretVersion
], AsyncGenerator
[Any
, SecretVersion
], YandexCloudError
]
@@ -1125,7 +1125,7 @@ Common models
+
diff --git a/docs/search.html b/docs/search.html
index 56e5c1b..7f70737 100644
--- a/docs/search.html
+++ b/docs/search.html
@@ -236,7 +236,7 @@
-
+
diff --git a/docs/searchindex.js b/docs/searchindex.js
index 0a78a8e..ea7a417 100644
--- a/docs/searchindex.js
+++ b/docs/searchindex.js
@@ -1 +1 @@
-Search.setIndex({"docnames": ["index", "pages/abstracts", "pages/adapters", "pages/clients", "pages/exceptions", "pages/models"], "filenames": ["index.rst", "pages/abstracts.rst", "pages/adapters.rst", "pages/clients.rst", "pages/exceptions.rst", "pages/models.rst"], "titles": ["Yandex Lockbox Python client documentation", "Abstracts", "Adapters", "Client", "Exceptions", "Models & objects"], "terms": {"releas": 0, "v": 0, "0": [0, 3], "1": 0, "3": 0, "thi": [0, 3, 5], "librari": 0, "i": [0, 3, 5], "simpl": [0, 3], "work": [0, 3], "over": 0, "rest": [0, 3], "api": [0, 3], "simplifi": 0, "allow": [0, 3], "you": [0, 3], "them": 0, "oop": 0, "paradigm": 0, "support": 0, "10": 0, "11": 0, "12": 0, "depend": 0, "pydanticv2": 0, "crypthographi": 0, "pyjwt": 0, "request": [0, 3], "current": [0, 5], "follow": 0, "ar": [0, 3, 5], "list": [0, 3, 5], "access": 0, "bind": 0, "set": [0, 3], "updat": [0, 3, 5], "pip": 0, "yc": [0, 3], "also": [0, 5], "can": [0, 3], "sourc": [0, 3, 5], "git": 0, "clone": 0, "http": [0, 3], "github": 0, "com": 0, "akimrx": 0, "cd": 0, "make": [0, 3], "authent": [0, 3], "via": [0, 3], "your": [0, 3], "oauth": [0, 3], "token": [0, 3, 5], "yc_lockbox": [0, 3, 5], "import": [0, 3], "yandexlockboxcli": [0, 3], "y0_xxxxxxxxxxxx": 0, "iam": [0, 3], "If": [0, 3], "pass": [0, 3], "credenti": [0, 3], "need": [0, 3], "take": [0, 3], "care": [0, 3], "fresh": [0, 3], "yourself": [0, 3], "t1": 0, "xxxxxx": 0, "xxxxxxx": 0, "us": [0, 3, 5], "servic": [0, 3], "account": [0, 3], "kei": [0, 3, 5], "json": [0, 3], "open": [0, 3], "path": [0, 3], "r": [0, 3], "keyfil": 0, "read": 0, "inewsecret": [0, 3, 5], "inewsecretpayloadentri": [0, 5], "oauth_or_iam_token": 0, "create_secret_oper": 0, "create_secret": [0, 3], "folder_id": [0, 3, 5], "b1xxxxxxxxxxxxxx": 0, "name": [0, 3, 5], "my": [0, 3, 5], "version_payload_entri": [0, 5], "secret_entry_1": 0, "text_valu": [0, 5], "secret_entry_text_valu": 0, "secret_entry_2": 0, "binary_valu": [0, 5], "secret_entry_binary_valu": 0, "encod": 0, "done": [0, 5], "new_secret": 0, "resourc": [0, 3, 5], "print": [0, 3, 5], "id": [0, 3, 5], "deactiv": [0, 3, 5], "get_secret": [0, 3], "e6qxxxxxxxxxx": 0, "statu": [0, 3, 5], "payload": [0, 3, 5], "version_id": [0, 3, 5], "current_vers": [0, 5], "option": [0, 3, 5], "default": [0, 3, 5], "entri": [0, 3, 5], "secretpayloadentri": [0, 5], "object": [0, 3], "direct": 0, "return": [0, 3, 5], "mask": [0, 3, 5], "valu": [0, 3, 5], "like": [0, 3, 5], "reveal_text_valu": [0, 3, 5], "similar": [0, 3, 5], "get_secret_valu": 0, "inewsecretvers": [0, 3, 5], "e6qxxxxxxxxxxxx": 0, "add_vers": [0, 5], "descript": [0, 3, 5], "base_version_id": [0, 5], "payload_entri": [0, 5], "altern": 0, "add_secret_vers": [0, 3], "secret_id": [0, 3, 5], "list_secret": [0, 3], "b1xxxxxxxxxx": 0, "iter": [0, 3, 5], "true": [0, 3, 5], "activ": [0, 3, 5], "list_vers": [0, 5], "fals": [0, 3, 5], "pagin": [0, 3], "next_page_token": [0, 3, 5], "schedule_version_destruct": [0, 5], "cancel_version_destruct": [0, 5], "activate_secret": [0, 3], "auth_head": [0, 3], "cancel_secret_version_destruct": [0, 3], "deactivate_secret": [0, 3], "delete_secret": [0, 3], "get_secret_payload": [0, 3], "list_secret_access_bind": [0, 3], "list_secret_oper": [0, 3], "list_secret_vers": [0, 3], "schedule_secret_version_destruct": [0, 3], "set_secret_access_bind": [0, 3], "update_secret": [0, 3], "update_secret_access_bind": [0, 3], "yandexauthcli": [0, 3], "adapt": [0, 3], "get_iam_token": [0, 3], "model": 0, "domain": 0, "secretvers": [0, 3, 5], "secretpayload": [0, 3, 5], "upsert": 0, "iupdatesecret": [0, 3, 5], "common": 0, "yandexclouderror": [0, 3, 5], "iamtokenrespons": [0, 5], "except": [0, 3], "abstract": 0, "index": 0, "come": [1, 2, 4], "soon": [1, 2, 4], "class": 3, "auth_client": 3, "_auth": 3, "_adapt": 3, "httpadapt": 3, "lockbox_base_url": 3, "none": [3, 5], "payload_lockbox_base_url": 3, "base": 3, "abstractyandexlockboxcli": 3, "yandex": [3, 5], "lockbox": [3, 5], "secret": [3, 5], "vault": 3, "paramet": [3, 5], "type": [3, 5], "abstractyandexauthcli": 3, "implement": 3, "abstracthttpadapt": 3, "commun": 3, "cloud": [3, 5], "str": [3, 5], "url": 3, "without": 3, "auth_base_url": 3, "all": [3, 5], "e": 3, "look": 3, "To": 3, "get": [3, 5], "real": [3, 5], "call": [3, 5], "inject": 3, "method": [3, 5], "reveal_binary_valu": [3, 5], "usag": [3, 5], "from": [3, 5], "y0_agaexxxxxxxxxxxxxxxxxxxxxxxxx": 3, "e6xxxxxxxxxxxxxxxx": 3, "try": 3, "mykei": 3, "keyerror": 3, "invalid": 3, "foo": 3, "exist": [3, 5], "rais": 3, "gener": 3, "sa": 3, "creat": [3, 5], "output": 3, "infil": 3, "load": 3, "raise_for_statu": 3, "specifi": [3, 5], "indentifi": 3, "bool": [3, 5], "instead": 3, "throw": 3, "oper": [3, 5], "version": [3, 5], "add": [3, 5], "new": [3, 5], "previou": 3, "one": 3, "A": [3, 5], "properti": [3, 5], "dict": [3, 5], "header": 3, "cancel": [3, 5], "previous": 3, "schedul": [3, 5], "destruct": [3, 5], "hasn": 3, "t": [3, 5], "been": 3, "destroi": 3, "yet": 3, "folder": 3, "delet": [3, 5], "identifi": 3, "arg": 3, "kwarg": [3, 5], "Not": 3, "readi": 3, "page_s": [3, 5], "100": [3, 5], "page_token": [3, 5], "retriev": 3, "int": [3, 5], "The": [3, 5], "maximum": 3, "number": 3, "result": 3, "per": 3, "page": [3, 5], "avail": [3, 5], "larger": 3, "than": 3, "next": [3, 5], "subsequ": 3, "1000": 3, "data": [3, 5], "union": [3, 5], "secretversionslist": [3, 5], "secretslist": [3, 5], "pending_period": [3, 5], "604800": [3, 5], "time": 3, "interv": 3, "second": 3, "between": 3, "actual": 3, "7": 3, "dai": 3, "field": [3, 5], "which": 3, "attribut": [3, 5], "go": 3, "comma": [3, 5], "separ": [3, 5], "off": 3, "onli": 3, "chang": 3, "other": [3, 5], "left": 3, "untouch": 3, "updatemask": [3, 5], "wa": 3, "sent": 3, "": 3, "reset": 3, "most": 3, "null": 3, "provid": [3, 5], "an": [3, 5], "up": 3, "date": 3, "synchron": 3, "mode": 3, "backward": 3, "compat": 3, "cacheabl": 3, "memori": 3, "instanc": 3, "complet": 5, "inform": 5, "about": 5, "aggreg": 5, "have": 5, "command": 5, "manag": 5, "pydant": 5, "_model": 5, "root": 5, "repres": 5, "contain": 5, "manipul": 5, "basic": 5, "secret_payload": 5, "my_entri": 5, "show": 5, "old": 5, "new_data": 5, "update_mask": 5, "update_oper": 5, "refresh": 5, "created_at": 5, "datetim": 5, "deletion_protect": 5, "kms_key_id": 5, "label": 5, "requir": 5, "alia": 5, "createdat": 5, "currentvers": 5, "deletionprotect": 5, "folderid": 5, "kmskeyid": 5, "unknown": 5, "shortcut": 5, "destroy_at": 5, "payload_entry_kei": 5, "destroyat": 5, "payloadentrykei": 5, "secretid": 5, "descruct": 5, "versionid": 5, "ani": 5, "secretstr": 5, "secretbyt": 5, "binaryvalu": 5, "textvalu": 5, "reveal": 5, "binari": 5, "byte": 5, "text": 5, "when": 5, "point": 5, "interfac": 5, "design": 5, "insid": 5, "version_descript": 5, "versiondescript": 5, "versionpayloadentri": 5, "baseversionid": 5, "payloadentri": 5, "relat": 5, "created_bi": 5, "error": 5, "metadata": 5, "modified_at": 5, "respons": 5, "createdbi": 5, "modifiedat": 5, "possibl": 5, "otherwis": 5, "code": 5, "detail": 5, "messag": 5, "error_typ": 5, "rpcerror": 5, "expires_at": 5, "expiresat": 5, "iamtoken": 5}, "objects": {"yc_lockbox": [[3, 0, 1, "", "YandexLockboxClient"]], "yc_lockbox.YandexLockboxClient": [[3, 1, 1, "", "activate_secret"], [3, 1, 1, "", "add_secret_version"], [3, 2, 1, "", "auth_headers"], [3, 1, 1, "", "cancel_secret_version_destruction"], [3, 1, 1, "", "create_secret"], [3, 1, 1, "", "deactivate_secret"], [3, 1, 1, "", "delete_secret"], [3, 1, 1, "", "get_secret"], [3, 1, 1, "", "get_secret_payload"], [3, 1, 1, "", "list_secret_access_bindings"], [3, 1, 1, "", "list_secret_operations"], [3, 1, 1, "", "list_secret_versions"], [3, 1, 1, "", "list_secrets"], [3, 1, 1, "", "schedule_secret_version_destruction"], [3, 1, 1, "", "set_secret_access_bindings"], [3, 1, 1, "", "update_secret"], [3, 1, 1, "", "update_secret_access_bindings"]], "yc_lockbox._auth": [[3, 0, 1, "", "YandexAuthClient"]], "yc_lockbox._auth.YandexAuthClient": [[3, 2, 1, "", "adapter"], [3, 1, 1, "", "get_iam_token"]], "yc_lockbox._models": [[5, 3, 1, "", "INewSecret"], [5, 3, 1, "", "INewSecretPayloadEntry"], [5, 3, 1, "", "INewSecretVersion"], [5, 3, 1, "", "IUpdateSecret"], [5, 3, 1, "", "IamTokenResponse"], [5, 3, 1, "", "Operation"], [5, 3, 1, "", "Secret"], [5, 3, 1, "", "SecretPayload"], [5, 3, 1, "", "SecretPayloadEntry"], [5, 3, 1, "", "SecretVersion"], [5, 3, 1, "", "SecretVersionsList"], [5, 3, 1, "", "SecretsList"], [5, 3, 1, "", "YandexCloudError"]], "yc_lockbox._models.INewSecret": [[5, 4, 1, "", "deletion_protection"], [5, 4, 1, "", "description"], [5, 4, 1, "", "folder_id"], [5, 4, 1, "", "kms_key_id"], [5, 4, 1, "", "labels"], [5, 4, 1, "", "name"], [5, 4, 1, "", "version_description"], [5, 4, 1, "", "version_payload_entries"]], "yc_lockbox._models.INewSecretPayloadEntry": [[5, 4, 1, "", "binary_value"], [5, 4, 1, "", "key"], [5, 4, 1, "", "text_value"]], "yc_lockbox._models.INewSecretVersion": [[5, 4, 1, "", "base_version_id"], [5, 4, 1, "", "description"], [5, 4, 1, "", "payload_entries"]], "yc_lockbox._models.IUpdateSecret": [[5, 4, 1, "", "deletion_protection"], [5, 4, 1, "", "description"], [5, 4, 1, "", "labels"], [5, 4, 1, "", "name"], [5, 4, 1, "", "update_mask"]], "yc_lockbox._models.IamTokenResponse": [[5, 4, 1, "", "expires_at"], [5, 4, 1, "", "token"]], "yc_lockbox._models.Operation": [[5, 4, 1, "", "created_at"], [5, 4, 1, "", "created_by"], [5, 4, 1, "", "description"], [5, 4, 1, "", "done"], [5, 4, 1, "", "error"], [5, 4, 1, "", "id"], [5, 4, 1, "", "metadata"], [5, 4, 1, "", "modified_at"], [5, 2, 1, "", "resource"], [5, 4, 1, "", "response"]], "yc_lockbox._models.Secret": [[5, 1, 1, "", "activate"], [5, 1, 1, "", "add_version"], [5, 1, 1, "", "cancel_version_destruction"], [5, 4, 1, "", "created_at"], [5, 4, 1, "", "current_version"], [5, 1, 1, "", "deactivate"], [5, 1, 1, "", "delete"], [5, 4, 1, "", "deletion_protection"], [5, 4, 1, "", "description"], [5, 4, 1, "", "folder_id"], [5, 4, 1, "", "id"], [5, 4, 1, "", "kms_key_id"], [5, 4, 1, "", "labels"], [5, 1, 1, "", "list_versions"], [5, 4, 1, "", "name"], [5, 1, 1, "", "payload"], [5, 1, 1, "", "refresh"], [5, 1, 1, "", "schedule_version_destruction"], [5, 4, 1, "", "status"], [5, 1, 1, "", "update"]], "yc_lockbox._models.SecretPayload": [[5, 4, 1, "", "entries"], [5, 1, 1, "", "get"], [5, 4, 1, "", "version_id"]], "yc_lockbox._models.SecretPayloadEntry": [[5, 4, 1, "", "binary_value"], [5, 4, 1, "", "key"], [5, 1, 1, "", "reveal_binary_value"], [5, 1, 1, "", "reveal_text_value"], [5, 4, 1, "", "text_value"]], "yc_lockbox._models.SecretVersion": [[5, 1, 1, "", "cancel_version_destruction"], [5, 4, 1, "", "created_at"], [5, 4, 1, "", "description"], [5, 4, 1, "", "destroy_at"], [5, 4, 1, "", "id"], [5, 1, 1, "", "payload"], [5, 4, 1, "", "payload_entry_keys"], [5, 1, 1, "", "schedule_version_destruction"], [5, 4, 1, "", "secret_id"], [5, 4, 1, "", "status"]], "yc_lockbox._models.SecretVersionsList": [[5, 4, 1, "", "versions"]], "yc_lockbox._models.SecretsList": [[5, 4, 1, "", "secrets"]], "yc_lockbox._models.YandexCloudError": [[5, 4, 1, "", "code"], [5, 4, 1, "", "details"], [5, 2, 1, "", "error_type"], [5, 4, 1, "", "message"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:property", "3": "py:pydantic_model", "4": "py:pydantic_field"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "property", "Python property"], "3": ["py", "pydantic_model", "Python model"], "4": ["py", "pydantic_field", "Python field"]}, "titleterms": {"yandex": 0, "lockbox": 0, "python": 0, "client": [0, 3], "document": 0, "instal": 0, "quick": 0, "start": 0, "creat": 0, "new": 0, "secret": 0, "get": 0, "from": 0, "add": 0, "version": 0, "other": 0, "oper": 0, "modul": 0, "content": 0, "indic": 0, "tabl": 0, "abstract": 1, "adapt": 2, "except": 4, "model": 5, "object": 5, "domain": 5, "pagin": 5, "upsert": 5, "common": 5}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 60}, "alltitles": {"Yandex Lockbox Python client documentation": [[0, "yandex-lockbox-python-client-documentation"]], "Installation": [[0, "installation"]], "Quick start": [[0, "quick-start"]], "Create a new secret": [[0, "create-a-new-secret"]], "Get secret from Lockbox": [[0, "get-secret-from-lockbox"]], "Add new version of secret": [[0, "add-new-version-of-secret"]], "Other operations with secret": [[0, "other-operations-with-secret"]], "Modules": [[0, "modules"]], "Content:": [[0, null]], "Indices and tables": [[0, "indices-and-tables"]], "Abstracts": [[1, "abstracts"]], "Adapters": [[2, "adapters"]], "Client": [[3, "client"]], "Exceptions": [[4, "exceptions"]], "Models & objects": [[5, "models-objects"]], "Domain models": [[5, "domain-models"]], "Paginated models": [[5, "paginated-models"]], "Upsert models": [[5, "upsert-models"]], "Common models": [[5, "common-models"]]}, "indexentries": {"yandexauthclient (class in yc_lockbox._auth)": [[3, "yc_lockbox._auth.YandexAuthClient"]], "yandexlockboxclient (class in yc_lockbox)": [[3, "yc_lockbox.YandexLockboxClient"]], "activate_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.activate_secret"]], "adapter (yc_lockbox._auth.yandexauthclient property)": [[3, "yc_lockbox._auth.YandexAuthClient.adapter"]], "add_secret_version() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.add_secret_version"]], "auth_headers (yc_lockbox.yandexlockboxclient property)": [[3, "yc_lockbox.YandexLockboxClient.auth_headers"]], "cancel_secret_version_destruction() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.cancel_secret_version_destruction"]], "create_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.create_secret"]], "deactivate_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.deactivate_secret"]], "delete_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.delete_secret"]], "get_iam_token() (yc_lockbox._auth.yandexauthclient method)": [[3, "yc_lockbox._auth.YandexAuthClient.get_iam_token"]], "get_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.get_secret"]], "get_secret_payload() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.get_secret_payload"]], "list_secret_access_bindings() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secret_access_bindings"]], "list_secret_operations() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secret_operations"]], "list_secret_versions() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secret_versions"]], "list_secrets() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secrets"]], "schedule_secret_version_destruction() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.schedule_secret_version_destruction"]], "set_secret_access_bindings() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.set_secret_access_bindings"]], "update_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.update_secret"]], "update_secret_access_bindings() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.update_secret_access_bindings"]], "activate() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.activate"]], "add_version() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.add_version"]], "base_version_id (yc_lockbox._models.inewsecretversion attribute)": [[5, "yc_lockbox._models.INewSecretVersion.base_version_id"]], "binary_value (yc_lockbox._models.inewsecretpayloadentry attribute)": [[5, "yc_lockbox._models.INewSecretPayloadEntry.binary_value"]], "binary_value (yc_lockbox._models.secretpayloadentry attribute)": [[5, "yc_lockbox._models.SecretPayloadEntry.binary_value"]], "cancel_version_destruction() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.cancel_version_destruction"]], "cancel_version_destruction() (yc_lockbox._models.secretversion method)": [[5, "yc_lockbox._models.SecretVersion.cancel_version_destruction"]], "code (yc_lockbox._models.yandexclouderror attribute)": [[5, "yc_lockbox._models.YandexCloudError.code"]], "created_at (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.created_at"]], "created_at (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.created_at"]], "created_at (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.created_at"]], "created_by (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.created_by"]], "current_version (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.current_version"]], "deactivate() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.deactivate"]], "delete() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.delete"]], "deletion_protection (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.deletion_protection"]], "deletion_protection (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.deletion_protection"]], "deletion_protection (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.deletion_protection"]], "description (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.description"]], "description (yc_lockbox._models.inewsecretversion attribute)": [[5, "yc_lockbox._models.INewSecretVersion.description"]], "description (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.description"]], "description (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.description"]], "description (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.description"]], "description (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.description"]], "destroy_at (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.destroy_at"]], "details (yc_lockbox._models.yandexclouderror attribute)": [[5, "yc_lockbox._models.YandexCloudError.details"]], "done (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.done"]], "entries (yc_lockbox._models.secretpayload attribute)": [[5, "yc_lockbox._models.SecretPayload.entries"]], "error (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.error"]], "error_type (yc_lockbox._models.yandexclouderror property)": [[5, "yc_lockbox._models.YandexCloudError.error_type"]], "expires_at (yc_lockbox._models.iamtokenresponse attribute)": [[5, "yc_lockbox._models.IamTokenResponse.expires_at"]], "folder_id (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.folder_id"]], "folder_id (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.folder_id"]], "get() (yc_lockbox._models.secretpayload method)": [[5, "yc_lockbox._models.SecretPayload.get"]], "id (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.id"]], "id (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.id"]], "id (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.id"]], "key (yc_lockbox._models.inewsecretpayloadentry attribute)": [[5, "yc_lockbox._models.INewSecretPayloadEntry.key"]], "key (yc_lockbox._models.secretpayloadentry attribute)": [[5, "yc_lockbox._models.SecretPayloadEntry.key"]], "kms_key_id (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.kms_key_id"]], "kms_key_id (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.kms_key_id"]], "labels (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.labels"]], "labels (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.labels"]], "labels (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.labels"]], "list_versions() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.list_versions"]], "message (yc_lockbox._models.yandexclouderror attribute)": [[5, "yc_lockbox._models.YandexCloudError.message"]], "metadata (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.metadata"]], "modified_at (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.modified_at"]], "name (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.name"]], "name (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.name"]], "name (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.name"]], "payload() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.payload"]], "payload() (yc_lockbox._models.secretversion method)": [[5, "yc_lockbox._models.SecretVersion.payload"]], "payload_entries (yc_lockbox._models.inewsecretversion attribute)": [[5, "yc_lockbox._models.INewSecretVersion.payload_entries"]], "payload_entry_keys (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.payload_entry_keys"]], "refresh() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.refresh"]], "resource (yc_lockbox._models.operation property)": [[5, "yc_lockbox._models.Operation.resource"]], "response (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.response"]], "reveal_binary_value() (yc_lockbox._models.secretpayloadentry method)": [[5, "yc_lockbox._models.SecretPayloadEntry.reveal_binary_value"]], "reveal_text_value() (yc_lockbox._models.secretpayloadentry method)": [[5, "yc_lockbox._models.SecretPayloadEntry.reveal_text_value"]], "schedule_version_destruction() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.schedule_version_destruction"]], "schedule_version_destruction() (yc_lockbox._models.secretversion method)": [[5, "yc_lockbox._models.SecretVersion.schedule_version_destruction"]], "secret_id (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.secret_id"]], "secrets (yc_lockbox._models.secretslist attribute)": [[5, "yc_lockbox._models.SecretsList.secrets"]], "status (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.status"]], "status (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.status"]], "text_value (yc_lockbox._models.inewsecretpayloadentry attribute)": [[5, "yc_lockbox._models.INewSecretPayloadEntry.text_value"]], "text_value (yc_lockbox._models.secretpayloadentry attribute)": [[5, "yc_lockbox._models.SecretPayloadEntry.text_value"]], "token (yc_lockbox._models.iamtokenresponse attribute)": [[5, "yc_lockbox._models.IamTokenResponse.token"]], "update() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.update"]], "update_mask (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.update_mask"]], "version_description (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.version_description"]], "version_id (yc_lockbox._models.secretpayload attribute)": [[5, "yc_lockbox._models.SecretPayload.version_id"]], "version_payload_entries (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.version_payload_entries"]], "versions (yc_lockbox._models.secretversionslist attribute)": [[5, "yc_lockbox._models.SecretVersionsList.versions"]]}})
\ No newline at end of file
+Search.setIndex({"docnames": ["index", "pages/abstracts", "pages/adapters", "pages/clients", "pages/exceptions", "pages/models"], "filenames": ["index.rst", "pages/abstracts.rst", "pages/adapters.rst", "pages/clients.rst", "pages/exceptions.rst", "pages/models.rst"], "titles": ["Yandex Lockbox Python client documentation", "Abstracts", "Adapters", "Client", "Exceptions", "Models & objects"], "terms": {"releas": 0, "v": 0, "0": [0, 3], "2": 0, "thi": [0, 3, 5], "librari": 0, "i": [0, 3, 5], "simpl": [0, 3], "work": [0, 3], "over": 0, "rest": [0, 3], "api": [0, 3], "simplifi": 0, "allow": [0, 3], "you": [0, 3], "them": 0, "oop": 0, "paradigm": 0, "support": 0, "3": 0, "10": 0, "11": 0, "12": 0, "depend": 0, "pydanticv2": 0, "crypthographi": 0, "pyjwt": 0, "request": [0, 3], "current": [0, 5], "follow": 0, "ar": [0, 3, 5], "list": [0, 3, 5], "access": 0, "bind": 0, "set": [0, 3], "updat": [0, 3, 5], "pip": 0, "yc": [0, 3], "also": [0, 5], "can": [0, 3], "sourc": [0, 3, 5], "git": 0, "clone": 0, "http": [0, 3], "github": 0, "com": 0, "akimrx": 0, "cd": 0, "make": [0, 3], "authent": [0, 3], "via": [0, 3], "your": [0, 3], "oauth": [0, 3], "token": [0, 3, 5], "yc_lockbox": [0, 3, 5], "import": [0, 3], "yandexlockboxcli": [0, 3], "y0_xxxxxxxxxxxx": 0, "iam": [0, 3], "If": [0, 3], "pass": [0, 3], "credenti": [0, 3], "need": [0, 3], "take": [0, 3], "care": [0, 3], "fresh": [0, 3], "yourself": [0, 3], "t1": 0, "xxxxxx": 0, "xxxxxxx": 0, "us": [0, 3, 5], "servic": [0, 3], "account": [0, 3], "kei": [0, 3, 5], "json": [0, 3], "open": [0, 3], "path": [0, 3], "r": [0, 3], "keyfil": 0, "read": 0, "inewsecret": [0, 3, 5], "inewsecretpayloadentri": [0, 5], "oauth_or_iam_token": 0, "create_secret_oper": 0, "create_secret": [0, 3], "folder_id": [0, 3, 5], "b1xxxxxxxxxxxxxx": 0, "name": [0, 3, 5], "my": [0, 3, 5], "version_payload_entri": [0, 5], "secret_entry_1": 0, "text_valu": [0, 5], "secret_entry_text_valu": 0, "secret_entry_2": 0, "binary_valu": [0, 5], "secret_entry_binary_valu": 0, "encod": 0, "done": [0, 5], "new_secret": 0, "resourc": [0, 3, 5], "print": [0, 3, 5], "id": [0, 3, 5], "deactiv": [0, 3, 5], "get_secret": [0, 3], "e6qxxxxxxxxxx": 0, "statu": [0, 3, 5], "payload": [0, 3, 5], "version_id": [0, 3, 5], "current_vers": [0, 3, 5], "option": [0, 3, 5], "default": [0, 3, 5], "entri": [0, 3, 5], "secretpayloadentri": [0, 5], "object": [0, 3], "direct": 0, "return": [0, 3, 5], "mask": [0, 3, 5], "valu": [0, 3, 5], "like": [0, 3, 5], "reveal_text_valu": [0, 3, 5], "similar": [0, 3, 5], "get_secret_valu": 0, "inewsecretvers": [0, 3, 5], "e6qxxxxxxxxxxxx": 0, "add_vers": [0, 5], "descript": [0, 3, 5], "base_version_id": [0, 5], "payload_entri": [0, 5], "altern": 0, "add_secret_vers": [0, 3], "secret_id": [0, 3, 5], "list_secret": [0, 3], "b1xxxxxxxxxx": 0, "iter": [0, 3, 5], "true": [0, 3, 5], "activ": [0, 3, 5], "list_vers": [0, 3, 5], "fals": [0, 3, 5], "pagin": [0, 3], "next_page_token": [0, 3, 5], "schedule_version_destruct": [0, 3, 5], "cancel_version_destruct": [0, 5], "The": [0, 3, 5], "asynchron": [0, 3], "aiohttp": 0, "signatur": 0, "method": [0, 3, 5], "doe": 0, "differ": 0, "synchron": [0, 3], "implement": [0, 3], "just": 0, "asyncyandexlockboxcli": [0, 3], "yandexlockboxfacad": [0, 3], "enable_async": [0, 3], "exampl": 0, "usag": [0, 3, 5], "await": [0, 3], "secret_vers": [0, 3], "activate_secret": [0, 3], "auth_head": [0, 3], "cancel_secret_version_destruct": [0, 3], "deactivate_secret": [0, 3], "delete_secret": [0, 3], "get_secret_payload": [0, 3], "list_secret_access_bind": [0, 3], "list_secret_oper": [0, 3], "list_secret_vers": [0, 3], "schedule_secret_version_destruct": [0, 3], "set_secret_access_bind": [0, 3], "update_secret": [0, 3], "update_secret_access_bind": [0, 3], "yandexauthcli": [0, 3], "adapt": [0, 3], "get_iam_token": [0, 3], "model": 0, "domain": 0, "secretvers": [0, 3, 5], "secretpayload": [0, 3, 5], "upsert": 0, "iupdatesecret": [0, 3, 5], "common": 0, "yandexclouderror": [0, 3, 5], "iamtokenrespons": [0, 5], "except": [0, 3], "abstract": 0, "index": 0, "come": [1, 2, 4], "soon": [1, 2, 4], "class": 3, "auth_client": 3, "_auth": 3, "lockbox_base_url": 3, "none": [3, 5], "payload_lockbox_base_url": 3, "base": 3, "A": [3, 5], "facad": 3, "encapsul": 3, "logic": 3, "oper": [3, 5], "provid": [3, 5], "uniform": 3, "properti": [3, 5], "abstractyandexlockboxcli": 3, "initi": 3, "lockbox": [3, 5], "_adapt": 3, "httpadapt": 3, "yandex": [3, 5], "secret": [3, 5], "vault": 3, "paramet": [3, 5], "type": [3, 5], "abstractyandexauthcli": 3, "abstracthttpadapt": 3, "commun": 3, "cloud": [3, 5], "str": [3, 5], "url": 3, "without": 3, "auth_base_url": 3, "all": [3, 5], "e": 3, "look": 3, "To": 3, "get": [3, 5], "real": [3, 5], "call": [3, 5], "inject": 3, "reveal_binary_valu": [3, 5], "from": [3, 5], "y0_agaexxxxxxxxxxxxxxxxxxxxxxxxx": 3, "e6xxxxxxxxxxxxxxxx": 3, "try": 3, "mykei": 3, "keyerror": 3, "invalid": 3, "foo": 3, "exist": [3, 5], "rais": 3, "gener": 3, "sa": 3, "creat": [3, 5], "output": 3, "infil": 3, "load": 3, "raise_for_statu": 3, "specifi": [3, 5], "indentifi": 3, "bool": [3, 5], "instead": 3, "throw": 3, "version": [3, 5], "add": [3, 5], "new": [3, 5], "previou": 3, "one": 3, "dict": [3, 5], "header": 3, "cancel": [3, 5], "previous": 3, "schedul": [3, 5], "destruct": [3, 5], "hasn": 3, "t": [3, 5], "been": 3, "destroi": 3, "yet": 3, "folder": 3, "delet": [3, 5], "identifi": 3, "arg": 3, "kwarg": [3, 5], "Not": 3, "readi": 3, "page_s": [3, 5], "100": [3, 5], "page_token": [3, 5], "retriev": 3, "int": [3, 5], "maximum": 3, "number": 3, "result": 3, "per": 3, "page": [3, 5], "avail": [3, 5], "larger": 3, "than": 3, "next": [3, 5], "subsequ": 3, "1000": 3, "data": [3, 5], "union": [3, 5], "secretversionslist": [3, 5], "secretslist": [3, 5], "pending_period": [3, 5], "604800": [3, 5], "time": 3, "interv": 3, "second": 3, "between": 3, "actual": 3, "7": 3, "dai": 3, "field": [3, 5], "which": 3, "attribut": [3, 5], "go": 3, "comma": [3, 5], "separ": [3, 5], "off": 3, "onli": 3, "chang": 3, "other": [3, 5], "left": 3, "untouch": 3, "updatemask": [3, 5], "wa": 3, "sent": 3, "": 3, "reset": 3, "most": 3, "null": 3, "asynchttpadapt": 3, "same": 3, "async": 3, "coroutin": 3, "ani": [3, 5], "asyncgener": [3, 5], "an": [3, 5], "up": 3, "date": 3, "mode": 3, "backward": 3, "compat": 3, "cacheabl": 3, "memori": 3, "instanc": 3, "complet": 5, "inform": 5, "about": 5, "aggreg": 5, "have": 5, "command": 5, "manag": 5, "pydant": 5, "_model": 5, "root": 5, "repres": 5, "contain": 5, "manipul": 5, "basic": 5, "secret_payload": 5, "my_entri": 5, "show": 5, "old": 5, "new_data": 5, "update_mask": 5, "update_oper": 5, "refresh": 5, "created_at": 5, "datetim": 5, "deletion_protect": 5, "kms_key_id": 5, "label": 5, "requir": 5, "alia": 5, "createdat": 5, "currentvers": 5, "deletionprotect": 5, "folderid": 5, "kmskeyid": 5, "unknown": 5, "shortcut": 5, "destroy_at": 5, "payload_entry_kei": 5, "destroyat": 5, "payloadentrykei": 5, "secretid": 5, "descruct": 5, "versionid": 5, "secretstr": 5, "secretbyt": 5, "binaryvalu": 5, "textvalu": 5, "reveal": 5, "binari": 5, "byte": 5, "text": 5, "when": 5, "point": 5, "interfac": 5, "design": 5, "insid": 5, "version_descript": 5, "versiondescript": 5, "versionpayloadentri": 5, "baseversionid": 5, "payloadentri": 5, "relat": 5, "created_bi": 5, "error": 5, "metadata": 5, "modified_at": 5, "respons": 5, "createdbi": 5, "modifiedat": 5, "possibl": 5, "otherwis": 5, "code": 5, "detail": 5, "messag": 5, "error_typ": 5, "rpcerror": 5, "expires_at": 5, "expiresat": 5, "iamtoken": 5}, "objects": {"yc_lockbox": [[3, 0, 1, "", "AsyncYandexLockboxClient"], [3, 0, 1, "", "YandexLockboxClient"], [3, 0, 1, "", "YandexLockboxFacade"]], "yc_lockbox.AsyncYandexLockboxClient": [[3, 1, 1, "", "activate_secret"], [3, 1, 1, "", "add_secret_version"], [3, 2, 1, "", "auth_headers"], [3, 1, 1, "", "cancel_secret_version_destruction"], [3, 1, 1, "", "create_secret"], [3, 1, 1, "", "deactivate_secret"], [3, 1, 1, "", "delete_secret"], [3, 3, 1, "", "enable_async"], [3, 1, 1, "", "get_secret"], [3, 1, 1, "", "get_secret_payload"], [3, 1, 1, "", "list_secret_access_bindings"], [3, 1, 1, "", "list_secret_operations"], [3, 1, 1, "", "list_secret_versions"], [3, 1, 1, "", "list_secrets"], [3, 1, 1, "", "schedule_secret_version_destruction"], [3, 1, 1, "", "set_secret_access_bindings"], [3, 1, 1, "", "update_secret"], [3, 1, 1, "", "update_secret_access_bindings"]], "yc_lockbox.YandexLockboxClient": [[3, 1, 1, "", "activate_secret"], [3, 1, 1, "", "add_secret_version"], [3, 2, 1, "", "auth_headers"], [3, 1, 1, "", "cancel_secret_version_destruction"], [3, 1, 1, "", "create_secret"], [3, 1, 1, "", "deactivate_secret"], [3, 1, 1, "", "delete_secret"], [3, 1, 1, "", "get_secret"], [3, 1, 1, "", "get_secret_payload"], [3, 1, 1, "", "list_secret_access_bindings"], [3, 1, 1, "", "list_secret_operations"], [3, 1, 1, "", "list_secret_versions"], [3, 1, 1, "", "list_secrets"], [3, 1, 1, "", "schedule_secret_version_destruction"], [3, 1, 1, "", "set_secret_access_bindings"], [3, 1, 1, "", "update_secret"], [3, 1, 1, "", "update_secret_access_bindings"]], "yc_lockbox.YandexLockboxFacade": [[3, 2, 1, "", "client"]], "yc_lockbox._auth": [[3, 0, 1, "", "YandexAuthClient"]], "yc_lockbox._auth.YandexAuthClient": [[3, 2, 1, "", "adapter"], [3, 1, 1, "", "get_iam_token"]], "yc_lockbox._models": [[5, 4, 1, "", "INewSecret"], [5, 4, 1, "", "INewSecretPayloadEntry"], [5, 4, 1, "", "INewSecretVersion"], [5, 4, 1, "", "IUpdateSecret"], [5, 4, 1, "", "IamTokenResponse"], [5, 4, 1, "", "Operation"], [5, 4, 1, "", "Secret"], [5, 4, 1, "", "SecretPayload"], [5, 4, 1, "", "SecretPayloadEntry"], [5, 4, 1, "", "SecretVersion"], [5, 4, 1, "", "SecretVersionsList"], [5, 4, 1, "", "SecretsList"], [5, 4, 1, "", "YandexCloudError"]], "yc_lockbox._models.INewSecret": [[5, 5, 1, "", "deletion_protection"], [5, 5, 1, "", "description"], [5, 5, 1, "", "folder_id"], [5, 5, 1, "", "kms_key_id"], [5, 5, 1, "", "labels"], [5, 5, 1, "", "name"], [5, 5, 1, "", "version_description"], [5, 5, 1, "", "version_payload_entries"]], "yc_lockbox._models.INewSecretPayloadEntry": [[5, 5, 1, "", "binary_value"], [5, 5, 1, "", "key"], [5, 5, 1, "", "text_value"]], "yc_lockbox._models.INewSecretVersion": [[5, 5, 1, "", "base_version_id"], [5, 5, 1, "", "description"], [5, 5, 1, "", "payload_entries"]], "yc_lockbox._models.IUpdateSecret": [[5, 5, 1, "", "deletion_protection"], [5, 5, 1, "", "description"], [5, 5, 1, "", "labels"], [5, 5, 1, "", "name"], [5, 5, 1, "", "update_mask"]], "yc_lockbox._models.IamTokenResponse": [[5, 5, 1, "", "expires_at"], [5, 5, 1, "", "token"]], "yc_lockbox._models.Operation": [[5, 5, 1, "", "created_at"], [5, 5, 1, "", "created_by"], [5, 5, 1, "", "description"], [5, 5, 1, "", "done"], [5, 5, 1, "", "error"], [5, 5, 1, "", "id"], [5, 5, 1, "", "metadata"], [5, 5, 1, "", "modified_at"], [5, 2, 1, "", "resource"], [5, 5, 1, "", "response"]], "yc_lockbox._models.Secret": [[5, 1, 1, "", "activate"], [5, 1, 1, "", "add_version"], [5, 1, 1, "", "cancel_version_destruction"], [5, 5, 1, "", "created_at"], [5, 5, 1, "", "current_version"], [5, 1, 1, "", "deactivate"], [5, 1, 1, "", "delete"], [5, 5, 1, "", "deletion_protection"], [5, 5, 1, "", "description"], [5, 5, 1, "", "folder_id"], [5, 5, 1, "", "id"], [5, 5, 1, "", "kms_key_id"], [5, 5, 1, "", "labels"], [5, 1, 1, "", "list_versions"], [5, 5, 1, "", "name"], [5, 1, 1, "", "payload"], [5, 1, 1, "", "refresh"], [5, 1, 1, "", "schedule_version_destruction"], [5, 5, 1, "", "status"], [5, 1, 1, "", "update"]], "yc_lockbox._models.SecretPayload": [[5, 5, 1, "", "entries"], [5, 1, 1, "", "get"], [5, 5, 1, "", "version_id"]], "yc_lockbox._models.SecretPayloadEntry": [[5, 5, 1, "", "binary_value"], [5, 5, 1, "", "key"], [5, 1, 1, "", "reveal_binary_value"], [5, 1, 1, "", "reveal_text_value"], [5, 5, 1, "", "text_value"]], "yc_lockbox._models.SecretVersion": [[5, 1, 1, "", "cancel_version_destruction"], [5, 5, 1, "", "created_at"], [5, 5, 1, "", "description"], [5, 5, 1, "", "destroy_at"], [5, 5, 1, "", "id"], [5, 1, 1, "", "payload"], [5, 5, 1, "", "payload_entry_keys"], [5, 1, 1, "", "schedule_version_destruction"], [5, 5, 1, "", "secret_id"], [5, 5, 1, "", "status"]], "yc_lockbox._models.SecretVersionsList": [[5, 5, 1, "", "versions"]], "yc_lockbox._models.SecretsList": [[5, 5, 1, "", "secrets"]], "yc_lockbox._models.YandexCloudError": [[5, 5, 1, "", "code"], [5, 5, 1, "", "details"], [5, 2, 1, "", "error_type"], [5, 5, 1, "", "message"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:property", "3": "py:attribute", "4": "py:pydantic_model", "5": "py:pydantic_field"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "property", "Python property"], "3": ["py", "attribute", "Python attribute"], "4": ["py", "pydantic_model", "Python model"], "5": ["py", "pydantic_field", "Python field"]}, "titleterms": {"yandex": 0, "lockbox": 0, "python": 0, "client": [0, 3], "document": 0, "instal": 0, "quick": 0, "start": 0, "creat": 0, "new": 0, "secret": 0, "get": 0, "from": 0, "add": 0, "version": 0, "other": 0, "oper": 0, "async": 0, "mode": 0, "modul": 0, "content": 0, "indic": 0, "tabl": 0, "abstract": 1, "adapt": 2, "except": 4, "model": 5, "object": 5, "domain": 5, "pagin": 5, "upsert": 5, "common": 5}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 60}, "alltitles": {"Yandex Lockbox Python client documentation": [[0, "yandex-lockbox-python-client-documentation"]], "Installation": [[0, "installation"]], "Quick start": [[0, "quick-start"]], "Create a new secret": [[0, "create-a-new-secret"]], "Get secret from Lockbox": [[0, "get-secret-from-lockbox"]], "Add new version of secret": [[0, "add-new-version-of-secret"]], "Other operations with secret": [[0, "other-operations-with-secret"]], "Async mode": [[0, "async-mode"]], "Modules": [[0, "modules"]], "Content:": [[0, null]], "Indices and tables": [[0, "indices-and-tables"]], "Abstracts": [[1, "abstracts"]], "Adapters": [[2, "adapters"]], "Client": [[3, "client"]], "Exceptions": [[4, "exceptions"]], "Models & objects": [[5, "models-objects"]], "Domain models": [[5, "domain-models"]], "Paginated models": [[5, "paginated-models"]], "Upsert models": [[5, "upsert-models"]], "Common models": [[5, "common-models"]]}, "indexentries": {"asyncyandexlockboxclient (class in yc_lockbox)": [[3, "yc_lockbox.AsyncYandexLockboxClient"]], "yandexauthclient (class in yc_lockbox._auth)": [[3, "yc_lockbox._auth.YandexAuthClient"]], "yandexlockboxclient (class in yc_lockbox)": [[3, "yc_lockbox.YandexLockboxClient"]], "yandexlockboxfacade (class in yc_lockbox)": [[3, "yc_lockbox.YandexLockboxFacade"]], "activate_secret() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.activate_secret"]], "activate_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.activate_secret"]], "adapter (yc_lockbox._auth.yandexauthclient property)": [[3, "yc_lockbox._auth.YandexAuthClient.adapter"]], "add_secret_version() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.add_secret_version"]], "add_secret_version() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.add_secret_version"]], "auth_headers (yc_lockbox.asyncyandexlockboxclient property)": [[3, "yc_lockbox.AsyncYandexLockboxClient.auth_headers"]], "auth_headers (yc_lockbox.yandexlockboxclient property)": [[3, "yc_lockbox.YandexLockboxClient.auth_headers"]], "cancel_secret_version_destruction() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.cancel_secret_version_destruction"]], "cancel_secret_version_destruction() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.cancel_secret_version_destruction"]], "client (yc_lockbox.yandexlockboxfacade property)": [[3, "yc_lockbox.YandexLockboxFacade.client"]], "create_secret() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.create_secret"]], "create_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.create_secret"]], "deactivate_secret() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.deactivate_secret"]], "deactivate_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.deactivate_secret"]], "delete_secret() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.delete_secret"]], "delete_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.delete_secret"]], "enable_async (yc_lockbox.asyncyandexlockboxclient attribute)": [[3, "yc_lockbox.AsyncYandexLockboxClient.enable_async"]], "get_iam_token() (yc_lockbox._auth.yandexauthclient method)": [[3, "yc_lockbox._auth.YandexAuthClient.get_iam_token"]], "get_secret() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.get_secret"]], "get_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.get_secret"]], "get_secret_payload() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.get_secret_payload"]], "get_secret_payload() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.get_secret_payload"]], "list_secret_access_bindings() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.list_secret_access_bindings"]], "list_secret_access_bindings() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secret_access_bindings"]], "list_secret_operations() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.list_secret_operations"]], "list_secret_operations() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secret_operations"]], "list_secret_versions() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.list_secret_versions"]], "list_secret_versions() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secret_versions"]], "list_secrets() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.list_secrets"]], "list_secrets() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.list_secrets"]], "schedule_secret_version_destruction() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.schedule_secret_version_destruction"]], "schedule_secret_version_destruction() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.schedule_secret_version_destruction"]], "set_secret_access_bindings() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.set_secret_access_bindings"]], "set_secret_access_bindings() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.set_secret_access_bindings"]], "update_secret() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.update_secret"]], "update_secret() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.update_secret"]], "update_secret_access_bindings() (yc_lockbox.asyncyandexlockboxclient method)": [[3, "yc_lockbox.AsyncYandexLockboxClient.update_secret_access_bindings"]], "update_secret_access_bindings() (yc_lockbox.yandexlockboxclient method)": [[3, "yc_lockbox.YandexLockboxClient.update_secret_access_bindings"]], "activate() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.activate"]], "add_version() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.add_version"]], "base_version_id (yc_lockbox._models.inewsecretversion attribute)": [[5, "yc_lockbox._models.INewSecretVersion.base_version_id"]], "binary_value (yc_lockbox._models.inewsecretpayloadentry attribute)": [[5, "yc_lockbox._models.INewSecretPayloadEntry.binary_value"]], "binary_value (yc_lockbox._models.secretpayloadentry attribute)": [[5, "yc_lockbox._models.SecretPayloadEntry.binary_value"]], "cancel_version_destruction() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.cancel_version_destruction"]], "cancel_version_destruction() (yc_lockbox._models.secretversion method)": [[5, "yc_lockbox._models.SecretVersion.cancel_version_destruction"]], "code (yc_lockbox._models.yandexclouderror attribute)": [[5, "yc_lockbox._models.YandexCloudError.code"]], "created_at (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.created_at"]], "created_at (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.created_at"]], "created_at (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.created_at"]], "created_by (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.created_by"]], "current_version (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.current_version"]], "deactivate() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.deactivate"]], "delete() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.delete"]], "deletion_protection (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.deletion_protection"]], "deletion_protection (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.deletion_protection"]], "deletion_protection (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.deletion_protection"]], "description (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.description"]], "description (yc_lockbox._models.inewsecretversion attribute)": [[5, "yc_lockbox._models.INewSecretVersion.description"]], "description (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.description"]], "description (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.description"]], "description (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.description"]], "description (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.description"]], "destroy_at (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.destroy_at"]], "details (yc_lockbox._models.yandexclouderror attribute)": [[5, "yc_lockbox._models.YandexCloudError.details"]], "done (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.done"]], "entries (yc_lockbox._models.secretpayload attribute)": [[5, "yc_lockbox._models.SecretPayload.entries"]], "error (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.error"]], "error_type (yc_lockbox._models.yandexclouderror property)": [[5, "yc_lockbox._models.YandexCloudError.error_type"]], "expires_at (yc_lockbox._models.iamtokenresponse attribute)": [[5, "yc_lockbox._models.IamTokenResponse.expires_at"]], "folder_id (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.folder_id"]], "folder_id (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.folder_id"]], "get() (yc_lockbox._models.secretpayload method)": [[5, "yc_lockbox._models.SecretPayload.get"]], "id (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.id"]], "id (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.id"]], "id (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.id"]], "key (yc_lockbox._models.inewsecretpayloadentry attribute)": [[5, "yc_lockbox._models.INewSecretPayloadEntry.key"]], "key (yc_lockbox._models.secretpayloadentry attribute)": [[5, "yc_lockbox._models.SecretPayloadEntry.key"]], "kms_key_id (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.kms_key_id"]], "kms_key_id (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.kms_key_id"]], "labels (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.labels"]], "labels (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.labels"]], "labels (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.labels"]], "list_versions() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.list_versions"]], "message (yc_lockbox._models.yandexclouderror attribute)": [[5, "yc_lockbox._models.YandexCloudError.message"]], "metadata (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.metadata"]], "modified_at (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.modified_at"]], "name (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.name"]], "name (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.name"]], "name (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.name"]], "payload() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.payload"]], "payload() (yc_lockbox._models.secretversion method)": [[5, "yc_lockbox._models.SecretVersion.payload"]], "payload_entries (yc_lockbox._models.inewsecretversion attribute)": [[5, "yc_lockbox._models.INewSecretVersion.payload_entries"]], "payload_entry_keys (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.payload_entry_keys"]], "refresh() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.refresh"]], "resource (yc_lockbox._models.operation property)": [[5, "yc_lockbox._models.Operation.resource"]], "response (yc_lockbox._models.operation attribute)": [[5, "yc_lockbox._models.Operation.response"]], "reveal_binary_value() (yc_lockbox._models.secretpayloadentry method)": [[5, "yc_lockbox._models.SecretPayloadEntry.reveal_binary_value"]], "reveal_text_value() (yc_lockbox._models.secretpayloadentry method)": [[5, "yc_lockbox._models.SecretPayloadEntry.reveal_text_value"]], "schedule_version_destruction() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.schedule_version_destruction"]], "schedule_version_destruction() (yc_lockbox._models.secretversion method)": [[5, "yc_lockbox._models.SecretVersion.schedule_version_destruction"]], "secret_id (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.secret_id"]], "secrets (yc_lockbox._models.secretslist attribute)": [[5, "yc_lockbox._models.SecretsList.secrets"]], "status (yc_lockbox._models.secret attribute)": [[5, "yc_lockbox._models.Secret.status"]], "status (yc_lockbox._models.secretversion attribute)": [[5, "yc_lockbox._models.SecretVersion.status"]], "text_value (yc_lockbox._models.inewsecretpayloadentry attribute)": [[5, "yc_lockbox._models.INewSecretPayloadEntry.text_value"]], "text_value (yc_lockbox._models.secretpayloadentry attribute)": [[5, "yc_lockbox._models.SecretPayloadEntry.text_value"]], "token (yc_lockbox._models.iamtokenresponse attribute)": [[5, "yc_lockbox._models.IamTokenResponse.token"]], "update() (yc_lockbox._models.secret method)": [[5, "yc_lockbox._models.Secret.update"]], "update_mask (yc_lockbox._models.iupdatesecret attribute)": [[5, "yc_lockbox._models.IUpdateSecret.update_mask"]], "version_description (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.version_description"]], "version_id (yc_lockbox._models.secretpayload attribute)": [[5, "yc_lockbox._models.SecretPayload.version_id"]], "version_payload_entries (yc_lockbox._models.inewsecret attribute)": [[5, "yc_lockbox._models.INewSecret.version_payload_entries"]], "versions (yc_lockbox._models.secretversionslist attribute)": [[5, "yc_lockbox._models.SecretVersionsList.versions"]]}})
\ No newline at end of file
diff --git a/docs_src/source/index.rst b/docs_src/source/index.rst
index b874b1c..4a5b30f 100644
--- a/docs_src/source/index.rst
+++ b/docs_src/source/index.rst
@@ -225,6 +225,56 @@ Other operations with secret
+Async mode
+----------
+
+The client supports asynchronous mode using the aiohttp library. The signature of the methods does not differ from the synchronous implementation.
+
+
+Just import async client:
+
+.. code-block:: python
+
+ from yc_lockbox import AsyncYandexLockboxClient
+
+ lockbox = AsyncYandexLockboxClient("oauth_or_iam_token")
+
+
+
+Alternative:
+
+.. code-block:: python
+
+ from yc_lockbox import YandexLockboxFacade
+
+ lockbox = YandexLockboxFacade("oauth_or_iam_token", enable_async=True).client
+
+
+Example usage:
+
+.. code-block:: python
+
+ secret: Secret = await lockbox.get_secret("e6qxxxxxxxxxx")
+ payload = await secret.payload()
+ print(payload.entries) # list of SecretPayloadEntry objects
+
+ # Direct access
+
+ entry = payload["secret_entry_1"] # or payload.get("secret_entry_1")
+
+ print(entry.text_value) # return MASKED value like ***********
+ print(entry.reveal_text_value()) # similar to entry.text_value.get_secret_value()
+
+ # Async iterators
+
+ secret_versions = await secret.list_versions(iterator=True)
+
+ async for version in secret_versions:
+ if version.id != secret.current_version.id:
+ await version.schedule_version_destruction()
+ await version.cancel_version_destruction()
+
+
Modules
-------
diff --git a/docs_src/source/pages/clients.rst b/docs_src/source/pages/clients.rst
index 0d6b192..7081091 100644
--- a/docs_src/source/pages/clients.rst
+++ b/docs_src/source/pages/clients.rst
@@ -1,12 +1,22 @@
Client
======
+.. autoclass:: yc_lockbox.YandexLockboxFacade
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
.. autoclass:: yc_lockbox.YandexLockboxClient
:members:
:undoc-members:
:show-inheritance:
+.. autoclass:: yc_lockbox.AsyncYandexLockboxClient
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
.. autoclass:: yc_lockbox._auth.YandexAuthClient
:members:
:undoc-members:
- :show-inheritance:
\ No newline at end of file
+ :show-inheritance:
diff --git a/requirements.dev.txt b/requirements.dev.txt
index 7ca4bdb..66298eb 100644
--- a/requirements.dev.txt
+++ b/requirements.dev.txt
@@ -1,3 +1,4 @@
+aioresponses
bandit==1.7.*
black==24.*
Faker==23.*
diff --git a/tests/integration/test_async/conftest.py b/tests/integration/test_async/conftest.py
new file mode 100644
index 0000000..24f9151
--- /dev/null
+++ b/tests/integration/test_async/conftest.py
@@ -0,0 +1,17 @@
+import pytest
+from aioresponses import aioresponses
+
+from yc_lockbox import AsyncYandexLockboxClient
+
+
+@pytest.fixture
+def lockbox_client() -> AsyncYandexLockboxClient:
+ return AsyncYandexLockboxClient(
+ "t1.9exxlZrHlpKalJKVkM-.IvgNiLOPTh7FkZC3n6oi_y2lIc27gOByJ4QfVZKtccYso8U6MKeIZxe4LIyRosTSKEwYiZdV28C8zAIMaKcsAA" # fake, don't get your hopes up
+ )
+
+
+@pytest.fixture
+def aio_requests_mocker():
+ with aioresponses() as m:
+ yield m
diff --git a/tests/integration/test_async/test_mocked_async_lockbox_client.py b/tests/integration/test_async/test_mocked_async_lockbox_client.py
new file mode 100644
index 0000000..778f9d5
--- /dev/null
+++ b/tests/integration/test_async/test_mocked_async_lockbox_client.py
@@ -0,0 +1,908 @@
+import re
+import pytest
+
+from aioresponses import aioresponses
+from typing import Any, AsyncGenerator, AsyncIterator
+from requests_mock import Mocker
+
+from yc_lockbox._constants import YC_LOCKBOX_BASE_URL, YC_LOCKBOX_PAYLOAD_BASE_URL
+from yc_lockbox._models import (
+ Operation,
+ Secret,
+ SecretVersion,
+ SecretPayload,
+ SecretPayloadEntry,
+ SecretsList,
+ SecretVersionsList,
+ YandexCloudError,
+ INewSecret,
+ INewSecretVersion,
+ INewSecretPayloadEntry,
+ IUpdateSecret,
+)
+from yc_lockbox._lockbox import AsyncYandexLockboxClient
+
+
+@pytest.mark.parametrize(
+ "secret_id, url, mock_response",
+ [
+ (
+ "e6qh3v0mgnmiq995h1v9",
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qh3v0mgnmiq995h1v9:activate",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.ActivateSecretMetadata",
+ "secretId": "e6qh3v0mgnmiq995h1v9",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Secret",
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qii1ovrs7suo5oroe8",
+ "secretId": "e6qh3v0mgnmiq995h1v9",
+ "createdAt": "2024-03-26T07:38:41.908Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": False,
+ "id": "e6qh3v0mgnmiq995h1v9",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T07:38:41.908Z",
+ "name": "test-key",
+ "status": "ACTIVE",
+ },
+ "id": "e6qdrk237rdpt8sibbng",
+ "description": "Activate secret",
+ "createdAt": "2024-03-26T07:38:42.189024661Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T07:38:42.189056725Z",
+ },
+ )
+ ],
+)
+async def test_mocked_activate_secret(
+ secret_id: str,
+ url: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.post(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.activate_secret(secret_id)
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] == secret_id
+
+ assert isinstance(result.resource, Secret)
+ assert isinstance(result.resource.client, AsyncYandexLockboxClient)
+ assert result.resource.id == secret_id
+
+
+@pytest.mark.parametrize(
+ "secret_id, url, mock_response, version",
+ [
+ (
+ "e6qgq6gaei7ejteotjge",
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qgq6gaei7ejteotjge:addVersion",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.AddVersionMetadata",
+ "secretId": "e6qgq6gaei7ejteotjge",
+ "versionId": "e6qetl2mu52s8gvq0ccj",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Version",
+ "payloadEntryKeys": ["key1", "key2", "test_key"],
+ "id": "e6qetl2mu52s8gvq0ccj",
+ "secretId": "e6qgq6gaei7ejteotjge",
+ "createdAt": "2024-03-26T07:59:23.172Z",
+ "status": "ACTIVE",
+ },
+ "id": "e6q67tu8pet2328ktemr",
+ "description": "Add version",
+ "createdAt": "2024-03-26T07:59:23.172687854Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T07:59:23.172723443Z",
+ },
+ INewSecretVersion(payloadEntries=[INewSecretPayloadEntry(key="test_key", textValue="test_value")]),
+ )
+ ],
+)
+async def test_mocked_add_secret_version(
+ secret_id: str,
+ url: str,
+ mock_response: dict[str, Any],
+ version: INewSecretVersion,
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.post(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.add_secret_version(secret_id, version)
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] == secret_id
+
+ assert isinstance(result.resource, SecretVersion)
+ assert isinstance(result.resource.client, AsyncYandexLockboxClient)
+ assert result.resource.secret_id == secret_id
+
+
+@pytest.mark.parametrize(
+ "url, mock_response, secret",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets",
+ {
+ "done": False,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.CreateSecretMetadata",
+ "secretId": "e6qgq6gaei7ejteotjge",
+ "versionId": "e6qfcrpioij83qbka9lo",
+ },
+ "id": "e6qe3dc7j2d0555pt9ak",
+ "description": "Create secret",
+ "createdAt": "2024-03-26T07:59:22.709848334Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T07:59:22.709848334Z",
+ },
+ INewSecret(
+ folder_id="b1gjpj7bq22qqqqqq7t6",
+ name="test-key",
+ version_payload_entries=[
+ INewSecretPayloadEntry(key="key1", textValue="value1"),
+ INewSecretPayloadEntry(key="key2", binaryValue="value2".encode()),
+ ],
+ ),
+ )
+ ],
+)
+async def test_mocked_create_secret(
+ url: str,
+ mock_response: dict[str, Any],
+ secret: INewSecret,
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.post(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.create_secret(secret)
+
+ assert isinstance(result, Operation)
+ assert not result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] is not None
+
+ assert result.resource is None
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, version_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qqg8aq7jum59ivv560:cancelVersionDestruction",
+ "e6qqg8aq7jum59ivv560",
+ "e6qo0aqmflbl0o00mlmd",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.CancelVersionDestructionMetadata",
+ "secretId": "e6qqg8aq7jum59ivv560",
+ "versionId": "e6qo0aqmflbl0o00mlmd",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Version",
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qo0aqmflbl0o00mlmd",
+ "secretId": "e6qqg8aq7jum59ivv560",
+ "createdAt": "2024-03-26T08:33:33.625Z",
+ "status": "ACTIVE",
+ },
+ "id": "e6qe0uqinjvu5j2pmj33",
+ "description": "Cancel version destruction",
+ "createdAt": "2024-03-26T08:33:34.912533615Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T08:33:34.912558579Z",
+ },
+ )
+ ],
+)
+async def test_mocked_cancel_version_descruction(
+ url: str,
+ secret_id: str,
+ version_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.post(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.cancel_secret_version_destruction(
+ secret_id, version_id
+ )
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] == secret_id
+ assert result.metadata["versionId"] == version_id
+
+ assert isinstance(result.resource, SecretVersion)
+ assert isinstance(result.resource.client, AsyncYandexLockboxClient)
+ assert result.resource.id == version_id
+ assert result.resource.secret_id == secret_id
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6q4d0nd2nto737ak1f0:deactivate",
+ "e6q4d0nd2nto737ak1f0",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.DeactivateSecretMetadata",
+ "secretId": "e6q4d0nd2nto737ak1f0",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Secret",
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qcc4gft2aik6bmg65m",
+ "secretId": "e6q4d0nd2nto737ak1f0",
+ "createdAt": "2024-03-26T08:45:51.825Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": False,
+ "id": "e6q4d0nd2nto737ak1f0",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T08:45:51.825Z",
+ "name": "test-key",
+ "status": "INACTIVE",
+ },
+ "id": "e6qsntgq23adl058gmh9",
+ "description": "Deactivate secret",
+ "createdAt": "2024-03-26T08:45:52.049278552Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T08:45:52.049314259Z",
+ },
+ )
+ ],
+)
+async def test_mocked_deactivate_secret(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.post(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.deactivate_secret(secret_id)
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] == secret_id
+
+ assert isinstance(result.resource, Secret)
+ assert isinstance(result.resource.client, AsyncYandexLockboxClient)
+ assert result.resource.id == secret_id
+ assert result.resource.status == "INACTIVE"
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6q8ccgvcp685ef0o85m",
+ "e6q8ccgvcp685ef0o85m",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.DeleteSecretMetadata",
+ "secretId": "e6q8ccgvcp685ef0o85m",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Secret",
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qa0570t64ao8gbjr5g",
+ "secretId": "e6q8ccgvcp685ef0o85m",
+ "createdAt": "2024-03-26T09:02:32.090Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": False,
+ "id": "e6q8ccgvcp685ef0o85m",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T09:02:32.090Z",
+ "name": "test-key",
+ },
+ "id": "e6qtmcjfshj46tup03qh",
+ "description": "Delete secret",
+ "createdAt": "2024-03-26T09:02:32.811030090Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T09:02:32.811066746Z",
+ },
+ )
+ ],
+)
+async def test_mocked_delete_secret(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.delete(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.delete_secret(secret_id)
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] == secret_id
+
+ assert isinstance(result.resource, Secret)
+ assert isinstance(result.resource.client, AsyncYandexLockboxClient)
+ assert result.resource.id == secret_id
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qj7gpvimsi1igs228r",
+ "e6qj7gpvimsi1igs228r",
+ {
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qfnqdkb105a4seprsn",
+ "secretId": "e6qj7gpvimsi1igs228r",
+ "createdAt": "2024-03-26T09:07:50.981Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": True,
+ "id": "e6qj7gpvimsi1igs228r",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T09:07:50.981Z",
+ "name": "test-key",
+ "status": "ACTIVE",
+ },
+ )
+ ],
+)
+async def test_mocked_get_secret(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.get(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Secret = await lockbox_client.get_secret(secret_id)
+
+ assert isinstance(result, Secret)
+ assert isinstance(result.current_version, SecretVersion)
+ assert isinstance(result.client, AsyncYandexLockboxClient)
+ assert result.id == secret_id
+ assert result.status == "ACTIVE"
+ assert result.deletion_protection
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_PAYLOAD_BASE_URL}/secrets/e6qj7gpvimsi1igs228r/payload",
+ "e6qj7gpvimsi1igs228r",
+ {
+ "entries": [{"key": "key1", "textValue": "value1"}, {"key": "key2", "binaryValue": "value2"}],
+ "versionId": "e6qck9fs0ue4dotveirb",
+ },
+ )
+ ],
+)
+async def test_mocked_get_secret_payload(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.get(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: SecretPayload = await lockbox_client.get_secret_payload(secret_id)
+
+ assert isinstance(result, SecretPayload)
+ assert isinstance(result.entries, list)
+ assert isinstance(result.entries[0], SecretPayloadEntry)
+ assert result.client is None
+
+ assert str(result[0].text_value) == "**********"
+ assert result[0].reveal_text_value() == "value1"
+ assert result[0].reveal_binary_value() is None
+
+ assert str(result.get("key1").text_value) == "**********"
+ assert result["key1"].reveal_text_value() == "value1"
+ assert result["key1"].reveal_binary_value() is None
+
+ assert str(result.get("key2").binary_value) == "**********"
+ assert result["key2"].reveal_text_value() is None
+ assert result["key2"].reveal_binary_value() == "value2"
+
+ with pytest.raises(KeyError) as key_excinfo:
+ result["key3"]
+ assert "not exists" in str(key_excinfo.value)
+
+ with pytest.raises(IndexError) as index_excinfo:
+ result[10]
+ assert "out of range" in str(index_excinfo.value)
+
+ assert result.get("key5") is None
+ assert result.get("key6", default="foo") == "foo"
+
+
+@pytest.mark.parametrize(
+ "url, folder_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets",
+ "b1gjpj7bq52xxxxxx7t6",
+ {
+ "secrets": [
+ {
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qs8nc5427jv25l98i6",
+ "secretId": "e6qlkppt9rc0saulbfjh",
+ "createdAt": "2024-03-26T09:28:19.259Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": False,
+ "id": "e6qlkppt9rc0saulbfjh",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T09:28:19.259Z",
+ "name": "test-secret-1",
+ "status": "ACTIVE",
+ },
+ {
+ "currentVersion": {
+ "payloadEntryKeys": ["test-key"],
+ "id": "e6q1kclhp4jdnfms9bal",
+ "secretId": "e6qndtc3gtcnti2jb0iq",
+ "createdAt": "2024-03-26T09:23:50.004Z",
+ "status": "INACTIVE",
+ },
+ "deletionProtection": True,
+ "id": "e6qndtc3gtcnti2jb0iq",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T09:23:50.004Z",
+ "name": "test-secret-2",
+ "status": "ACTIVE",
+ },
+ ],
+ "nextPageToken": "e6qndtc4gtcnti3jb0ix",
+ },
+ )
+ ],
+)
+async def test_mocked_paginated_list_secrets(
+ url: str,
+ folder_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.get(
+ re.compile(f"{re.escape(url)}\\?.*"), # aiohttp is sensitive to query params
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: SecretsList = await lockbox_client.list_secrets(folder_id, page_size=2)
+
+ assert isinstance(result, SecretsList)
+ assert hasattr(result, "secrets")
+ assert isinstance(result.secrets, list)
+ assert result.next_page_token is not None
+
+ for secret in result.secrets:
+ assert isinstance(secret, Secret)
+ assert isinstance(secret.current_version, SecretVersion)
+ assert isinstance(secret.client, AsyncYandexLockboxClient)
+
+
+@pytest.mark.parametrize(
+ "url, folder_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets",
+ "b1gjpj7bq52xxxxxx7t6",
+ {
+ "secrets": [
+ {
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qs8nc5427jv25l98i6",
+ "secretId": "e6qlkppt9rc0saulbfjh",
+ "createdAt": "2024-03-26T09:28:19.259Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": False,
+ "id": "e6qlkppt9rc0saulbfjh",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T09:28:19.259Z",
+ "name": "test-secret-1",
+ "status": "ACTIVE",
+ },
+ {
+ "currentVersion": {
+ "payloadEntryKeys": ["test-key"],
+ "id": "e6q1kclhp4jdnfms9bal",
+ "secretId": "e6qndtc3gtcnti2jb0iq",
+ "createdAt": "2024-03-26T09:23:50.004Z",
+ "status": "INACTIVE",
+ },
+ "deletionProtection": True,
+ "id": "e6qndtc3gtcnti2jb0iq",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T09:23:50.004Z",
+ "name": "test-secret-2",
+ "status": "ACTIVE",
+ },
+ ],
+ "nextPageToken": None,
+ },
+ )
+ ],
+)
+async def test_mocked_iterable_list_secrets(
+ url: str,
+ folder_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.get(
+ re.compile(f"{re.escape(url)}\\?.*"), # aiohttp is sensitive to query params
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result = await lockbox_client.list_secrets(folder_id, iterator=True)
+
+ assert isinstance(result, AsyncGenerator) or isinstance(result, AsyncIterator)
+ assert not hasattr(result, "next_page_token")
+
+ async for secret in result:
+ assert isinstance(secret, Secret)
+ assert isinstance(secret.current_version, SecretVersion)
+ assert isinstance(secret.client, AsyncYandexLockboxClient)
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qr4ra9qh9thdnhrh7s/versions",
+ "e6qr4ra9qh9thdnhrh7s",
+ {
+ "versions": [
+ {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6q2fbgrmuc3tmh8yyy3",
+ "secretId": "e6qr4ra9qh9thdnhrh7s",
+ "createdAt": "2024-03-26T10:15:37.400Z",
+ "status": "ACTIVE",
+ },
+ {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6q2fbgrmuc3tmh8xxx3",
+ "secretId": "e6qr4ra9qh9thdnhrh7s",
+ "createdAt": "2024-03-26T10:15:37.400Z",
+ "status": "ACTIVE",
+ },
+ ],
+ "nextPageToken": "e6q2fbgrmuc3tmh8yyy3",
+ },
+ )
+ ],
+)
+async def test_mocked_paginated_list_secret_versions(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.get(
+ re.compile(f"{re.escape(url)}\\?.*"), # aiohttp is sensitive to query params
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: SecretsList = await lockbox_client.list_secret_versions(secret_id, page_size=2)
+
+ assert isinstance(result, SecretVersionsList)
+ assert hasattr(result, "versions")
+ assert isinstance(result.versions, list)
+ assert result.next_page_token is not None
+
+ for version in result.versions:
+ assert isinstance(version, SecretVersion)
+ assert isinstance(version.client, AsyncYandexLockboxClient)
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qr4ra9qh9thdnhrh7s/versions",
+ "e6qr4ra9qh9thdnhrh7s",
+ {
+ "versions": [
+ {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6q2fbgrmuc3tmh8yyy3",
+ "secretId": "e6qr4ra9qh9thdnhrh7s",
+ "createdAt": "2024-03-26T10:15:37.400Z",
+ "status": "ACTIVE",
+ },
+ {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6q2fbgrmuc3tmh8xxx3",
+ "secretId": "e6qr4ra9qh9thdnhrh7s",
+ "createdAt": "2024-03-26T10:15:37.400Z",
+ "status": "ACTIVE",
+ },
+ ],
+ },
+ )
+ ],
+)
+async def test_mocked_iterable_list_secret_versions(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.get(
+ re.compile(f"{re.escape(url)}\\?.*"), # aiohttp is sensitive to query params
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result = await lockbox_client.list_secret_versions(secret_id, iterator=True)
+
+ assert isinstance(result, AsyncGenerator) or isinstance(result, AsyncIterator)
+ assert not hasattr(result, "next_page_token")
+
+ async for version in result:
+ assert isinstance(version, SecretVersion)
+ assert isinstance(version.client, AsyncYandexLockboxClient)
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, version_id, mock_response",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qqg8aq7jum59ivv560:scheduleVersionDestruction",
+ "e6qqg8aq7jum59ivv560",
+ "e6qo0aqmflbl0o00mlmd",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.ScheduleVersionDestructionMetadata",
+ "secretId": "e6qqg8aq7jum59ivv560",
+ "versionId": "e6qo0aqmflbl0o00mlmd",
+ "destroyAt": "2024-04-02T08:33:34.641Z",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Version",
+ "payloadEntryKeys": ["mykey", "everybody"],
+ "id": "e6qo0aqmflbl0o00mlmd",
+ "secretId": "e6qqg8aq7jum59ivv560",
+ "createdAt": "2024-03-26T08:33:33.625Z",
+ "destroyAt": "2024-04-02T08:33:34.641Z",
+ "status": "SCHEDULED_FOR_DESTRUCTION",
+ },
+ "id": "e6qdb9sm2tut6econ95c",
+ "description": "Schedule version destruction",
+ "createdAt": "2024-03-26T08:33:34.654233229Z",
+ "createdBy": "aje884de7xxxxxxq3joj",
+ "modifiedAt": "2024-03-26T08:33:34.654258874Z",
+ },
+ )
+ ],
+)
+async def test_mocked_schedule_secret_version_destruction(
+ url: str,
+ secret_id: str,
+ version_id: str,
+ mock_response: dict[str, Any],
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.post(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.schedule_secret_version_destruction(
+ secret_id, version_id
+ )
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] == secret_id
+ assert result.metadata["versionId"] == version_id
+
+ assert isinstance(result.resource, SecretVersion)
+ assert isinstance(result.resource.client, AsyncYandexLockboxClient)
+ assert result.resource.id == version_id
+ assert result.resource.secret_id == secret_id
+ assert result.resource.status == "SCHEDULED_FOR_DESTRUCTION"
+
+
+@pytest.mark.parametrize(
+ "url, secret_id, mock_response, data",
+ [
+ (
+ f"{YC_LOCKBOX_BASE_URL}/secrets/e6qq26njrboiglh9nfkq",
+ "e6qq26njrboiglh9nfkq",
+ {
+ "done": True,
+ "metadata": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.UpdateSecretMetadata",
+ "secretId": "e6qq26njrboiglh9nfkq",
+ },
+ "response": {
+ "@type": "type.googleapis.com/yandex.cloud.lockbox.v1.Secret",
+ "currentVersion": {
+ "payloadEntryKeys": ["key1", "key2"],
+ "id": "e6qsmqo0svqdcgjlted7",
+ "secretId": "e6qq26njrboiglh9nfkq",
+ "createdAt": "2024-03-26T10:31:56.563Z",
+ "status": "ACTIVE",
+ },
+ "deletionProtection": False,
+ "id": "e6qq26njrboiglh9nfkq",
+ "folderId": "b1gjpj7bq52xxxxxx7t6",
+ "createdAt": "2024-03-26T10:31:56.563Z",
+ "name": "updated-secret",
+ "description": "has been updated",
+ "status": "ACTIVE",
+ },
+ "id": "e6qhnt68r89usttisc14",
+ "description": "Update secret",
+ "createdAt": "2024-03-26T10:31:56.934095604Z",
+ "createdBy": "aje884de4fxxxxxx3joj",
+ "modifiedAt": "2024-03-26T10:31:56.934138749Z",
+ },
+ IUpdateSecret(updateMask="name,description", name="updated-secret", description="has been updated"),
+ )
+ ],
+)
+async def test_mocked_update_secret(
+ url: str,
+ secret_id: str,
+ mock_response: dict[str, Any],
+ data: IUpdateSecret,
+ aio_requests_mocker: aioresponses,
+ lockbox_client: AsyncYandexLockboxClient,
+) -> None:
+
+ aio_requests_mocker.patch(
+ url,
+ headers={"Content-Type": "application/json"},
+ payload=mock_response,
+ status=200,
+ )
+
+ result: Operation | YandexCloudError = await lockbox_client.update_secret(secret_id, data)
+
+ assert isinstance(result, Operation)
+ assert result.done
+ assert result.id == mock_response["id"]
+ assert result.metadata["secretId"] is not None
+
+ assert isinstance(result.resource, Secret)
+ assert isinstance(result.resource.current_version, SecretVersion)
+ assert isinstance(result.client, AsyncYandexLockboxClient)
+
+
+# Not implemented methods test
+
+
+async def test_mocked_list_secret_access_bindings(lockbox_client) -> None:
+ with pytest.raises(NotImplementedError) as excinfo:
+ await lockbox_client.list_secret_access_bindings()
+ assert str(excinfo.value) == ""
+
+
+async def test_mocked_list_secret_operations(lockbox_client) -> None:
+ with pytest.raises(NotImplementedError) as excinfo:
+ await lockbox_client.list_secret_operations()
+ assert str(excinfo.value) == ""
+
+
+async def test_mocked_set_secret_access_bindings(lockbox_client) -> None:
+ with pytest.raises(NotImplementedError) as excinfo:
+ await lockbox_client.set_secret_access_bindings()
+ assert str(excinfo.value) == ""
+
+
+async def test_mocked_update_secret_access_bindings(lockbox_client) -> None:
+ with pytest.raises(NotImplementedError) as excinfo:
+ await lockbox_client.update_secret_access_bindings()
+ assert str(excinfo.value) == ""
diff --git a/tests/integration/conftest.py b/tests/integration/test_sync/conftest.py
similarity index 100%
rename from tests/integration/conftest.py
rename to tests/integration/test_sync/conftest.py
diff --git a/tests/integration/test_mocked_lockbox_client.py b/tests/integration/test_sync/test_mocked_lockbox_client.py
similarity index 100%
rename from tests/integration/test_mocked_lockbox_client.py
rename to tests/integration/test_sync/test_mocked_lockbox_client.py
diff --git a/yc_lockbox/__init__.py b/yc_lockbox/__init__.py
index 3eb0c60..644aa51 100644
--- a/yc_lockbox/__init__.py
+++ b/yc_lockbox/__init__.py
@@ -24,7 +24,7 @@
SOFTWARE.
"""
-from yc_lockbox._lockbox import YandexLockboxClient
+from yc_lockbox._lockbox import AsyncYandexLockboxClient, YandexLockboxClient, YandexLockboxFacade
from yc_lockbox._models import (
Secret,
INewSecretPayloadEntry,
@@ -35,7 +35,7 @@
YandexCloudError,
)
-__version__ = "0.1.3"
+__version__ = "0.2.0"
__author__ = "Akim Faskhutdinov"
__author_email__ = "akimstrong@yandex.ru"
__license__ = "MIT"
@@ -47,7 +47,9 @@
"INewSecret",
"INewSecretVersion",
"IUpdateSecret",
+ "AsyncYandexLockboxClient",
"YandexLockboxClient",
+ "YandexLockboxFacade",
"Operation",
"YandexCloudError",
]
diff --git a/yc_lockbox/_adapters.py b/yc_lockbox/_adapters.py
index 370594f..ff96027 100644
--- a/yc_lockbox/_adapters.py
+++ b/yc_lockbox/_adapters.py
@@ -149,6 +149,9 @@ async def request(
"or use ``pip install yc-lockbox[aio]`` for resolve it."
)
+ if params is not None:
+ params = {k: v for k, v in params.items() if v is not None} # aiohttp don't like NoneType
+
async with aiohttp.ClientSession() as session:
async with session.request(
method=method, url=url, data=data, json=json, headers=headers, params=params, **kwargs
diff --git a/yc_lockbox/_lockbox.py b/yc_lockbox/_lockbox.py
index a5f6a49..e54fc3b 100644
--- a/yc_lockbox/_lockbox.py
+++ b/yc_lockbox/_lockbox.py
@@ -1,8 +1,8 @@
import logging
-from typing import Type, Optional, Callable, Iterator
+from typing import Any, AsyncGenerator, Coroutine, Type, Optional, Callable, Iterator
from yc_lockbox._abc import AbstractYandexAuthClient, AbstractYandexLockboxClient, AbstractHTTPAdapter
-from yc_lockbox._adapters import HTTPAdapter
+from yc_lockbox._adapters import HTTPAdapter, AsyncHTTPAdapter
from yc_lockbox._auth import YandexAuthClient
from yc_lockbox._models import (
Secret,
@@ -479,23 +479,530 @@ def update_secret_access_bindings(self, *args, **kwargs):
raise NotImplementedError
-# TODO: implement
class AsyncYandexLockboxClient(AbstractYandexLockboxClient):
- """The same as :class:`YandexLockboxClient` but async."""
+ """
+ Yandex Lockbox secrets vault client.
+ The same as :class:`YandexLockboxClient` but async.
+
+ :param credentials: Credentials for authenticate requests.
+ Allowed types: service account key, OAuth token, IAM token.
+ :param auth_client: Optional client implementation for authenticate requests.
+ Defaults to ``YandexAuthClient``.
+ :param adapter: HTTP adapter for communicate with Yandex Cloud API.
+ :param lockbox_base_url: Lockbox base URL without resource path.
+ :param payload_lockbox_base_url: Lockbox payload base URL without resource path.
+ :param auth_base_url: IAM base URL without resource path.
+
+ .. note::
+
+ All the values of the secrets are masked, i.e. looks like ``***********``.
+ To get the real value of the secret, you need to call the injected methods
+ :func:`reveal_text_value()` or :func:`reveal_binary_value()`.
+
+ Usage::
+
+ from yc_lockbox import AsyncYandexLockboxClient, Secret
+
+ lockbox = AsyncYandexLockboxClient("y0_AgAEXXXXXXXXXXXXXXXXXXXXXXXXX") # OAuth or IAM token
+
+ secret: Secret = await lockbox.get_secret("e6xxxxxxxxxxxxxxxx")
+ print(secret.name, secret.status, secret.description)
+
+ secret_versions = await secret.list_versions()
+ async for version in secret_versions:
+ print(version)
+ if version.id != secret.current_version.id:
+ await version.schedule_version_destruction()
+
+ payload = await secret.payload()
+
+ try:
+ value = payload["mykey"]
+ print(value.reveal_text_value())
+ except KeyError:
+ print("Invalid key!")
+
+ print(payload.get("foo")) # None if not exists without raising exception
+ entry = payload[0] # similar to payload.entries[0]
- def __init__(self, *args, **kwargs) -> None:
- raise NotImplementedError # pragma: no cover
+ Authenticate via service account key::
+ import json
+
+ # generate json key for your SA
+ # yc iam key create --service-account-name my-sa --output key.json
+
+ with open("./key.json", "r") as infile:
+ credentials = json.load(infile)
+
+ lockbox = AsyncYandexLockboxClient(credentials)
-# TODO: implement
-class YandexLockbox:
+ """
+
+ enable_async = True
+
+ def __init__(
+ self,
+ credentials,
+ *,
+ auth_client: Optional[Type[AbstractYandexAuthClient]] = YandexAuthClient,
+ adapter: Optional[Type[AbstractHTTPAdapter]] = AsyncHTTPAdapter,
+ lockbox_base_url: str | None = None,
+ payload_lockbox_base_url: str | None = None,
+ ) -> None:
+ super().__init__(
+ lockbox_base_url=lockbox_base_url,
+ payload_lockbox_base_url=payload_lockbox_base_url,
+ )
+ self.auth: AbstractYandexAuthClient = auth_client(credentials)
+ self.adapter: AbstractHTTPAdapter = adapter
+
+ @property
+ def auth_headers(self) -> dict[str, str]:
+ """Returns headers for authenticate."""
+ return self.auth.get_auth_headers()
+
+ def _inject_client_to_items(self, items: list[T]) -> list[T]:
+ """Inject this client to each response model."""
+ return list(map(lambda item: item.inject_client(self), items))
+
+ async def _seekable_response(
+ self, func: Callable[..., BasePaginatedResponse], entrypoint: str, *args, **kwargs
+ ) -> AsyncGenerator[Any, T]:
+ """
+ Requests all data from the API using the generators, instead of a page-by-page response.
+ This method does not works with dict. Be careful.
+ Returns list of objects from model entrypoint.
+
+ :param func: Adapter func to get data from API.
+ :param entrypoint: Response attribute that contains list of useful data items.
+ :param args: Arguments for func. Will be passed when called inside.
+ :param kwargs: Keyword arguments for func. Similar to ``args``.
+ """
+
+ if kwargs.get("params") is None:
+ raise TypeError(
+ "This method works only with query string parameters. Check keyword arguments to resolve it."
+ )
+
+ next_token = "" # nosec B105
+
+ while next_token is not None:
+ # There could potentially be a problem if some request doesn't have a 'pageToken' in query string params.
+ # However, this is already a question for a non-consistent API, I think.
+ # An unlikely story, but worth keeping in mind.
+ kwargs["params"]["pageToken"] = next_token
+
+ response = await func(*args, **kwargs)
+ next_token = response.next_page_token # None or a new token from the API
+
+ if not hasattr(response, entrypoint):
+ raise AttributeError(f"Entrypoint {entrypoint} not exists in response model.")
+
+ for item in getattr(response, entrypoint):
+ if not hasattr(item, "inject_client"):
+ raise AttributeError(
+ f"Incorrect item. Method 'inject_client' is not exists in {item.__class__} {type(item)}"
+ )
+ item.inject_client(self)
+ yield item
+
+ async def activate_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Activates the specified secret.
+
+ :param secret_id: Secret indentifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:activate"
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def add_secret_version(
+ self, secret_id: str, version: INewSecretVersion, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Adds new version based on a previous one.
+
+ :param secret_id: Secret indentifier.
+ :param version: A new version object.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:addVersion"
+ payload = version.model_dump_json(by_alias=True, exclude_none=True)
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ data=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def create_secret(
+ self, secret: INewSecret, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Creates a secret in the specified folder.
+
+ :param secret: A new secret object.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets"
+ payload = secret.model_dump_json(by_alias=True, exclude_none=True)
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ data=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def cancel_secret_version_destruction(
+ self, secret_id: str, version_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Cancels previously scheduled version destruction, if the version hasn't been destroyed yet.
+
+ :param secret_id: Secret indentifier.
+ :param version_id: Secret version id to cancel destruction.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:cancelVersionDestruction"
+ payload = {"versionId": version_id}
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ json=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def deactivate_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Deactivate a secret.
+
+ :param secret_id: Secret indentifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:deactivate"
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def delete_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Deletes the specified secret.
+
+ :param secret_id: Secret indentifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}"
+ response = await self.adapter.request(
+ "DELETE",
+ url,
+ headers=self.auth_headers,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def get_secret(
+ self, secret_id: str, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Secret | YandexCloudError]:
+ """
+ Get lockbox secret by ID.
+
+ :param secret_id: Secret identifier.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}"
+ response = await self.adapter.request(
+ "GET",
+ url,
+ headers=self.auth_headers,
+ response_model=Secret,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ async def get_secret_payload(
+ self,
+ secret_id: str,
+ version_id: str | None = None,
+ raise_for_status: bool = True,
+ ) -> Coroutine[Any, Any, SecretPayload | YandexCloudError]:
+ """
+ Get lockbox secret payload by ID and optional version.
+
+ :param secret_id: Secret identifier.
+ :param version_id: Secret version. Optional.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.payload_lockbox_base_url}/secrets/{secret_id}/payload"
+ params = {"version_id": version_id} if version_id else None
+ return await self.adapter.request(
+ "GET",
+ url,
+ headers=self.auth_headers,
+ response_model=SecretPayload,
+ raise_for_status=raise_for_status,
+ params=params,
+ )
+
+ async def list_secrets(
+ self,
+ folder_id: str,
+ page_size: int = 100,
+ page_token: str | None = None,
+ raise_for_status: bool = True,
+ iterator: bool = False,
+ ) -> Coroutine[Any, Any, SecretsList | YandexCloudError] | AsyncGenerator[Any, Secret]:
+ """
+ Retrieves the list of secrets in the specified folder.
+
+ :param folder_id: ID of the folder to list secrets in.
+ :param page_size: The maximum number of results per page to return.
+ If the number of available results is larger than ``page_size``,
+ the service returns a ``next_page_token`` that can be used to get
+ the next page of results in subsequent list requests.
+ Default value: ``100``.
+ The maximum value is ``1000``.
+ :param page_token: Page token. To get the next page of results, set ``page_token``
+ to the ``next_page_token`` returned by a previous list request.
+ :param iterator: Returns all data as iterator (generator) instead paginated result.
+ """
+ args = (
+ "GET",
+ f"{self.lockbox_base_url}/secrets",
+ )
+ kwargs = {
+ "headers": self.auth_headers,
+ "params": {"folderId": folder_id, "pageSize": page_size, "pageToken": page_token},
+ "response_model": SecretsList,
+ "raise_for_status": raise_for_status,
+ }
+
+ if iterator:
+ return self._seekable_response(self.adapter.request, "secrets", *args, **kwargs)
+
+ response = await self.adapter.request(*args, **kwargs)
+ self._inject_client_to_items(response.secrets)
+ return response
+
+ # TODO: implement
+ async def list_secret_access_bindings(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+ # TODO: implement
+ async def list_secret_operations(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+ async def list_secret_versions(
+ self,
+ secret_id: str,
+ page_size: int = 100,
+ page_token: str | None = None,
+ raise_for_status: bool = True,
+ iterator: bool = False,
+ ) -> Coroutine[Any, Any, SecretVersionsList | YandexCloudError] | AsyncGenerator[Any, SecretVersion]:
+ """
+ Retrieves the list of versions of the specified secret.
+
+ :param secret_id: Secret identifier.
+ :param page_size: The maximum number of results per page to return.
+ If the number of available results is larger than ``page_size``,
+ the service returns a ``next_page_token`` that can be used to get
+ the next page of results in subsequent list requests.
+ Default value: ``100``.
+ The maximum value is ``1000``.
+ :param page_token: Page token. To get the next page of results, set ``page_token``
+ to the ``next_page_token`` returned by a previous list request.
+ :param iterator: Returns all data as iterator (generator) instead paginated result.
+ """
+ args = (
+ "GET",
+ f"{self.lockbox_base_url}/secrets/{secret_id}/versions",
+ )
+ kwargs = {
+ "headers": self.auth_headers,
+ "params": {"pageSize": page_size, "pageToken": page_token},
+ "response_model": SecretVersionsList,
+ "raise_for_status": raise_for_status,
+ }
+
+ if iterator:
+ print("IMA ITERATOR IMA ITERATOR IMA ITERATOR IMA ITERATOR")
+ return self._seekable_response(self.adapter.request, "versions", *args, **kwargs)
+
+ response = await self.adapter.request(*args, **kwargs)
+ self._inject_client_to_items(response.versions)
+ return response
+
+ async def schedule_secret_version_destruction(
+ self, secret_id: str, version_id: str, pending_period: int = 604800, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Schedules the specified version for destruction.
+ Scheduled destruction can be cancelled with the :func:`cancel_secret_version_destruction()` method.
+
+ :param secret_id: Secret indentifier.
+ :param version_id: ID of the version to be destroyed.
+ :param pending_period: Time interval in seconds between the version destruction request and actual destruction.
+ Default value: ``604800`` (i.e. 7 days).
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ if isinstance(pending_period, int):
+ if pending_period <= 0:
+ raise ValueError("The ``pending_period`` value must be greater than 0.")
+ # protobuf duration compat
+ # https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/duration.proto
+ pending_period = str(pending_period) + "s"
+ else:
+ raise ValueError("The ``pending_period`` value must be integer.")
+
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}:scheduleVersionDestruction"
+ payload = {"versionId": version_id, "pendingPeriod": pending_period}
+ response = await self.adapter.request(
+ "POST",
+ url,
+ headers=self.auth_headers,
+ json=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ # TODO: implement
+ async def set_secret_access_bindings(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+ async def update_secret(
+ self, secret_id: str, data: IUpdateSecret, raise_for_status: bool = True
+ ) -> Coroutine[Any, Any, Operation | YandexCloudError]:
+ """
+ Updates the specified secret.
+
+ :param secret_id: Secret identifier.
+ :param data: A new data for the secret as object.
+ Important. Field mask that specifies which attributes of the secret are going to be updated.
+ A comma-separated names off ALL fields to be updated. Only the specified fields will be changed.
+ The others will be left untouched. If the field is specified in updateMask and no value for
+ that field was sent in the request, the field's value will be reset to the default.
+ The default value for most fields is null or 0.
+ If ``updateMask`` is not sent in the request, all fields values will be updated.
+ Fields specified in the request will be updated to provided values. The rest of the fields will be reset to the default.
+ :param raise_for_status: If set to ``False`` returns :class:`YandexCloudError` instead throw exception.
+ Defaults to ``True``.
+ """
+ url = f"{self.lockbox_base_url}/secrets/{secret_id}"
+ payload = data.model_dump_json(by_alias=True)
+ response = await self.adapter.request(
+ "PATCH",
+ url,
+ headers=self.auth_headers,
+ data=payload,
+ response_model=Operation,
+ raise_for_status=raise_for_status,
+ )
+ response.inject_client(self)
+ return response
+
+ # TODO: implement
+ async def update_secret_access_bindings(self, *args, **kwargs):
+ """Not ready yet."""
+ raise NotImplementedError
+
+
+class YandexLockboxFacade: # pragma: no cover
"""
A facade for encapsulating the logic of synchronous and asynchronous client operations,
providing uniform methods.
"""
- def __init__(self) -> None:
- raise NotImplementedError # pragma: no cover
+ _client: AbstractYandexLockboxClient
+
+ def __init__(
+ self,
+ credentials,
+ *,
+ auth_client: Optional[Type[AbstractYandexAuthClient]] = YandexAuthClient,
+ lockbox_base_url: str | None = None,
+ payload_lockbox_base_url: str | None = None,
+ enable_async: bool = False,
+ ) -> None:
+ if enable_async:
+ self._client = AsyncYandexLockboxClient(
+ credentials,
+ auth_client=auth_client,
+ lockbox_base_url=lockbox_base_url,
+ payload_lockbox_base_url=payload_lockbox_base_url,
+ )
+ else:
+ self._client = YandexLockboxClient(
+ credentials,
+ auth_client=auth_client,
+ lockbox_base_url=lockbox_base_url,
+ payload_lockbox_base_url=payload_lockbox_base_url,
+ )
+
+ @property
+ def client(self) -> AbstractYandexLockboxClient:
+ """Returns initialized Lockbox client."""
+ return self._client
+
+ def __getattr__(self, name):
+ """Dynamically delegate method calls to the appropriate client."""
+
+ if name == "_client":
+ return self._client
+
+ if not hasattr(self._client, name):
+ raise AttributeError
+
+ return getattr(self._client, name)
-__all__ = ["AsyncYandexLockboxClient", "YandexLockboxClient", "YandexLockbox"]
+__all__ = ["AsyncYandexLockboxClient", "YandexLockboxClient", "YandexLockboxFacade"]
diff --git a/yc_lockbox/_models.py b/yc_lockbox/_models.py
index ca64317..b77fdce 100644
--- a/yc_lockbox/_models.py
+++ b/yc_lockbox/_models.py
@@ -1,11 +1,11 @@
import logging
-from typing import Any, Iterator, Union
+from typing import Any, AsyncGenerator, Iterator, Union
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, SecretStr, SecretBytes, computed_field
from yc_lockbox._constants import RpcError
from yc_lockbox._abc import AbstractYandexLockboxClient
-from yc_lockbox._types import T
+from yc_lockbox._types import T, SecretVersionsResponse
from yc_lockbox._exceptions import LockboxError
@@ -243,16 +243,30 @@ def delete(self, **kwargs) -> Union["Operation", "YandexCloudError"]:
self._raise_when_empty_client()
return self.client.delete_secret(self.id, **kwargs)
- def refresh(self, **kwargs) -> "Secret":
- """Shortcut for refresh attributes for this secret."""
- self._raise_when_empty_client()
+ async def _async_refresh(self, **kwargs) -> "Secret":
+ data = await self.client.get_secret(self.id, **kwargs)
+ self._update_attributes(data)
+ return self
+
+ def _sync_refresh(self, **kwargs) -> "Secret":
data = self.client.get_secret(self.id, **kwargs)
+ self._update_attributes(data)
+ return self
+ def _update_attributes(self, data) -> None:
+ """Method for update model attributes after refresh."""
for attr, value in data.model_dump().items():
- if value != getattr(self, attr):
+ if value != getattr(self, attr, None):
setattr(self, attr, value)
- return data
+ def refresh(self, **kwargs) -> "Secret":
+ """Shortcut for refresh attributes for this secret."""
+ self._raise_when_empty_client()
+
+ if hasattr(self.client, "enable_async") and self.client.enable_async:
+ return self._async_refresh(**kwargs)
+
+ return self._sync_refresh(**kwargs)
def payload(self, version_id: str | None = None, **kwargs) -> Union["Operation", "YandexCloudError"]:
self._raise_when_empty_client()
@@ -260,7 +274,7 @@ def payload(self, version_id: str | None = None, **kwargs) -> Union["Operation",
def list_versions(
self, page_size: int = 100, page_token: str | None = None, iterator: bool = False, **kwargs
- ) -> Union["SecretVersionsList", Iterator["SecretVersion"], "YandexCloudError"]:
+ ) -> SecretVersionsResponse:
"""Shortcut for list all available versions of the current secret."""
self._raise_when_empty_client()
return self.client.list_secret_versions(
diff --git a/yc_lockbox/_types.py b/yc_lockbox/_types.py
index 6c31d1d..9a4e873 100644
--- a/yc_lockbox/_types.py
+++ b/yc_lockbox/_types.py
@@ -1,11 +1,16 @@
-from typing import Any, Coroutine, TypeAlias, TypeVar, TYPE_CHECKING, Union
+from typing import Any, AsyncGenerator, Coroutine, Iterator, TypeAlias, TypeVar, TYPE_CHECKING, Union
from pydantic import BaseModel
if TYPE_CHECKING: # pragma: no cover
- from yc_lockbox._models import Operation, YandexCloudError
+ from yc_lockbox._models import Operation, SecretVersion, SecretVersionsList, YandexCloudError
T = TypeVar("T", bound=BaseModel)
YandexCloudGenericResponse: TypeAlias = (
- Coroutine[Any, Any, Union["Operation", "YandexCloudError"]] | Union["Operation", "YandexCloudError"]
+ Union["Operation", "YandexCloudError"] | Coroutine[Any, Any, Union["Operation", "YandexCloudError"]]
) # pragma: no cover
+
+
+SecretVersionsResponse = Union[
+ "SecretVersionsList", Iterator["SecretVersion"], AsyncGenerator[Any, "SecretVersion"], "YandexCloudError"
+] # pragma: no cover
Client#
+-
+
- +class yc_lockbox.YandexLockboxFacade(credentials, *, auth_client=<class 'yc_lockbox._auth.YandexAuthClient'>, lockbox_base_url=None, payload_lockbox_base_url=None, enable_async=False)[source]# +
Bases:
+object
A facade for encapsulating the logic of synchronous and asynchronous client operations, +providing uniform methods.
+-
+
- +property client: AbstractYandexLockboxClient# +
Returns initialized Lockbox client.
+
- class yc_lockbox.YandexLockboxClient(credentials, *, auth_client=<class 'yc_lockbox._auth.YandexAuthClient'>, adapter=<class 'yc_lockbox._adapters.HTTPAdapter'>, lockbox_base_url=None, payload_lockbox_base_url=None)[source]# @@ -533,6 +547,352 @@
Client#
-
+
- +class yc_lockbox.AsyncYandexLockboxClient(credentials, *, auth_client=<class 'yc_lockbox._auth.YandexAuthClient'>, adapter=<class 'yc_lockbox._adapters.AsyncHTTPAdapter'>, lockbox_base_url=None, payload_lockbox_base_url=None)[source]# +
Bases:
+AbstractYandexLockboxClient
Yandex Lockbox secrets vault client. +The same as
+YandexLockboxClient
but async.-
+
- Parameters: +
-
+
credentials – Credentials for authenticate requests. +Allowed types: service account key, OAuth token, IAM token.
+auth_client (
Optional
[Type
[AbstractYandexAuthClient
]]) – Optional client implementation for authenticate requests. +Defaults toYandexAuthClient
.
+adapter (
Optional
[Type
[AbstractHTTPAdapter
]]) – HTTP adapter for communicate with Yandex Cloud API.
+lockbox_base_url (
Optional
[str
]) – Lockbox base URL without resource path.
+payload_lockbox_base_url (
Optional
[str
]) – Lockbox payload base URL without resource path.
+auth_base_url – IAM base URL without resource path.
+
+
++Note
+All the values of the secrets are masked, i.e. looks like
+***********
. +To get the real value of the secret, you need to call the injected methods +reveal_text_value()
orreveal_binary_value()
.Usage:
+++from yc_lockbox import AsyncYandexLockboxClient, Secret + +lockbox = AsyncYandexLockboxClient("y0_AgAEXXXXXXXXXXXXXXXXXXXXXXXXX") # OAuth or IAM token + +secret: Secret = await lockbox.get_secret("e6xxxxxxxxxxxxxxxx") +print(secret.name, secret.status, secret.description) + +secret_versions = await secret.list_versions() +async for version in secret_versions: + print(version) + if version.id != secret.current_version.id: + await version.schedule_version_destruction() + +payload = await secret.payload() + +try: + value = payload["mykey"] + print(value.reveal_text_value()) +except KeyError: + print("Invalid key!") + +print(payload.get("foo")) # None if not exists without raising exception +entry = payload[0] # similar to payload.entries[0] +
Authenticate via service account key:
+++import json + +# generate json key for your SA +# yc iam key create --service-account-name my-sa --output key.json + +with open("./key.json", "r") as infile: + credentials = json.load(infile) + +lockbox = AsyncYandexLockboxClient(credentials) +
-
+
- +async activate_secret(secret_id, raise_for_status=True)[source]# +
Activates the specified secret.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret indentifier.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +async add_secret_version(secret_id, version, raise_for_status=True)[source]# +
Adds new version based on a previous one.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret indentifier.
+version (
INewSecretVersion
) – A new version object.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +property auth_headers: dict[str, str]# +
Returns headers for authenticate.
+
-
+
- +async cancel_secret_version_destruction(secret_id, version_id, raise_for_status=True)[source]# +
Cancels previously scheduled version destruction, if the version hasn’t been destroyed yet.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret indentifier.
+version_id (
str
) – Secret version id to cancel destruction.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +async create_secret(secret, raise_for_status=True)[source]# +
Creates a secret in the specified folder.
+-
+
- Parameters: +
-
+
secret (
INewSecret
) – A new secret object.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +async deactivate_secret(secret_id, raise_for_status=True)[source]# +
Deactivate a secret.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret indentifier.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +async delete_secret(secret_id, raise_for_status=True)[source]# +
Deletes the specified secret.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret indentifier.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +enable_async = True# +
-
+
- +async get_secret(secret_id, raise_for_status=True)[source]# +
Get lockbox secret by ID.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret identifier.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Secret
|YandexCloudError
]
+
-
+
- +async get_secret_payload(secret_id, version_id=None, raise_for_status=True)[source]# +
Get lockbox secret payload by ID and optional version.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret identifier.
+version_id (
Optional
[str
]) – Secret version. Optional.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,SecretPayload
|YandexCloudError
]
+
-
+
- +async list_secret_access_bindings(*args, **kwargs)[source]# +
Not ready yet.
+
-
+
- +async list_secret_operations(*args, **kwargs)[source]# +
Not ready yet.
+
-
+
- +async list_secret_versions(secret_id, page_size=100, page_token=None, raise_for_status=True, iterator=False)[source]# +
Retrieves the list of versions of the specified secret.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret identifier.
+page_size (
int
) – The maximum number of results per page to return. +If the number of available results is larger thanpage_size
, +the service returns anext_page_token
that can be used to get +the next page of results in subsequent list requests. +Default value:100
. +The maximum value is1000
.
+page_token (
Optional
[str
]) – Page token. To get the next page of results, setpage_token
+to thenext_page_token
returned by a previous list request.
+iterator (
bool
) – Returns all data as iterator (generator) instead paginated result.
+
+- Return type: +
+Union
[Coroutine
[Any
,Any
,SecretVersionsList
|YandexCloudError
],AsyncGenerator
[Any
,SecretVersion
]]
+
-
+
- +async list_secrets(folder_id, page_size=100, page_token=None, raise_for_status=True, iterator=False)[source]# +
Retrieves the list of secrets in the specified folder.
+-
+
- Parameters: +
-
+
folder_id (
str
) – ID of the folder to list secrets in.
+page_size (
int
) – The maximum number of results per page to return. +If the number of available results is larger thanpage_size
, +the service returns anext_page_token
that can be used to get +the next page of results in subsequent list requests. +Default value:100
. +The maximum value is1000
.
+page_token (
Optional
[str
]) – Page token. To get the next page of results, setpage_token
+to thenext_page_token
returned by a previous list request.
+iterator (
bool
) – Returns all data as iterator (generator) instead paginated result.
+
+- Return type: +
+Union
[Coroutine
[Any
,Any
,SecretsList
|YandexCloudError
],AsyncGenerator
[Any
,Secret
]]
+
-
+
- +async schedule_secret_version_destruction(secret_id, version_id, pending_period=604800, raise_for_status=True)[source]# +
Schedules the specified version for destruction. +Scheduled destruction can be cancelled with the
+cancel_secret_version_destruction()
method.-
+
- Parameters: +
-
+
secret_id (
str
) – Secret indentifier.
+version_id (
str
) – ID of the version to be destroyed.
+pending_period (
int
) – Time interval in seconds between the version destruction request and actual destruction. +Default value:604800
(i.e. 7 days).
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +async set_secret_access_bindings(*args, **kwargs)[source]# +
Not ready yet.
+
-
+
- +async update_secret(secret_id, data, raise_for_status=True)[source]# +
Updates the specified secret.
+-
+
- Parameters: +
-
+
secret_id (
str
) – Secret identifier.
+data (
IUpdateSecret
) – A new data for the secret as object. +Important. Field mask that specifies which attributes of the secret are going to be updated. +A comma-separated names off ALL fields to be updated. Only the specified fields will be changed. +The others will be left untouched. If the field is specified in updateMask and no value for +that field was sent in the request, the field’s value will be reset to the default. +The default value for most fields is null or 0. +IfupdateMask
is not sent in the request, all fields values will be updated. +Fields specified in the request will be updated to provided values. The rest of the fields will be reset to the default.
+raise_for_status (
bool
) – If set toFalse
returnsYandexCloudError
instead throw exception. +Defaults toTrue
.
+
+- Return type: +
+Coroutine
[Any
,Any
,Operation
|YandexCloudError
]
+
-
+
- +async update_secret_access_bindings(*args, **kwargs)[source]# +
Not ready yet.
+
- class yc_lockbox._auth.YandexAuthClient(credentials, *, auth_base_url=None, **kwargs)[source]# @@ -632,6 +992,10 @@
- Client +
AsyncYandexLockboxClient
-
+
AsyncYandexLockboxClient.activate_secret()
+AsyncYandexLockboxClient.add_secret_version()
+AsyncYandexLockboxClient.auth_headers
+AsyncYandexLockboxClient.cancel_secret_version_destruction()
+AsyncYandexLockboxClient.create_secret()
+AsyncYandexLockboxClient.deactivate_secret()
+AsyncYandexLockboxClient.delete_secret()
+AsyncYandexLockboxClient.enable_async
+AsyncYandexLockboxClient.get_secret()
+AsyncYandexLockboxClient.get_secret_payload()
+AsyncYandexLockboxClient.list_secret_access_bindings()
+AsyncYandexLockboxClient.list_secret_operations()
+AsyncYandexLockboxClient.list_secret_versions()
+AsyncYandexLockboxClient.list_secrets()
+AsyncYandexLockboxClient.schedule_secret_version_destruction()
+AsyncYandexLockboxClient.set_secret_access_bindings()
+AsyncYandexLockboxClient.update_secret()
+AsyncYandexLockboxClient.update_secret_access_bindings()
+
YandexAuthClient
YandexAuthClient.adapter
YandexAuthClient.get_iam_token()
@@ -668,7 +1053,7 @@ - Return type: -
+Union
[SecretVersionsList
,Iterator
[SecretVersion
],YandexCloudError
]Union
[SecretVersionsList
,Iterator
[SecretVersion
],AsyncGenerator
[Any
,SecretVersion
],YandexCloudError
]
Client# - + diff --git a/docs/pages/exceptions.html b/docs/pages/exceptions.html index fe8d6de..6e6ee71 100644 --- a/docs/pages/exceptions.html +++ b/docs/pages/exceptions.html @@ -251,7 +251,7 @@
Exceptions + diff --git a/docs/pages/models.html b/docs/pages/models.html index 616a05f..fe6e3e3 100644 --- a/docs/pages/models.html +++ b/docs/pages/models.html @@ -363,7 +363,7 @@
Domain models