{"id":51544977,"url":"https://github.com/robertolima-dev/rust-py-cache","last_synced_at":"2026-07-09T17:01:54.421Z","repository":{"id":366584840,"uuid":"1276902797","full_name":"robertolima-dev/rust-py-cache","owner":"robertolima-dev","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-22T12:37:15.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T14:09:48.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robertolima-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-22T11:57:40.000Z","updated_at":"2026-06-22T12:37:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/robertolima-dev/rust-py-cache","commit_stats":null,"previous_names":["robertolima-dev/rust-py-cache"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/robertolima-dev/rust-py-cache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust-py-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust-py-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust-py-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust-py-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robertolima-dev","download_url":"https://codeload.github.com/robertolima-dev/rust-py-cache/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertolima-dev%2Frust-py-cache/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35306717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-09T17:01:51.977Z","updated_at":"2026-07-09T17:01:54.416Z","avatar_url":"https://github.com/robertolima-dev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rust-py-cache\n\n\u003e **An ultra-fast local cache for Python, powered by Rust.**\n\nA local, in-memory, thread-safe cache with TTL, lazy expiration, and metrics. The\ncore is written in Rust (PyO3 + maturin) on top of a concurrent `DashMap`; the\nPython API is minimal. Think of it as a \"mini Redis\" living **inside** your Python\nprocess.\n\n[![PyPI](https://img.shields.io/pypi/v/rust-py-cache)](https://pypi.org/project/rust-py-cache/)\n[![Python](https://img.shields.io/pypi/pyversions/rust-py-cache)](https://pypi.org/project/rust-py-cache/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow)](./LICENSE)\n\n🌐 **Website:** [rust-py-cache.vercel.app](https://rust-py-cache.vercel.app/)\n\n## Installation\n\n```bash\npip install rust-py-cache\n```\n\nTo work on it locally (requires Rust + maturin):\n\n```bash\npython -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install maturin pytest\nmaturin develop          # compiles the Rust core and installs into the venv\npytest                   # runs the tests\n```\n\n## Usage\n\n```python\nfrom rust_py_cache import Cache\n\ncache = Cache()\n\ncache.set(\"user:1\", {\"name\": \"Roberto\"}, ttl=60)   # ttl in seconds\nuser = cache.get(\"user:1\")                          # {\"name\": \"Roberto\"}\ncache.get(\"missing\", default=0)                     # 0\n\ncache.exists(\"user:1\")        # True (honors TTL)\ncache.delete(\"user:1\")        # True if removed, False if absent\ncache.len()                   # approximate size\ncache.keys()                  # list of keys\ncache.cleanup_expired()       # remove expired entries; returns the count\ncache.clear()                 # remove everything (keeps counters)\ncache.stats()                 # {'hits','misses','sets','deletes','expired','evicted','size'}\n```\n\n### Bounded cache with LRU eviction\n\n```python\n# Cap the number of keys. When full and a new key arrives, evict the\n# least-recently-used entry instead of rejecting the write.\ncache = Cache(max_size=1000, eviction_policy=\"lru\")\ncache.eviction_policy            # \"lru\"\n\n# Default policy is \"reject\": set() returns False when full (and the key is new).\ncache = Cache(max_size=1000)     # eviction_policy=\"reject\"\ncache.set(\"a\", 1)                # True / False\n```\n\n### Background expiration\n\n```python\n# A background thread reclaims expired entries every N seconds, so you don't\n# have to call cleanup_expired() yourself. It stops when the cache is collected.\ncache = Cache(cleanup_interval=30)   # seconds (int/float)\n```\n\n### Memoization decorator\n\n```python\n@cache.cached(ttl=60)\ndef add(a, b):\n    return a + b\n\nadd(2, 3)   # runs and caches\nadd(2, 3)   # served from cache\n\n# custom key (fixed string or callable):\n@cache.cached(ttl=300, key=lambda user_id: f\"user:{user_id}\")\ndef load_user(user_id):\n    ...\n```\n\nSee full examples under [`examples/`](./examples) (FastAPI and Django).\n\n## API\n\nConstructor: `Cache(max_size=None, eviction_policy=\"reject\", cleanup_interval=None)`.\n`eviction_policy` must be `\"reject\"` or `\"lru\"` (any other value raises\n`ValueError`). `cleanup_interval` (seconds, `\u003e 0`) enables the background sweeper.\n\n| Method | Description |\n|---|---|\n| `set(key, value, ttl=None)` | Store a value. `ttl` in seconds (`int`/`float`); `None` = no expiration; `ttl \u003c= 0` → `ValueError`. Overwrites. Returns `True`, or `False` when full under `eviction_policy=\"reject\"` and the key is new. |\n| `get(key, default=None)` | The value, or `default` if missing/expired (expired entries are removed). |\n| `delete(key)` | `True` if removed, `False` if it didn't exist. |\n| `exists(key)` | `True`/`False`, honoring TTL. |\n| `keys()` | List of keys (may include expired-but-not-yet-collected ones). |\n| `len()` / `len(cache)` | Approximate size. |\n| `clear()` | Remove everything (does not reset counters). |\n| `cleanup_expired()` | Remove expired entries; returns how many. |\n| `eviction_policy` (property) | The active policy: `\"reject\"` or `\"lru\"`. |\n| `stats()` | `dict` with `hits, misses, sets, deletes, expired, evicted, size`. |\n| `@cache.cached(ttl=None, key=None)` | Memoization decorator. |\n\n## How it works\n\n- **Serialization:** in the MVP, values are serialized with `pickle` (on the Python\n  side, via PyO3) and stored as opaque bytes (`Vec\u003cu8\u003e`) in the Rust core.\n- **Concurrency:** `DashMap` (a HashMap with per-shard locks) plus `AtomicU64`\n  counters, with no global lock on the hot path. Thread-safe, no busy loop.\n- **TTL:** expiration is **lazy** by default — an expired key is removed when\n  accessed (`get`/`exists`) or via `cleanup_expired()`. Pass `cleanup_interval` to\n  also run a **background** sweeper thread that reclaims expired keys on its own.\n- **Eviction:** with `max_size` + `eviction_policy=\"lru\"`, a full cache evicts the\n  least-recently-used entry (recency updated on every `get` hit) to admit a new key.\n\n## Limitations\n\n- The cache is **process-local**: multiple workers = multiple independent caches.\n- It does **not** replace Redis for distributed caching.\n- Data is **lost** when the process restarts.\n- `pickle` must **not** be used to deserialize untrusted data.\n- Lazy TTL by default: without `cleanup_interval`, expired items may linger until\n  accessed or until `cleanup_expired()` runs.\n\n## Development\n\n```bash\ncargo test          # Rust core tests\nmaturin develop     # rebuild and install\npytest              # Python tests\n```\n\n\u003e If `maturin develop` complains about both `VIRTUAL_ENV` and `CONDA_PREFIX` being\n\u003e set, run `conda deactivate` first, or use `env -u CONDA_PREFIX maturin develop`.\n\n## Roadmap\n\nStages and next steps (LRU/LFU eviction, background expiration, configurable\nserializer, namespaces, etc.) are in [ROADMAP.md](./ROADMAP.md).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertolima-dev%2Frust-py-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobertolima-dev%2Frust-py-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertolima-dev%2Frust-py-cache/lists"}