diff --git a/CHANGELOG.md b/CHANGELOG.md index 71defe1..dc98945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to CryptoServe will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [SDK 1.4.3] - 2026-03-18 + +### Fixed +- CryptoClient and AsyncCryptoClient now accept `base_url` as keyword alias for `server_url` for backwards compatibility +- Clarified easy.py encrypt/decrypt docstrings to state these are offline password-based functions, not server-connected operations with crypto contexts + +--- + ## [CLI 0.3.4] - 2026-03-17 ### Added diff --git a/sdk/python/cryptoserve/__init__.py b/sdk/python/cryptoserve/__init__.py index 94fc987..fef5e2c 100644 --- a/sdk/python/cryptoserve/__init__.py +++ b/sdk/python/cryptoserve/__init__.py @@ -64,7 +64,7 @@ STREAMING = Usage.STREAMING DISK = Usage.DISK -__version__ = "1.4.2" +__version__ = "1.4.3" __all__ = [ # Main SDK class "CryptoServe", diff --git a/sdk/python/packages/cryptoserve-client/cryptoserve_client/async_client.py b/sdk/python/packages/cryptoserve-client/cryptoserve_client/async_client.py index a8dd980..6d0ffb6 100644 --- a/sdk/python/packages/cryptoserve-client/cryptoserve_client/async_client.py +++ b/sdk/python/packages/cryptoserve-client/cryptoserve_client/async_client.py @@ -33,21 +33,27 @@ class AsyncCryptoClient: def __init__( self, - server_url: str, - token: str, + server_url: str | None = None, + token: str = "", timeout: float = 30.0, user_agent: str | None = None, + *, + base_url: str | None = None, ): """ Initialize the async client. Args: - server_url: Base URL of the CryptoServe server + server_url: Base URL of the CryptoServe server (also accepts ``base_url`` as alias) token: Identity token for authentication timeout: Request timeout in seconds user_agent: Custom user agent string + base_url: Alias for ``server_url`` (keyword-only, for backwards compatibility) """ - self.server_url = server_url.rstrip("/") + url = server_url or base_url + if url is None: + raise TypeError("AsyncCryptoClient requires 'server_url' (or 'base_url') argument") + self.server_url = url.rstrip("/") self.token = token self.timeout = timeout diff --git a/sdk/python/packages/cryptoserve-client/cryptoserve_client/client.py b/sdk/python/packages/cryptoserve-client/cryptoserve_client/client.py index 6f3f46e..bf7aa2b 100644 --- a/sdk/python/packages/cryptoserve-client/cryptoserve_client/client.py +++ b/sdk/python/packages/cryptoserve-client/cryptoserve_client/client.py @@ -61,8 +61,8 @@ class CryptoClient: def __init__( self, - server_url: str, - token: str, + server_url: str | None = None, + token: str = "", refresh_token: Optional[str] = None, auto_refresh: bool = True, timeout: float = 30.0, @@ -70,12 +70,14 @@ def __init__( retry_config: RetryConfig | None = None, circuit_config: CircuitBreakerConfig | None = None, enable_resilience: bool = False, + *, + base_url: str | None = None, ): """ Initialize the client. Args: - server_url: CryptoServe server URL + server_url: CryptoServe server URL (also accepts ``base_url`` as alias) token: Access token for API calls refresh_token: Optional refresh token for auto-refresh auto_refresh: Enable automatic token refresh (default: True) @@ -84,8 +86,12 @@ def __init__( retry_config: Retry configuration (None to use defaults when enabled) circuit_config: Circuit breaker configuration (None to use defaults when enabled) enable_resilience: Enable retry and circuit breaker with production defaults + base_url: Alias for ``server_url`` (keyword-only, for backwards compatibility) """ - self.server_url = server_url.rstrip("/") + url = server_url or base_url + if url is None: + raise TypeError("CryptoClient requires 'server_url' (or 'base_url') argument") + self.server_url = url.rstrip("/") self._access_token = token self._refresh_token = refresh_token self._auto_refresh = auto_refresh and refresh_token is not None diff --git a/sdk/python/packages/cryptoserve-core/cryptoserve_core/easy.py b/sdk/python/packages/cryptoserve-core/cryptoserve_core/easy.py index 2ac1e84..e9f94ac 100644 --- a/sdk/python/packages/cryptoserve-core/cryptoserve_core/easy.py +++ b/sdk/python/packages/cryptoserve-core/cryptoserve_core/easy.py @@ -38,7 +38,12 @@ class EasyEncryptionError(CipherError): def encrypt(plaintext: Union[bytes, str], password: str) -> bytes: """ - Encrypt data with a password. + Encrypt data with a password (offline, no server required). + + This is a standalone password-based encryption function that runs entirely + locally. It does not use server-managed keys or crypto contexts. For + server-connected encryption with context-based key management, use + :meth:`CryptoClient.encrypt` from ``cryptoserve-client`` instead. Uses PBKDF2 key derivation (600K iterations) and AES-256-GCM. Each call generates a fresh random salt and nonce. @@ -71,7 +76,12 @@ def encrypt(plaintext: Union[bytes, str], password: str) -> bytes: def decrypt(ciphertext: bytes, password: str) -> bytes: """ - Decrypt data encrypted with encrypt(). + Decrypt data encrypted with encrypt() (offline, no server required). + + This is a standalone password-based decryption function that runs entirely + locally. It does not use server-managed keys or crypto contexts. For + server-connected decryption, use :meth:`CryptoClient.decrypt` from + ``cryptoserve-client`` instead. Args: ciphertext: Encrypted blob from encrypt(). diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 288d4a0..0aedaea 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "cryptoserve" -version = "1.4.2" +version = "1.4.3" description = "CryptoServe SDK - Zero-config cryptographic operations with auto-registration and local key caching" readme = "README.md" license = {text = "Apache-2.0"}