Metadata-Version: 2.3
Name: aiorediscache
Version: 4.1.0
Summary: Async библиотека для работы с Redis структурами и декоратор кэширования
Author: Your Company
Requires-Python: >=3.11,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: redis (>=5.0.0,<6.0.0)
Description-Content-Type: text/markdown

# rediscache 4.0.0

Async библиотека для работы с Redis структурами (хеши, списки, rate limiting).

Оптимизирована для работы с `red_mng` (async Redis manager).

## Установка

```bash
# Из локальной директории
cd /Users/aleks/Libraryies/rediscache-4.0.0
pip install -e .

# Или через poetry
poetry add rediscache@file:///Users/aleks/Libraryies/rediscache-4.0.0
```

## Возможности

- ✅ **HashCache** - работа с хешами Redis (HSET, HGETALL, HGET)
- ✅ **ListCache** - работа со списками Redis (RPUSH, LRANGE, TTL)
- ✅ **RateLimiter** - rate limiting через SET NX
- ✅ **CacheUtils** - утилиты (удаление по префиксам, проверка существования)
- ✅ Async/await
- ✅ Поддержка RedisRouter для построения ключей
- ✅ Логирование через LoggerMixin

## Использование

### 1. Инициализация Redis

```python
import red_mng
from config_fastapi import Config

# Регистрация подключения
redis_cfg = Config().extract("redis")
red_mng.register(
    alias=redis_cfg.get("alias"),
    **redis_cfg.extract("connection").to_dict()
)
```

### 2. HashCache - работа с хешами

```python
import red_mng
from rediscache import HashCache
from your_project.redis import RedisRouter
from your_project.constants import PREFIX

redis = red_mng.get("default")
router = RedisRouter()
cache = HashCache(redis, router)

# Сохранить хеш
await cache.save(
    PREFIX.TICK,
    "BTCUSDT",
    "binance",
    data={"price": 50000, "volume": 1000}
)

# Получить хеш
data = await cache.get(PREFIX.TICK, "BTCUSDT", "binance")

# Найти все цены для символа
prices = await cache.find_field_by_pattern(
    PREFIX.TICK,
    "BTCUSDT",
    "*",
    field="price",
    key_field="exchange",
    decoder=lambda x: float(x.decode())
)
# → {"binance": 50000.0, "bybit": 50100.0}
```

### 3. ListCache - работа со списками

```python
from rediscache import ListCache

list_cache = ListCache(redis, router)

# Добавить элемент с TTL
await list_cache.append(
    PREFIX.OBSERVATION,
    "BTCUSDT",
    value=timestamp,
    ttl=3600
)

# Получить все элементы
observations = await list_cache.get(
    PREFIX.OBSERVATION,
    "BTCUSDT",
    decoder=lambda x: float(x.decode())
)
```

### 4. RateLimiter - rate limiting

```python
from rediscache import RateLimiter

limiter = RateLimiter(redis, router)

# Проверить, можно ли выполнить действие
if await limiter.can_proceed(PREFIX.NOTIFY, "telegram", "BTCUSDT", ttl=60):
    await send_notification()
    # Следующий вызов в течение 60 секунд вернет False
```

### 5. Использование в контроллерах (рекомендуемый паттерн)

```python
import red_mng as redis_manager
import rediscache
from config_fastapi import Config

from .baseclasses import BaseControl
from .redis import RedisRouter

class ArbitrageControl(BaseControl):
    """Контроллер для поиска арбитражных возможностей"""

    config = Config(section="redis")

    def __init__(self):
        # Паттерн как в jobs: router + redis + cache
        self.router = RedisRouter()
        self.redis = redis_manager.get(self.config.get("alias"))
        self.cache = rediscache.get(self.config.get("alias"))

    async def arbitrage(self, tick: Tick) -> Tick | None:
        # Высокоуровневые операции через cache
        prices = await self.cache.hash.find_field_by_pattern(
            PREFIX.TICK, tick.symbol, "*",
            field="price",
            key_field="exchange",
            decoder=lambda x: float(x.decode())
        )

        # Можно использовать router напрямую для построения ключей
        key = self.router.url_for(PREFIX.TICK, tick.symbol, "binance")

        # Можно использовать redis напрямую для низкоуровневых операций
        data = await self.redis.hgetall(key)

        return tick
```

## API Reference

### HashCache

**Методы:**
- `save(prefix, *keys, data)` - сохранить хеш
- `get(prefix, *keys)` - получить хеш целиком
- `get_field(prefix, *keys, field)` - получить одно поле
- `find_by_pattern(prefix, *keys)` - найти все хеши по паттерну
- `find_field_by_pattern(prefix, *keys, field, key_field, decoder)` - найти значения поля
- `check_field(prefix, *keys, field, expected)` - проверить значение поля
- `delete_by_pattern(prefix, *keys)` - удалить ключи по паттерну

### ListCache

**Методы:**
- `append(prefix, *keys, value, ttl)` - добавить в конец списка
- `prepend(prefix, *keys, value, ttl)` - добавить в начало списка
- `get(prefix, *keys, start, end, decoder)` - получить элементы
- `length(prefix, *keys)` - получить длину списка
- `delete(prefix, *keys)` - удалить список

### RateLimiter

**Методы:**
- `can_proceed(prefix, *keys, ttl, value)` - проверить rate limit
- `reset(prefix, *keys)` - сбросить rate limit

### CacheUtils

**Методы:**
- `delete_by_prefixes(*prefixes)` - удалить все ключи по префиксам
- `exists(prefix, *keys)` - проверить существование ключа
- `set_ttl(prefix, *keys, ttl)` - установить TTL

## Требования

- Python ≥ 3.11
- redis ≥ 5.0.0
- red_mng (async Redis manager)
- RedisRouter с методом `url_for(prefix, *keys)`

## Отличия от rediscache-3.0.0

- ❌ Убраны sync декораторы `@cached` и `@acached` (не работают с async)
- ✅ Добавлены async классы для работы с Redis структурами
- ✅ Полная поддержка async/await
- ✅ Оптимизировано для работы с red_mng

## Лицензия

Proprietary - для внутреннего использования компании.
