Metadata-Version: 2.4
Name: yokedcache
Version: 1.0.0
Summary: Python caching library for FastAPI with Redis auto-invalidation, vector search caching, and intelligent cache management
Project-URL: Homepage, https://github.com/sirstig/yokedcache
Project-URL: Documentation, https://sirstig.github.io/yokedcache
Project-URL: Repository, https://github.com/sirstig/yokedcache
Project-URL: Bug Tracker, https://github.com/sirstig/yokedcache/issues
Author: Project Yoked LLC
License-Expression: MIT
License-File: LICENSE
Keywords: async caching,cache,cache auto-invalidation,cache invalidation,cache management,caching,database,database caching,fastapi,fastapi caching,fastapi redis,intelligent caching,memcached,orm,performance,python caching library,python redis,redis,redis caching,sqlalchemy,vector search caching
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: AsyncIO
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Topic :: Database
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Distributed Computing
Requires-Python: >=3.10
Requires-Dist: click>=8.0.0
Requires-Dist: fastapi>=0.68.0
Requires-Dist: orjson>=3.11.6
Requires-Dist: pyyaml>=6.0
Requires-Dist: redis>=4.0.0
Requires-Dist: typing-extensions>=4.0.0
Provides-Extra: dev
Requires-Dist: aiomcache<1.0.0,>=0.8.0; extra == 'dev'
Requires-Dist: aiosqlite>=0.19.0; extra == 'dev'
Requires-Dist: black==26.3.1; extra == 'dev'
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: diskcache>=5.6.0; extra == 'dev'
Requires-Dist: fakeredis>=2.0.0; extra == 'dev'
Requires-Dist: flake8>=4.0.0; extra == 'dev'
Requires-Dist: fuzzywuzzy>=0.18.0; extra == 'dev'
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: isort>=5.10.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: numpy>=1.21.0; extra == 'dev'
Requires-Dist: opentelemetry-api>=1.24.0; extra == 'dev'
Requires-Dist: opentelemetry-sdk>=1.24.0; extra == 'dev'
Requires-Dist: pre-commit>=2.20.0; extra == 'dev'
Requires-Dist: prometheus-client>=0.16.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: python-levenshtein>=0.12.0; extra == 'dev'
Requires-Dist: scikit-learn>=1.0.0; extra == 'dev'
Requires-Dist: scipy>=1.7.0; extra == 'dev'
Requires-Dist: statsd>=4.0.0; extra == 'dev'
Requires-Dist: twine>=4.0.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Requires-Dist: types-redis>=4.0.0; extra == 'dev'
Provides-Extra: disk
Requires-Dist: diskcache>=5.0.0; extra == 'disk'
Provides-Extra: docs
Requires-Dist: jinja2>=3.1.0; extra == 'docs'
Requires-Dist: markdown>=3.5.0; extra == 'docs'
Requires-Dist: pdoc>=14.0.0; extra == 'docs'
Provides-Extra: full
Requires-Dist: aiomcache<1.0.0,>=0.8.0; extra == 'full'
Requires-Dist: aiosqlite>=0.19.0; extra == 'full'
Requires-Dist: diskcache>=5.0.0; extra == 'full'
Requires-Dist: fuzzywuzzy>=0.18.0; extra == 'full'
Requires-Dist: numpy>=1.21.0; extra == 'full'
Requires-Dist: opentelemetry-api>=1.15.0; extra == 'full'
Requires-Dist: opentelemetry-sdk>=1.15.0; extra == 'full'
Requires-Dist: prometheus-client>=0.16.0; extra == 'full'
Requires-Dist: python-levenshtein>=0.12.0; extra == 'full'
Requires-Dist: scikit-learn>=1.0.0; extra == 'full'
Requires-Dist: scipy>=1.7.0; extra == 'full'
Requires-Dist: sqlalchemy>=1.4.0; extra == 'full'
Requires-Dist: statsd>=4.0.0; extra == 'full'
Provides-Extra: fuzzy
Requires-Dist: fuzzywuzzy>=0.18.0; extra == 'fuzzy'
Requires-Dist: python-levenshtein>=0.12.0; extra == 'fuzzy'
Provides-Extra: memcached
Requires-Dist: aiomcache<1.0.0,>=0.8.0; extra == 'memcached'
Provides-Extra: monitoring
Requires-Dist: prometheus-client>=0.16.0; extra == 'monitoring'
Requires-Dist: statsd>=4.0.0; extra == 'monitoring'
Provides-Extra: sqlalchemy
Requires-Dist: sqlalchemy>=1.4.0; extra == 'sqlalchemy'
Provides-Extra: sqlite
Requires-Dist: aiosqlite>=0.19.0; extra == 'sqlite'
Provides-Extra: tracing
Requires-Dist: opentelemetry-api>=1.15.0; extra == 'tracing'
Requires-Dist: opentelemetry-sdk>=1.15.0; extra == 'tracing'
Provides-Extra: vector
Requires-Dist: numpy>=1.21.0; extra == 'vector'
Requires-Dist: scikit-learn>=1.0.0; extra == 'vector'
Requires-Dist: scipy>=1.7.0; extra == 'vector'
Description-Content-Type: text/markdown

# yokedcache

[![PyPI version](https://img.shields.io/pypi/v/yokedcache.svg)](https://pypi.org/project/yokedcache/)
[![Python](https://img.shields.io/pypi/pyversions/yokedcache.svg)](https://pypi.org/project/yokedcache/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Tests](https://github.com/sirstig/yokedcache/actions/workflows/test.yml/badge.svg)](https://github.com/sirstig/yokedcache/actions/workflows/test.yml)
[![Coverage](https://codecov.io/gh/sirstig/yokedcache/branch/main/graph/badge.svg)](https://codecov.io/gh/sirstig/yokedcache)

Async-first Python caching for FastAPI and other asyncio services: Redis-oriented invalidation, pluggable backends, optional vector helpers, and metrics that fit real deployments.

**[Documentation](https://sirstig.github.io/yokedcache/)** · **[Changelog](https://sirstig.github.io/yokedcache/changelog.html)** · **[PyPI](https://pypi.org/project/yokedcache/)** · **[Issues](https://github.com/sirstig/yokedcache/issues)**

---

## Features

- **Invalidation** — Tags, patterns, and workflows that keep cache and writes aligned
- **FastAPI** — Dependency-friendly helpers (`cached_dependency`, decorators) without rewriting routes
- **Backends** — Redis (default), Memcached, memory, disk, SQLite; per-prefix routing
- **HTTP** — ETag / `Cache-Control` middleware and 304-friendly responses
- **Resilience** — Circuit breaker, retries, stale-if-error style patterns
- **Observability** — Prometheus, StatsD, OpenTelemetry hooks
- **CLI** — Inspect keys, stats, and health from the shell

## Installation

Current stable line: **1.0.0** (default on PyPI).

```bash
pip install yokedcache
```

To require 1.x or newer:

```bash
pip install "yokedcache>=1.0.0"
```

Optional extras:

| Extra | Purpose |
|--------|---------|
| `memcached` | Memcached backend |
| `monitoring` | Prometheus / StatsD |
| `vector` | Vector / similarity helpers |
| `fuzzy` | Fuzzy matching utilities |
| `disk` | Disk backend |
| `sqlite` | SQLite backend |
| `tracing` | OpenTelemetry API/SDK |
| `full` | All of the above |
| `dev` | Tests, linters, type checking |

## Quick start

```python
from fastapi import FastAPI, Depends
from yokedcache import cached_dependency

app = FastAPI()

cached_get_db = cached_dependency(get_db, ttl=300)

@app.get("/users/{user_id}")
async def get_user(user_id: int, db=Depends(cached_get_db)):
    return db.query(User).filter(User.id == user_id).first()
```

## Requirements

| | Minimum |
|---|---|
| Python | 3.10+ for **yokedcache 1.x** (tested on 3.10 through 3.14 in CI) |
| Redis | 4.x client; server 6+ typical for production |

**Python 3.9** is unsupported on 1.x (transitive deps such as patched **filelock** require 3.10+). If you must stay on 3.9, pin **`yokedcache==0.3.0`** (or `0.3.x`); that release line is **not** maintained for new security fixes—plan an upgrade.

Other backends impose their own dependencies when you install the matching extra.

## Documentation

- [Getting started](https://sirstig.github.io/yokedcache/getting-started.html)
- [Usage patterns](https://sirstig.github.io/yokedcache/usage-patterns.html)
- [FastAPI tutorial](https://sirstig.github.io/yokedcache/tutorials/fastapi.html)
- [API reference (pdoc)](https://sirstig.github.io/yokedcache/api/)
- [llms.txt](https://sirstig.github.io/yokedcache/llms.txt) for tool-oriented summaries

## Security

Treat Redis and Memcached as **trusted** stores: anyone who can write arbitrary keys can affect deserialization. From **1.0.0**, new values are written with a typed envelope; set `allow_legacy_insecure_deserialization=False` on `CacheConfig` once legacy entries are migrated. Do not use `HTTPCacheMiddleware` on authenticated routes without a `key_builder` that varies the key per user or session. See the changelog for details. The **[SECURITY.md](SECURITY.md)** file covers the optional disk backend (pickle / `diskcache`) and how we pin vulnerable transitive deps in `uv.lock`.

## Development

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

Build the static docs site locally:

```bash
pip install -e ".[docs]"
python scripts/build_docs_site.py
cp CHANGELOG.md site/changelog.md
python -m pdoc yokedcache -o site/api --template-directory site-src/pdoc-template
cd site && python -m http.server 8000
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for workflow and review expectations.

## License

MIT. See [LICENSE](LICENSE).

Maintained by **Project Yoked LLC**; technical lead **Joshua Kac**.
