Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
# a missing backend package would turn the gate below into a formality,
# so it does not rely on a dev-group entry staying put.
- name: Sync dependencies
run: uv sync --group dev --extra jwt --extra redis --extra memcache
run: uv sync --group dev --extra jwt --extra redis --extra memcached

# The gate. A release is the one run where a red test result arrives too
# late to matter, so everything CI checks elsewhere is checked here too,
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2.
- **`CacheLock`, a distributed lock built on backend primitives.** Usable as an async context manager or with direct `acquire`/`release`/`extend`/`locked` calls, raising `LockTimeoutError` on timeout. ([#64](https://github.com/allen0099/FastAPI-CacheX/issues/64))
- **`expire_if_equals()` backend primitive for owner-checked TTL renewal.** Added to `BaseCacheBackend`, `MemoryBackend`, `AsyncRedisCacheBackend`, and `MemcachedBackend`. ([#64](https://github.com/allen0099/FastAPI-CacheX/issues/64))

- **`memcached` extra for `MemcachedBackend`.** Install with
`fastapi-cachex[memcached]`, matching the backend's name. It pulls in the
same `pymemcache` dependency as the old `memcache` extra.
([#201](https://github.com/allen0099/FastAPI-CacheX/issues/201))

### Changed

- **GitHub release notes list one line per change.** Each changelog entry now
Expand All @@ -37,6 +42,11 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2.
`DeprecationWarning` if it clears anything. The retry will be removed in
0.4.0. ([#125](https://github.com/allen0099/FastAPI-CacheX/issues/125))

- **The `memcache` extra.** Use `memcached` instead. The old name keeps working
until 0.4.0 removes it; after that, pip and uv only warn about the unknown
extra and install without `pymemcache`.
([#202](https://github.com/allen0099/FastAPI-CacheX/issues/202))

### Fixed

- **Redis `clear_pattern()` no longer strips a pattern that starts with the key
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The library has four independent subsystems:
All backends implement `BaseCacheBackend` (abstract base in `backends/base.py`):
- `MemoryBackend`: In-process dict with background cleanup task. Not suitable for multi-process production use.
- `AsyncRedisCacheBackend` (`backends/redis.py`): Fully async; uses `SCAN` (not `KEYS`) for pattern operations. Requires `redis[hiredis]` and `orjson` extras.
- `MemcachedBackend` (`backends/memcached.py`): `clear_pattern`/`get_all_keys` are no-ops (return `0`/`[]` with a `RuntimeWarning`) since the Memcached protocol has no key enumeration. Runs the sync pymemcache client in worker threads with connection pooling (`use_pooling=True`, `default_noreply=False`), so concurrent calls never share a socket and every write is acknowledged before the next call on another socket can observe it. Requires `pymemcache` extra.
- `MemcachedBackend` (`backends/memcached.py`): `clear_pattern`/`get_all_keys` are no-ops (return `0`/`[]` with a `RuntimeWarning`) since the Memcached protocol has no key enumeration. Runs the sync pymemcache client in worker threads with connection pooling (`use_pooling=True`, `default_noreply=False`), so concurrent calls never share a socket and every write is acknowledged before the next call on another socket can observe it. Requires the `memcached` extra (`memcache` is a deprecated alias until 0.4.0).

Backend keys are namespaced automatically (default prefix: `fastapi_cachex:`).

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ backends and the optional session transports ship as extras:
| Extra | Install | Pulls in | Needed for |
|-------|---------|----------|------------|
| `redis` | `uv add "fastapi-cachex[redis]"` | `redis[hiredis]`, `orjson` | `AsyncRedisCacheBackend` |
| `memcache` | `uv add "fastapi-cachex[memcache]"` | `pymemcache` | `MemcachedBackend` (note: `memcache`, not `memcached`) |
| `memcached` | `uv add "fastapi-cachex[memcached]"` | `pymemcache` | `MemcachedBackend` (the older `memcache` name still works until 0.4.0) |
| `jwt` | `uv add "fastapi-cachex[jwt]"` | `PyJWT` | `SessionConfig(token_format="jwt")` |

Extras combine: `uv add "fastapi-cachex[redis,jwt]"`.
Expand Down
6 changes: 4 additions & 2 deletions docs/BACKENDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,10 @@ hiredis will fail to negotiate it.

## Memcached

Install the extra with `uv add "fastapi-cachex[memcache]"` (note: `memcache`, not
`memcached`).
Install the extra with `uv add "fastapi-cachex[memcached]"`. Before 0.3.8 it was
called `memcache`; that name still works but is deprecated and will be removed in
0.4.0. An unknown extra only produces a warning at install time, so after 0.4.0
`fastapi-cachex[memcache]` would install without `pymemcache`.

```python
from fastapi_cachex.backends import MemcachedBackend
Expand Down
2 changes: 1 addition & 1 deletion docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Worth doing whenever a test is written for something security-relevant.
## Using tox

tox ensures the code works across different Python versions (3.10-3.14, the
`env_list` in `tox.ini`). Each environment installs the `redis` and `memcache`
`env_list` in `tox.ini`). Each environment installs the `redis` and `memcached`
extras through `tox-uv` and passes the `CACHEX_TEST_*` and
`CACHEX_REQUIRE_LIVE_SERVERS` variables through, so the opt-in rules above apply
unchanged.
Expand Down
2 changes: 1 addition & 1 deletion fastapi_cachex/backends/memcached.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def __init__(
try:
from pymemcache import HashClient
except ImportError:
msg = "pymemcache is not installed. Please install it with 'pip install pymemcache'"
msg = "pymemcache is not installed. Install it with the extra: pip install 'fastapi-cachex[memcached]'"
raise CacheXError(msg)

# Pooled connections have no ordering guarantee between each other, so
Expand Down
2 changes: 1 addition & 1 deletion i18n/zh-TW/docs/BACKENDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ BackendProxy.set(backend)

## Memcached {#memcached}

以 `uv add "fastapi-cachex[memcache]"` 安裝此 extra(注意是 `memcache`,不是 `memcached`)。
以 `uv add "fastapi-cachex[memcached]"` 安裝此 extra。0.3.8 以前這個 extra 名為 `memcache`;舊名稱仍可使用但已棄用,將於 0.4.0 移除。安裝時遇到不存在的 extra 只會顯示警告,因此 0.4.0 之後 `fastapi-cachex[memcache]` 會裝好套件但不含 `pymemcache`。

```python
from fastapi_cachex.backends import MemcachedBackend
Expand Down
2 changes: 1 addition & 1 deletion i18n/zh-TW/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ uv add fastapi-cachex
| Extra | 安裝 | 帶入套件 | 用途 |
|-------|------|---------|------|
| `redis` | `uv add "fastapi-cachex[redis]"` | `redis[hiredis]`、`orjson` | `AsyncRedisCacheBackend` |
| `memcache` | `uv add "fastapi-cachex[memcache]"` | `pymemcache` | `MemcachedBackend`(注意是 `memcache`,不是 `memcached`) |
| `memcached` | `uv add "fastapi-cachex[memcached]"` | `pymemcache` | `MemcachedBackend`(舊名稱 `memcache` 在 0.4.0 之前仍可使用) |
| `jwt` | `uv add "fastapi-cachex[jwt]"` | `PyJWT` | `SessionConfig(token_format="jwt")` |

Extra 可以組合:`uv add "fastapi-cachex[redis,jwt]"`。
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ docs = [
]

[project.optional-dependencies]
memcached = ["pymemcache"]
# Deprecated alias of `memcached`, removed in 0.4.0 (#202).
memcache = ["pymemcache"]
redis = ["redis[hiredis]>=5.3.0", "orjson"]
jwt = ["PyJWT>=2.9.0"]
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ env_list =
runner = uv-venv-lock-runner
extras =
redis
memcache
memcached
# The Redis/Memcached suites are opt-in because they wipe the server they
# connect to; without these they skip. See tests/live_servers.py.
passenv =
Expand Down
6 changes: 5 additions & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading