Caching, retry and resilient-HTTP helpers for FastAPI services.
Project description
fastapi-memory
Caching, retry, and resilient-HTTP helpers for FastAPI services.
A single package that provides response caching, retry policies, a resilient async HTTP client, and cached config singletons — tailored for FastAPI projects that talk to upstream APIs.
from fastapi_memory import (
FmCacheManager, FmMemoryBackend, memorize,
retry, stop_after_retries, exponential_backoff, retry_on_error,
fm_lru,
)
Why
Most FastAPI services that proxy slower or less-reliable upstream APIs end up re-writing the same patterns:
- A cache for endpoints or data that don't change often.
- A retry policy for upstream calls — retry network errors and 5xx, but not 4xx.
- A cached singleton config object (build once, reuse everywhere).
- A resilient HTTP client with connection pooling and retries baked in.
fastapi-memory consolidates all of these into one import, with ready-made
helpers so you don't have to re-derive common patterns every time.
Installation
# From PyPI
pip install fastapi-memory
# With optional Redis cache backend support
pip install "fastapi-memory[redis]"
What's inside
| Module | Provides | Adds |
|---|---|---|
caching |
FmCacheManager, FmMemoryBackend, memorize, FmRedisBackend |
FmCacheManager.get(), .set(), .clear(), .init() |
resilience |
retry, stop_after_retries, exponential_backoff, retry_on_error |
default_retry(), is_retryable_httpx_error() |
config |
fm_lru |
cached_singleton |
http |
— | FmResilientClient |
Everything above is re-exported from the top-level fastapi_memory package,
so from fastapi_memory import <anything in the table> works.
Quick start
Caching — response caching with a single call
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi_memory import FmCacheManager, FmMemoryBackend, memorize
@asynccontextmanager
async def lifespan(app: FastAPI):
FmCacheManager.init(FmMemoryBackend(), prefix="app-cache") # in-memory
yield
app = FastAPI(lifespan=lifespan)
@app.get("/api/data")
@memorize(expire=60)
async def get_data():
return {"data": "computed result"}
# Manual get/set
await FmCacheManager.set("my-key", {"data": "value"}, expire=60)
cached = await FmCacheManager.get("my-key")
@app.post("/api/cache/invalidate")
async def invalidate_cache():
await FmCacheManager.clear()
return {"ok": True}
Switching to Redis later
from fastapi_memory import FmCacheManager, FmRedisBackend
FmCacheManager.init(
FmRedisBackend(redis_client),
prefix="app-cache",
)
Retry — exponential backoff with sensible defaults
from fastapi_memory import default_retry
@default_retry()
async def call_upstream():
resp = await client.get(url)
resp.raise_for_status()
return resp.json()
default_retry() retries up to 3 times with exponential backoff (2s–10s),
skip 4xx, reraise on final failure. Override any piece:
@default_retry(attempts=5, wait_max=30)
async def flaky_call():
...
Config — cached singleton
from fastapi_memory import cached_singleton
class Settings:
BASE_URL: str = "http://api.example.com:8080"
CACHE_TTL: int = 300
@cached_singleton
def get_settings() -> Settings:
return Settings()
config = get_settings()
Resilient HTTP client
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi_memory import FmResilientClient, FmCacheManager, FmMemoryBackend
upstream = FmResilientClient(
base_url="http://api.example.com:8080",
timeout=30.0,
)
@asynccontextmanager
async def lifespan(app: FastAPI):
await upstream.start()
FmCacheManager.init(FmMemoryBackend(), prefix="app-cache")
yield
await upstream.aclose()
app = FastAPI(lifespan=lifespan)
@app.get("/api/data")
async def get_data():
return await upstream.get_json("data")
upstream.get_raw(path, params) is also available if you want the raw
exceptions instead of HTTPException.
Project layout
fastapi-memory/
├── pyproject.toml
├── setup.py
├── README.md
├── LICENSE
├── fastapi_memory/
│ ├── __init__.py # re-exports everything
│ ├── caching.py # FmCacheManager, FmMemoryBackend, memorize
│ ├── resilience.py # retry + default_retry, is_retryable_httpx_error
│ ├── config.py # fm_lru + cached_singleton
│ └── http.py # FmResilientClient
└── tests/
└── test_imports.py
Updating requirements.txt
Replace:
tenacity>=8.3.0
fastapi-cache2>=0.2.2
redis>=5.0.0
with:
fastapi-memory @ file:///path/to/fastapi-memory
(or once published: fastapi-memory>=0.1.0, optionally fastapi-memory[redis].)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_memory-0.0.1.tar.gz.
File metadata
- Download URL: fastapi_memory-0.0.1.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4523ccfdff2acee542759f26f017d1c7069ca74a7bf660a151d9fff752ca699
|
|
| MD5 |
303167d7442985631500f3ca551c5f71
|
|
| BLAKE2b-256 |
c59b062c96fdc6ee6caa2c6cf268e199bb8e64749f1d4595b1c6bd16bdfcab97
|
File details
Details for the file fastapi_memory-0.0.1-py3-none-any.whl.
File metadata
- Download URL: fastapi_memory-0.0.1-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b07fef9de62c02fa794d8cd6c2e95f193e6268a07a4da61911c1261eabf361fe
|
|
| MD5 |
be48a684fc617f3bb04fce4639ef4777
|
|
| BLAKE2b-256 |
4512fa91d8d34afaa94d0fb7f536b7032221d20071b310315a90bfb4dc6204da
|