From d5f52d26c4feb58e4a72e8caea5695a335a5f3ac Mon Sep 17 00:00:00 2001 From: allen0099 Date: Sun, 27 Sep 2026 10:35:12 +0000 Subject: [PATCH 1/3] docs(changelog): add the 0.3.8 entries collected from parallel PRs Copies the CHANGELOG sections of #207, #208, #209, #211, #212, #272, #273, #274, #275, #276, #279 and #284 into Unreleased. The #273 entry drops expire_if_equals from its list of methods that changed, since that primitive is new in 0.3.8. --- CHANGELOG.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50ca7c9..79f18e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,22 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. backend that is not involved. It subclasses `BackendNotFoundError`, so existing handlers keep catching it. `BackendProxy` is unchanged. ([#161](https://github.com/allen0099/FastAPI-CacheX/issues/161)) +- **`CacheXError`, `BackendNotFoundError` and `RequestNotFoundError` are + exported from `fastapi_cachex`.** They were only importable from + `fastapi_cachex.exceptions`, unlike every session and state exception. + ([#160](https://github.com/allen0099/FastAPI-CacheX/issues/160)) +- **`require_user_session` / `AuthenticatedSession` require a logged-in + user.** `get_session`, `RequiredSession` and `UserSessionDep` accept the + anonymous session any visitor gets by writing to `request.session`; the + new dependency also answers `401` when `session.user` is `None`. + `UserSessionDep` keeps its behaviour until 0.4.0. + ([#114](https://github.com/allen0099/FastAPI-CacheX/issues/114)) +- **`/cached-records` reports each entry's `media_type`.** It is the media + type the response was stored with, or `null` when it had none. + `content_type` is still returned for compatibility but is always `"bytes"`. + `CACHE_KEY_MAX_PARTS` in `fastapi_cachex.routes` is renamed + `CACHE_KEY_MAX_SPLIT`, since it is a `maxsplit` count; the old name remains + as an alias. ([#184](https://github.com/allen0099/FastAPI-CacheX/issues/184)) ### Changed @@ -59,6 +75,51 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. old behaviour. `invalidate()`, `CacheManager`, `StateManager`, `CacheLock` and sessions still raise. ([#228](https://github.com/allen0099/FastAPI-CacheX/issues/228)) +- **Redis clear operations delete page by page.** `clear()`, `clear_pattern()` + and `clear_path()` delete each SCAN page as it arrives instead of first + collecting every matching key in memory, and `clear_path()` no longer runs + an extra `EXISTS` on the direct key. + ([#172](https://github.com/allen0099/FastAPI-CacheX/issues/172)) +- **Redis `get_cache_data()` no longer blocks the server.** It fetched every + value and TTL inside one `MULTI`/`EXEC`, because redis-py pipelines are + transactional by default. It now sends non-transactional pipelines of 100 + keys each. + ([#171](https://github.com/allen0099/FastAPI-CacheX/issues/171)) +- **Memcached runs each operation in one worker call, and `delete_many()` + counts what it removed.** `increment`, `get_and_delete` and + `delete_if_equals` used to hand every round trip to its own worker thread; + `delete_many()` took one per key and returned how many keys it was given. + Each call now makes a single trip, and `delete_many()` returns how many of + the keys existed. + ([#174](https://github.com/allen0099/FastAPI-CacheX/issues/174), + [#176](https://github.com/allen0099/FastAPI-CacheX/issues/176)) +- **`CacheBackend` falls back to a `MemoryBackend` like `@cache` and + `AppCache`.** It used to answer 500 (`BackendNotFoundError`) until some + `@cache` route had registered the fallback. The three lazy defaults + (`get_backend_or_fallback`, `get_app_cache`, `get_state_manager`) now share + `ProxyBase.get_or_create(factory)`, which runs the factory at most once + under a per-class lock; `get_state_manager` could previously register two + managers under concurrent first requests. States still have no memory + fallback. ([#112](https://github.com/allen0099/FastAPI-CacheX/issues/112)) +- **`@cache` builds the cache key only when it reads or writes the backend.** + A custom `key_builder` is no longer called for `no_store`, `private` or + TTL-less routes, where the key only fed debug logs. + ([#182](https://github.com/allen0099/FastAPI-CacheX/issues/182)) +- **Session lookups no longer write to the backend unless sliding expiration + renewed the session.** `SessionManager.get_session()` used to save the + session on every call to record `last_accessed`, so each authenticated + request cost a write (two if it also modified the session). The stored + `last_accessed` is now updated only when the session is written (created, + modified, renewed or regenerated); pass `get_session(..., touch=True)` to + save it on every lookup. Session entries also store a constant fingerprint + instead of hashing the payload. + ([#115](https://github.com/allen0099/FastAPI-CacheX/issues/115)) +- **Runtime dependencies declare minimum versions.** `fastapi>=0.133.0`, + `starlette>=1.0.0` (now declared directly; the session middleware needs + Starlette 1.0), `pydantic>=2.7.0` and `itsdangerous>=1.1.0`; the extras + require `pymemcache>=4.0.0` and `orjson>=3.4.7`. Older versions could be + installed before but failed at import. A `lowest` tox env and CI workflow + test every floor. ([#194](https://github.com/allen0099/FastAPI-CacheX/issues/194)) ### Deprecated @@ -191,6 +252,26 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. to retrieve and remove the current value, matching Redis `GETDEL`, and raises `CacheXError` if retries run out. ([#175](https://github.com/allen0099/FastAPI-CacheX/issues/175)) +- **`clear_expired_sessions()` also removes invalidated and expired-status + sessions.** It only checked `expires_at`, so a session marked `INVALIDATED` + by `invalidate_session()` or `EXPIRED` by an expired read stayed in the + backend until its TTL ran out. Any session that is no longer `ACTIVE` is now + removed. `clear_expired_sessions()` and `delete_user_sessions()` also delete + what they find with one `backend.delete_many()` call instead of one `delete` + per session. + ([#165](https://github.com/allen0099/FastAPI-CacheX/issues/165)) +- **The session middleware varies on the header that carried the token.** + `FastAPICacheXSessionMiddleware` added `Vary: Cookie` whenever + `request.session` was accessed, even when the token came in + `X-Session-Token` or `Authorization`, so a shared cache could key those + responses on the wrong header. It now varies on every request header it + read to find the token, and on `Cookie` only when no header carried one. + ([#168](https://github.com/allen0099/FastAPI-CacheX/issues/168)) +- **The wheel and sdist ship the LICENSE file.** `pyproject.toml` declared + `Apache-2.0` but no `license-files`, so neither artifact contained the + licence text the Apache-2.0 licence requires recipients to receive. The + package also carries the `Typing :: Typed` classifier now. + ([#232](https://github.com/allen0099/FastAPI-CacheX/issues/232)) ### Security @@ -242,6 +323,21 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. contains `|` or `%` change, so those entries are cached afresh once. The HTTP caching guide now recommends `TrustedHostMiddleware`. ([#230](https://github.com/allen0099/FastAPI-CacheX/issues/230)) +- **Releases run from master only, and only the publish step can reach + PyPI.** `release.yml` could be dispatched on any branch, pushing the + release commit there and publishing unmerged code, and the one job that + installed every dev dependency also held `contents: write` and + `id-token: write`. A non-dry-run dispatch off `master` now fails at once. + The workflow is split into a read-only `build` job, a `release` job that + commits, tags and creates the GitHub release, and a `publish` job in the + `pypi` environment that alone can mint the PyPI token. + ([#231](https://github.com/allen0099/FastAPI-CacheX/issues/231)) +- **The JWT serializer warns about an HMAC key shorter than RFC 7518 + requires.** `secret_key` needs only 32 characters, but `HS384` and `HS512` + need 48 and 64 bytes. `JWTTokenSerializer` now emits one `UserWarning` + when it is built with a shorter key, instead of relying on PyJWT's + per-token `InsecureKeyLengthWarning`. + ([#116](https://github.com/allen0099/FastAPI-CacheX/issues/116)) ## [0.3.7] - 2026-09-25 From b05d10d74e209891c71873cd066df7db320d440d Mon Sep 17 00:00:00 2001 From: allen0099 Date: Sun, 27 Sep 2026 10:57:12 +0000 Subject: [PATCH 2/3] docs(changelog): add the Documentation entries for the examples and the docs pass --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79f18e0..b06b56f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -339,6 +339,22 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. per-token `InsecureKeyLengthWarning`. ([#116](https://github.com/allen0099/FastAPI-CacheX/issues/116)) +### Documentation + +- **Runnable examples.** `examples/` holds one complete FastAPI app per + feature: HTTP caching, `CacheManager`, cookie and JWT sessions, OAuth + state, `CacheLock`, a rate limiter on `increment()` and a Redis backend. + `tests/test_examples.py` runs each one's main flow, so they keep working + as the library changes. The guide pages link to the matching example. + ([#241](https://github.com/allen0099/FastAPI-CacheX/issues/241)) +- **Guides checked against 0.3.8.** The distributed lock and contributing + guides are now available in Traditional Chinese. The JWT claims guide uses + `FastAPICacheXSessionMiddleware`, and its custom serializer no longer reads + private attributes. Corrected statements: `invalidate()` raises backend + errors, only the Redis and Memcached backends prefix their keys, and + `CacheLock` is a lease rather than a guarantee of mutual exclusion. + ([#214](https://github.com/allen0099/FastAPI-CacheX/issues/214)) + ## [0.3.7] - 2026-09-25 ### Added From 682aac84e12b49e59ae12affb00eb97d59241a1f Mon Sep 17 00:00:00 2001 From: allen0099 Date: Sun, 27 Sep 2026 11:06:56 +0000 Subject: [PATCH 3/3] docs(changelog): add the session login docs entry (#294) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b06b56f..ac99000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -354,6 +354,10 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2. errors, only the Redis and Memcached backends prefix their keys, and `CacheLock` is a lease rather than a guarantee of mutual exclusion. ([#214](https://github.com/allen0099/FastAPI-CacheX/issues/214)) +- **Logging a user in.** The session guide now shows how to attach a + `SessionUser` at login so `require_user_session` and + `AuthenticatedSession` accept the session; writing to `request.session` + alone does not. ([#294](https://github.com/allen0099/FastAPI-CacheX/pull/294)) ## [0.3.7] - 2026-09-25