Metadata-Version: 2.5
Name: xlambda-redis
Version: 0.2.0
Summary: xlambda managed Redis SDK: provisioning, sub-users, backups, and a get_client() convenience.
Project-URL: Homepage, https://xlambda.tech
Project-URL: Source, https://github.com/randyryan177-cloud/media-server/tree/main/packages-python/redis
Author: xlambda
License-Expression: MIT
Keywords: cache,redis,sdk,xlambda
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: xlambda-core==0.2.0
Provides-Extra: client
Requires-Dist: redis>=5.0; extra == 'client'
Description-Content-Type: text/markdown

# xlambda-redis

Managed Redis: provisioning, sub-users, backups, and a `get_client()`
convenience.

```
pip install xlambda-redis            # provisioning only
pip install "xlambda-redis[client]"  # plus redis-py, for get_client()
```

Python port of [`@xlambda-tech/redis`](../../packages/redis).

`xlambda.redis` and redis-py's top-level `redis` coexist without shadowing
each other — Python 3 imports are absolute, so importing one never resolves
to the other.

## Provisioning

```python
from xlambda.redis import RedisClient

client = RedisClient(api_key=os.environ["XLAMBDA_API_KEY"])

instance = client.instances.create(
    project_id="proj_123",
    name="cache",
    tier="starter",              # shared; 'pro'/'business' are dedicated
    persistence_mode="rdb",      # 'none' | 'rdb' | 'rdb_aof'
)
```

`create()`, `rotate_password()`, and `reveal_connection()` return a
`RedisInstanceHandle` — a plain `dict` subclass, so every response field reads
normally, with client constructors added on top:

```python
cache = instance.get_client()              # redis-py, blocking
cache.set("hello", "world")

acache = instance.get_async_client()       # redis.asyncio
await acache.set("hello", "world")
```

On shared-tier instances every key is namespaced behind `instance["keyPrefix"]`.

`reveal_connection()` discloses the *current* password rather than changing
it. It 404s for instances that predate the feature or were created without
`CONSOLE_CREDENTIAL_ENCRYPTION_KEY` configured — rotate to recover.

## Sub-users and backups

```python
user = client.instances.users(instance["id"]).create(permission="readonly")
user["password"]     # shown once

backups = client.instances.backups(instance["id"])
backups.create()
backups.restore("bkp_123")   # overwrites all current data; cannot be undone
```

## What this doesn't wrap

The dashboard's own command / EVAL / pub-sub browser. Running commands isn't
something the REST API mediates, so once an instance is provisioned you talk
to it with redis-py through the handle above. `get_client()` is a thin
ergonomic wrapper, not a reimplementation, and redis-py stays an optional
extra so provisioning-only callers don't install a driver they never use.

## Async

```python
from xlambda.redis import AsyncRedisClient

async with AsyncRedisClient(api_key=...) as client:
    instance = await client.instances.create(project_id="proj_123", name="cache", tier="starter")
```

Note the two axes are independent: `AsyncRedisClient` is about the
*provisioning* API, `get_async_client()` about talking to Redis itself. You
can mix them freely.

## Conventions

Arguments are snake_case; responses are the API's own camelCase, returned as
plain dicts typed by `TypedDict`. `memoryBytes` and backup `sizeBytes` are
bigints server-side and arrive as strings. See
[xlambda-core](../core#conventions).
