Metadata-Version: 2.4
Name: redis_memory
Version: 0.4.3
Summary: An object that persists in Redis. Works across instances and works seamlessly through magic functions.
Author-email: Sinan Ozel <coding@sinan.slmail.me>
License: MIT License
        
        Copyright (c) 2025 Sinan Ozel
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/sinan-ozel/redis-memory
Project-URL: Issues, https://github.com/sinan-ozel/redis-memory/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: redis>=6.1.0
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-cov>=3.0.0; extra == "test"
Requires-Dist: pytest-depends>=1.0.1; extra == "test"
Requires-Dist: pytest-mock>=3.14.0; extra == "test"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
Provides-Extra: dev
Requires-Dist: isort>=5.12.0; extra == "dev"
Requires-Dist: ruff>=0.12.11; extra == "dev"
Requires-Dist: black>=24.0.0; extra == "dev"
Requires-Dist: docformatter>=1.7.5; extra == "dev"
Provides-Extra: publish
Requires-Dist: packaging>=25.0; extra == "publish"
Dynamic: license-file

![Tests & Lint](https://github.com/sinan-ozel/redis-memory/actions/workflows/ci.yaml/badge.svg?branch=main)
![PyPI](https://img.shields.io/pypi/v/redis-memory.svg)
![Downloads](https://static.pepy.tech/badge/redis-memory)
![Monthly Downloads](https://static.pepy.tech/badge/redis-memory/month)
![License](https://img.shields.io/github/license/sinan-ozel/redis-memory.svg)
[![Documentation](https://img.shields.io/badge/docs-github--pages-blue)](https://sinan-ozel.github.io/redis-memory/)


# 🗄️ redis-memory

> **⚠️ This repository is no longer maintained.**
>
> Development continues at **[synced-memory](https://github.com/sinan-ozel/synced-memory)**, which supports multiple backends, currently both Redis and DragonflyDB.
>
> - PyPI: <https://pypi.org/project/synced-memory/>
> - GitHub: <https://github.com/sinan-ozel/synced-memory>
> - Docs: <https://sinan-ozel.github.io/synced-memory/latest/>
>
> Please migrate to `synced-memory` for continued updates and support.

A production-ready Python class for seamless, multiprocessing-safe, persistent key-value storage
using Redis as a backend. If Redis is unavailable, values are cached locally
and queued for syncing when Redis comes back online. All values are serialized
as JSON, and you interact with it using natural Python attribute access.

# Purpose

The intention is to use this with agentic workflows deployed as microservices,
allowing for multiple instances of the same pod to share their state.


## ✨ Features

- 🔄 **Multiprocessing-safe**: All processes share the same state via Redis.
- 🧠 **Pythonic API**: Set and get attributes as if they were regular object properties.
- 🕰️ **Persistence**: Values survive process restarts and context blocks.
- 🚦 **Resilient**: If Redis is down, changes are queued and flushed when it returns.
- 🧩 **Customizable**: Prefixes and conversation IDs for namespacing.
- 🧵 **Background sync**: Queued changes are flushed automatically in the background.

## 🚀 Quickstart

```bash
pip install redis-memory
```


```python
from redis_memory import Memory

mem = Memory()
mem.answer = 42
print(mem.answer)  # 42

# Across processes or instances:
mem2 = Memory()
print(mem2.answer)  # 42

mem.settings = {"theme": "dark", "volume": 0.75}
print(mem.settings)  # {'theme': 'dark', 'volume': 0.75}
```

## 🧑‍💻 Context Management

You can use `Memory` as a context manager for automatic resource handling:

```python
with Memory() as memory:
    memory.session = "active"
    print(memory.session)  # "active"

# Later, in a new context:
with Memory() as memory:
    print(memory.session)  # "active"
```

## � Auto-Synced Collections

Lists and dictionaries are automatically wrapped as `SyncedList` and `SyncedDict`, which sync changes to Redis immediately:

```python
mem = Memory()
mem.items = [1, 2, 3]
mem.items.append(4)  # Automatically syncs to Redis

mem2 = Memory()
print(mem2.items)  # [1, 2, 3, 4]

mem.config = {"theme": "dark"}
mem.config["lang"] = "en"  # Automatically syncs to Redis
print(mem2.config)  # {'theme': 'dark', 'lang': 'en'}
```

**Nested structures** work too:
```python
mem.data = {"user": {"preferences": {"color": "blue"}}}
mem.data["user"]["preferences"]["color"] = "red"  # Syncs!
```

### Converting to Plain Python Types

For libraries that need plain Python objects (serialization, pickling, etc.):

```python
mem.items = [1, 2, 3]
plain_list = mem.items.aslist()  # Returns regular list

mem.config = {"key": "value"}
plain_dict = mem.config.asdict()  # Returns regular dict

# Now you can pickle, deepcopy, or pass to external libraries
import pickle
pickle.dump(plain_list, file)  # Works!
```

## 🗂️ Namespacing

By default, `redis-memory` uses `memory:` as its Redis prefix.

Set that with `REDIS_PREFIX`:
```.env
REDIS_PREFIX="my_service_state:"
```

```python
from redis_memory import Memory

mem = Memory()
mem.state = {"step": 1}
print(mem.state)  # {'step': 1}
```

## Agents

Use the specific class `ConversationMemory` as an agent memory:

```python
# TODO: Expand with a real conversation object and/or LiteLLM

from redis_memory import ConversationMemory

conversation_id = uuid()

mem = ConversationMemory(conversation_id=conversation_id)
mem.messages = messages  # The messages payload to an LLM.
```

## ⚙️ Environment Variables

- `REDIS_HOST`: Redis server hostname (default: `redis`)
- `REDIS_PORT`: Redis server port (default: `6379`)
- `REDIS_PREFIX`: Key prefix (default: `memory:`)

## 🛠️ Development

### 🐳 Docker/Devcontainer

- Clone the repo.
- You can use [VS Code Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) for an instant dev environment.
- Or, just run tests in Docker—no setup needed!

### 🧪 Running Tests

**With a Development Container**: Open in VS Code, and start the development
container. You do not need to install anything other than VS Code and docker.
(Shift/Cmd + P and check under ``Dev Containers'')

Run the two VS code tasks, test and reformat, before making a PR. These are
the same as the tests that will run on the CI/CD pipeline.

**Without Anything**: Just write the code, and add your unit tests.
(Test-Driven Development)
Run the following command:
```bash
docker-compose up --build --remove-orphans --force-recreate --abort-on-container-exit --exit-code-from test
```

The only requirement is `docker`.

**Virtual Env**: I did not add support for the Python `venv`. However, all of
the requirements are captured in pyproject.toml. You _should_ be able to use the
following commands to set up a venv with all of the requirements.

```bash
python -m venv .venv
source .venv/bin/activate       # macOS/Linux
.venv\Scripts\activate          # Windows

pip install --upgrade pip
pip install .
pip install .[test]
pip install .[dev]
```


### 🤝 Contributing

- PRs are welcome! No special permissions required.
- All you need is Docker (or a devcontainer).
- Please ensure all tests pass before submitting your PR.

## 📚 License

MIT

---

Made with ❤️ and Redis.
