Files
sdk/python/blyss/bucket_service.py
Neil Movva fdb7206517 update python example (#32)
* update python basic example

* reduce test size to support small servers
2024-03-21 01:45:09 -07:00

141 lines
5.1 KiB
Python

from typing import Any, Optional, Union
from . import bucket, api, seed
BLYSS_BUCKET_URL = "https://alpha.api.blyss.dev"
DEFAULT_BUCKET_PARAMETERS = {
"maxItemSize": 1000,
"keyStoragePolicy": "none",
"version": 1,
}
ApiConfig = dict[str, str]
class BucketService:
"""A client to the hosted Blyss bucket service. Allows creation, deletion, and modification of buckets."""
def __init__(self, api_key: str, endpoint: str = BLYSS_BUCKET_URL):
"""Initialize a client of the Blyss bucket service.
Args:
api_key: A valid Blyss API key.
endpoint: A fully qualified endpoint URL for the bucket service, e.g. https://beta.api.blyss.dev.
"""
self._api = api.API(api_key, endpoint)
def connect(
self,
bucket_name: str,
secret_seed: Optional[str] = None,
) -> bucket.Bucket:
"""Connect to an existing Blyss bucket.
Args:
bucket_name: The name of the bucket to connect to.
secret_seed: An optional secret seed to derive the client secret,
which will be used to encrypt all client queries.
If not supplied, a random one is generated with `os.urandom`.
Returns:
An object representing a client to the Blyss bucket.
"""
if secret_seed is None:
secret_seed = seed.get_random_seed()
b = bucket.Bucket(self._api, bucket_name, secret_seed=secret_seed)
return b
@staticmethod
def _build_create_req(
bucket_name: str, open_access: bool, usage_hints: dict[str, Any]
) -> dict[str, Any]:
parameters = {**DEFAULT_BUCKET_PARAMETERS}
parameters.update(usage_hints)
bucket_create_req = {
"name": bucket_name,
"parameters": parameters,
"open_access": open_access,
}
return bucket_create_req
def create(
self,
bucket_name: str,
open_access: bool = False,
usage_hints: dict[str, Any] = {},
):
"""Create a new Blyss bucket.
Args:
bucket_name: Name of the new bucket. See [bucket naming rules](https://docs.blyss.dev/docs/buckets#names).
open_access: If True, bucket will support open read-only access, i.e. any user can perform reads. See [open access permissions](https://docs.blyss.dev/docs/buckets#permissions).
usage_hints: A dictionary of hints describing the intended usage of this bucket. Supported keys:
- "maxItemSize": The maximum size of any item in the bucket, in bytes.
A scheme will be chosen that can support at least this size, and possibly more.
Larger item sizes carry performance costs; expect longer query times and more bandwidth usage.
- "keyStoragePolicy": The key storage policy to use for this bucket. Options:
- "none" (default): Stores no key-related information. This is the most performant option and will maximize write speed.
- "bloom": Enables `Bucket.private_intersect()`. Uses a bloom filter to store probablistic information of key membership, with minimal impact on write speed.
"""
bucket_create_req = self._build_create_req(
bucket_name, open_access, usage_hints
)
self._api._blocking_create(bucket_create_req)
def exists(self, name: str) -> bool:
"""Check if a bucket exists.
Args:
name: Bucket name to look up.
Returns:
True if a bucket with the given name currently exists.
"""
return self._api._blocking_exists(name)
def list_buckets(self) -> dict[str, Any]:
"""List all buckets accessible to this API key.
Returns:
A dictionary of bucket metadata, keyed by bucket name.
"""
buckets = {}
for b in self._api._blocking_list_buckets()["buckets"]:
n = b.pop("name")
buckets[n] = b
return buckets
class BucketServiceAsync(BucketService):
async def create(
self,
bucket_name: str,
open_access: bool = False,
usage_hints: dict[str, Any] = {},
):
bucket_create_req = self._build_create_req(
bucket_name, open_access, usage_hints
)
await self._api.create(bucket_create_req)
async def connect(
self,
bucket_name: str,
secret_seed: Optional[str] = None,
) -> bucket.AsyncBucket:
"""Returns an asynchronous client to the Blyss bucket. Identical functionality to `BucketService.connect`."""
b = bucket.AsyncBucket(self._api, bucket_name, secret_seed=secret_seed)
await b.async_init()
return b
async def exists(self, name: str) -> bool:
return await self._api.exists(name)
async def list_buckets(self) -> dict[str, Any]:
buckets = {}
for b in (await self._api.list_buckets())["buckets"]:
n = b.pop("name")
buckets[n] = b
return buckets