.. core-redis documentation master file, created by sphinx-quickstart on Tue May 6 23:11:45 2025. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. core-redis =============================================================================== This project/library contains common elements related to Redis integration. =============================================================================== .. image:: https://img.shields.io/pypi/pyversions/core-redis.svg :target: https://pypi.org/project/core-redis/ :alt: Python Versions .. image:: https://img.shields.io/badge/license-MIT-blue.svg :target: https://gitlab.com/bytecode-solutions/core/core-redis/-/blob/main/LICENSE :alt: License .. image:: https://gitlab.com/bytecode-solutions/core/core-redis/badges/release/pipeline.svg :target: https://gitlab.com/bytecode-solutions/core/core-redis/-/pipelines :alt: Pipeline Status .. image:: https://readthedocs.org/projects/core-redis/badge/?version=latest :target: https://readthedocs.org/projects/core-redis/ :alt: Docs Status .. image:: https://img.shields.io/badge/security-bandit-yellow.svg :target: https://github.com/PyCQA/bandit :alt: Security Features ------------------------------------------------------------------------------- - ``RedisClient``: thin connection wrapper that decouples the ecosystem from the underlying ``redis`` library. - ``cache_redis_based``: write-through caching decorator backed by Redis (L2) with an in-memory LRU as L1. - ``FixedWindow``: fixed-window rate limiter backed by Redis. - ``SlidingWindowLog``: sliding-window log rate limiter backed by Redis; eliminates the burst problem at the cost of per-request sorted-set writes. - ``TokenBucket``: token-bucket rate limiter backed by Redis; supports bursts up to bucket capacity while enforcing a smooth long-term refill rate. - ``LeakyBucket``: leaky-bucket rate limiter backed by Redis; enforces a strictly constant output rate by queuing requests and draining at a fixed leak rate. RedisClient ------------------------------------------------------------------------------- ``RedisClient`` abstracts the ``redis`` library so the rest of the ecosystem never imports it directly. The connection is created lazily on first use and is thread-safe. .. code-block:: python from core_redis import RedisClient client = RedisClient(host="localhost", port=6379, db=0) client.set("key", b"value", ex=60) # store with 60 s TTL data = client.get("key") # b"value" or None count = client.delete("key") # 1 n = client.exists("key", "other") # 0–N alive = client.ping() # True Additional keyword arguments are forwarded verbatim to ``redis.Redis`` (e.g. ``ssl=True``, ``socket_timeout=5``). Decorators ------------------------------------------------------------------------------- Reusable decorators that add cross-cutting behaviour (caching, retries, …) to any callable. These are framework-agnostic and work with plain functions, ETL methods, or any other callable. .. note:: **Serialization format (pickle)** Cached values are serialized with Python's :mod:`pickle` module. Bandit flags ``pickle`` by default (rules B403 and B301) because deserializing data from an *untrusted* source can execute arbitrary code. That risk does not apply here: the only data ever passed to ``pickle.loads()`` is data that *this library* previously wrote with ``pickle.dumps()``. There is no user-controlled input anywhere in the deserialization path, so the Bandit warnings are suppressed with ``# nosec B403`` / ``# nosec B301``. **Do not point these decorators at Redis keys that are writable by untrusted parties.** cache_redis_based ^^^^^^^^^^^^^^^^^ Write-through caching decorator: L1 is a bounded in-memory LRU; L2 is Redis. TTL is handled natively by Redis (``SET … EX``), so no background threads or manual expiry are needed. .. code-block:: python from core_redis.decorators import cache_redis_based @cache_redis_based( key_prefix="myapp/", ttl=3600, redis_kwargs={"host": "localhost", "port": 6379}, ) def fetch_reference_data(dataset: str) -> dict: ... Rate Limiters ------------------------------------------------------------------------------- Four algorithms are available in ``core_redis.rate_limits``: ``FixedWindow``, ``SlidingWindowLog``, ``TokenBucket``, and ``LeakyBucket``. Each one is backed by Redis and accepts an ``identifier`` string (user ID, IP address, API key, etc.) on every call. .. toctree:: :maxdepth: 2 rate_limits Local Redis with Docker ------------------------------------------------------------------------------- Start a Redis server on the default port: .. code-block:: bash docker run -d --name redis-local -p 6379:6379 redis:latest Stop and remove it when done: .. code-block:: bash docker stop redis-local && docker rm redis-local Installation ------------------------------------------------------------------------------- .. code-block:: bash pip install core-redis uv pip install core-redis # or using UV pip install -e ".[dev]" # for development Setting Up for Development ------------------------------------------------------------------------------- .. code-block:: bash pip install --upgrade pip pip install virtualenv virtualenv --python=python3.12 .venv source .venv/bin/activate pip install -e ".[dev]" Running Tests ------------------------------------------------------------------------------- .. code-block:: shell python manager.py run-tests # unit tests python manager.py run-tests --test-type integration python manager.py run-coverage # unit + coverage Functional tests require a running Redis server (see `Local Redis with Docker`_): .. code-block:: shell # defaults: REDIS_HOST=localhost REDIS_PORT=6379 REDIS_DB=15 python manager.py run-tests --test-type functional --pattern "*.py" Contributing ------------------------------------------------------------------------------- Contributions are welcome! Please: 1. Fork the repository 2. Create a feature branch 3. Write tests for new functionality 4. Ensure all tests pass: ``python manager.py run-tests`` 5. Run linting: ``pylint core_redis`` 6. Run security checks: ``bandit -r core_redis`` 7. Submit a pull request License ------------------------------------------------------------------------------- This project is licensed under the MIT License. See the LICENSE file for details. Links ------------------------------------------------------------------------------- * **Documentation:** https://core-redis.readthedocs.io/en/latest/ * **Repository:** https://gitlab.com/bytecode-solutions/core/core-redis * **Issues:** https://gitlab.com/bytecode-solutions/core/core-redis/-/issues * **Changelog:** https://gitlab.com/bytecode-solutions/core/core-redis/-/blob/master/CHANGELOG.md * **PyPI:** https://pypi.org/project/core-redis/ Support ------------------------------------------------------------------------------- For questions or support, please open an issue on GitLab or contact the maintainers. Authors ------------------------------------------------------------------------------- * **Alejandro Cora González** - *Initial work* - alek.cora.glez@gmail.com