Stash Python Client
Python client library for Stash - a simple key-value configuration service.
Installation
pip install stash-client
Or with uv:
uv add stash-client
For local development:
cd lib/stash-python
uv sync --all-extras
Quick Start
from stash import Client
# basic usage
client = Client("http://localhost:8080")
client.set("app/config", '{"debug": true}', fmt="json")
value = client.get("app/config")
print(value) # {"debug": true}
# with authentication
client = Client("http://localhost:8080", token="your-api-token")
# with zero-knowledge encryption
client = Client(
"http://localhost:8080",
zk_key="your-secret-passphrase-min-16-chars"
)
# values are encrypted client-side before sending to server
client.set("secrets/api-key", "sk-secret-value")
# automatically decrypted on retrieval
value = client.get("secrets/api-key") # "sk-secret-value"
Context Manager
from stash import Client
with Client("http://localhost:8080", zk_key="passphrase-min-16") as client:
client.set("key", "value")
value = client.get("key")
# passphrase is cleared from memory on exit
Dict-like Access
client = Client("http://localhost:8080")
# set
client["app/config"] = "value"
# get
value = client["app/config"]
# delete
del client["app/config"]
# check existence
if "app/config" in client:
print("exists")
API Reference
Client
Client(
base_url: str,
token: str | None = None,
timeout: float = 30.0,
retries: int = 3,
zk_key: str | None = None
)
Parameters:
base_url: Stash server URLtoken: Bearer token for authenticationtimeout: Request timeout in secondsretries: Number of retry attempts for failed requestszk_key: Passphrase for zero-knowledge encryption (min 16 chars)
Methods
| Method | Description |
|---|---|
get(key: str) -> str |
Get value as string |
get_bytes(key: str) -> bytes |
Get value as bytes |
get_or_default(key: str, default: str) -> str |
Get value or return default |
set(key: str, value: str, fmt: str = "text") |
Set value with format |
delete(key: str) |
Delete key |
list(prefix: str = "") -> list[KeyInfo] |
List keys with optional prefix filter |
info(key: str) -> KeyInfo |
Get key metadata |
ping() -> None |
Check server connectivity |
close() -> None |
Clear ZK passphrase from memory |
subscribe(key: str) -> Subscription |
Subscribe to exact key changes |
subscribe_prefix(prefix: str) -> Subscription |
Subscribe to prefix changes |
subscribe_all() -> Subscription |
Subscribe to all key changes |
Subscriptions
Real-time key change notifications via Server-Sent Events:
from stash import Client
client = Client("http://localhost:8080", token="your-token")
# subscribe to exact key
with client.subscribe("app/config") as sub:
for event in sub:
print(f"{event.action}: {event.key} at {event.timestamp}")
# subscribe to prefix (all keys under app/)
with client.subscribe_prefix("app") as sub:
for event in sub:
print(f"{event.action}: {event.key}")
# subscribe to all keys
with client.subscribe_all() as sub:
for event in sub:
print(f"{event.action}: {event.key}")
SubscriptionEvent:
key: The key that changedaction:create,update, ordeletetimestamp: RFC3339 timestamp
Subscriptions automatically reconnect on connection failure with exponential backoff (1s initial, 30s max).
KeyInfo
@dataclass
class KeyInfo:
key: str
size: int
format: str
secret: bool
zk_encrypted: bool
created_at: datetime
updated_at: datetime
Errors
from stash import (
StashError, # base exception
NotFoundError, # key not found (404)
UnauthorizedError, # unauthorized (401)
ForbiddenError, # forbidden (403)
DecryptionError, # ZK decryption failed
ConnectionError, # connection failed
)
Zero-Knowledge Encryption
When zk_key is provided, all values are encrypted client-side using AES-256-GCM with Argon2id key derivation. The server only stores encrypted data and cannot decrypt it.
Encryption parameters (compatible with Go client):
- Algorithm: AES-256-GCM
- Key derivation: Argon2id (time=1, memory=64MB, parallelism=4)
- Encrypted format:
$ZK$<base64(salt || nonce || ciphertext || tag)>
Development
# install dev dependencies
uv sync --all-extras
# run tests
uv run pytest
# run tests with coverage
uv run pytest --cov
# run linter
uv run ruff check .
# format code
uv run ruff format .
License
MIT License - see the main Stash repository for details.
Metadata
Release files for stash-client 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| stash_client-0.2.0.tar.gz | 14.0 kB | With provenance | Details for stash_client-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| stash_client-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for stash_client-0.2.0-py3-none-any.whl |
Total release size: 24.3 kB
Release files / stash_client-0.2.0.tar.gz
| Download URL | stash_client-0.2.0.tar.gz |
|---|---|
| Size | 14.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a6df6a28e0e62649c4a7b31bd3dafe7dfe330c5f47a59ee209a2ee7b4f2be444
|
|
BLAKE2b-256 checksum How to use checksums |
33c4f954bba3a3ca51983027ac0de414599916cea7d10517ec912111220037a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 4, 2026.
Transparency logRelease files / stash_client-0.2.0-py3-none-any.whl
| Download URL | stash_client-0.2.0-py3-none-any.whl |
|---|---|
| Size | 10.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2d84b42370ae32288b4018a5e6246e0b1c223f4b02e72f0f600a8570984be7b4
|
|
BLAKE2b-256 checksum How to use checksums |
187049a0572972dca38ad5e0192e9d81e41023e4b96557961f60c550ad875aa6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 4, 2026.
Transparency logSecurity for stash-client 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for stash_client-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 4, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.