Skip to content

docs: add runnable examples - #291

Merged
allen0099 merged 2 commits into
masterfrom
docs/runnable-examples
Sep 27, 2026
Merged

allen0099 merged 2 commits into
masterfrom
docs/runnable-examples

Conversation

@allen0099

Copy link
Copy Markdown
Owner

Adds examples/: one self-contained FastAPI app per feature, each driven through its main flow by the test suite, and links them from the README, the docs index and the guide pages (EN and zh-TW).

Files

File Shows Needs
examples/http_cache.py @cache with TTL, ETag / 304, no_cache, private, clear_path() after an update, monitoring routes behind an admin-token dependency —
examples/app_cache.py CacheManager.get_or_set(), add() as an idempotency check, the AppCache dependency —
examples/session_login.py FastAPICacheXSessionMiddleware with cookies: anonymous session, login with rotate_session_id(), AuthenticatedSession, logout via request.session.clear() —
examples/session_jwt.py token_format="jwt" sessions over Authorization: Bearer, revoked on logout jwt extra
examples/oauth_state.py StateManager with binding —
examples/cache_lock.py CacheLock, blocking (async with) and non-blocking —
examples/rate_limit.py Fixed-window limiter on backend.increment(), 429 + Retry-After —
examples/redis_backend.py AsyncRedisCacheBackend from env vars in the lifespan, closed on shutdown redis extra, a server
examples/README.md Index: what each shows, what it needs, how to run it
tests/test_examples.py Loads each example from its file and drives it through TestClient
pyproject.toml Ruff per-file ignores for examples/** (INP001, S106 for token_format="jwt")
README.md, i18n/zh-TW/docs/index.md "Runnable examples" link
Guide pages (EN + zh-TW): HTTP_CACHING, APP_CACHE, SESSION, STATE, LOCK, BACKENDS (Redis section, atomic primitives) One line: "Complete runnable example: examples/…"

The examples use the public API only and MemoryBackend by default. Secrets come from environment variables (SESSION_SECRET_KEY, CACHE_ADMIN_TOKEN); the session fallback is an obvious development placeholder long enough for HS256, and the monitoring routes stay closed while no admin token is set.

uv run fastapi dev needs fastapi-cli, which is not a dependency here, so the README documents uv run --with "fastapi-cli[standard]" fastapi dev examples/<file>.py and the Uvicorn form uv run --with uvicorn uvicorn examples.<mod>:app. Both were started locally and served requests.

Tests

  • tests/test_examples.py: 12 tests plus the Redis one. DeprecationWarning is an error. session_jwt and redis_backend are skipped via importlib.util.find_spec when their packages are missing; redis_backend also runs only with CACHEX_TEST_REDIS_PORT set (it uses redis_skip_reason(), so CACHEX_REQUIRE_LIVE_SERVERS=1 applies as for the other live suites). All four proxies are reset around each test, and each example is loaded as a fresh module.
  • A guard test checks that every examples/*.py has a test and a row in examples/README.md.
  • Full suite: 857 passed, 191 skipped (no live servers locally). tox -e lowest on tests/test_examples.py: 12 passed, 1 skipped.
  • uv run mypy examples --strict, ruff, pre-commit (its mypy hook already covers examples/), and both strict docs builds are clean.

Mutation checks, each applied to one example and run against its tests (all 11 killed):

Mutation Result
drop @cache(ttl=60) from the product route killed
drop clear_path() after the update killed
admin check accepts any token killed
call the factory directly instead of get_or_set() killed
add() → set() for the idempotency key killed
drop rotate_session_id() at login killed
logout with pop() instead of clear() killed
consume the OAuth state without the binding killed
replace CacheLock with a null context killed
non-blocking import acquires with blocking=True killed
rate limit off by one killed

Packaging

uv build: the wheel contains only fastapi_cachex/ and its dist-info, and the sdist contains LICENSE, PKG-INFO, README.md, pyproject.toml (plus the pyproject.toml.orig that uv_build writes) and fastapi_cachex/. examples/ is in neither, so packaging is unchanged.

CHANGELOG

Added

  • 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.

Part of #241. Next step: #289 (include the example files in the docs as snippets).

One self-contained FastAPI app per feature under examples/: HTTP caching,
CacheManager, cookie sessions with login and logout, JWT sessions, OAuth
state, CacheLock, a fixed-window rate limiter and a Redis backend.
tests/test_examples.py loads each one from its file and drives its main
flow through TestClient, with DeprecationWarning as an error. The JWT and
Redis examples are skipped without their packages; the Redis one also
follows the live-server opt-in.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant