fastapi-cachex 0.2.7__tar.gz → 0.2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/PKG-INFO +5 -5
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/README.md +4 -4
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/cache.py +2 -2
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/dependencies.py +1 -1
- fastapi_cachex-0.2.9/fastapi_cachex/proxy.py +95 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/routes.py +2 -2
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/__init__.py +2 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/middleware.py +3 -2
- fastapi_cachex-0.2.9/fastapi_cachex/session/proxy.py +9 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/state/manager.py +1 -1
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/pyproject.toml +1 -1
- fastapi_cachex-0.2.7/fastapi_cachex/proxy.py +0 -43
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/__init__.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/backends/__init__.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/backends/base.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/backends/config.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/backends/memcached.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/backends/memory.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/backends/redis.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/directives.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/exceptions.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/py.typed +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/config.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/dependencies.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/exceptions.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/manager.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/models.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/security.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/session/token_serializers.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/state/__init__.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/state/exceptions.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/state/models.py +0 -0
- {fastapi_cachex-0.2.7 → fastapi_cachex-0.2.9}/fastapi_cachex/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-cachex
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: A caching library for FastAPI with support for Cache-Control, ETag, and multiple backends.
|
|
5
5
|
Keywords: fastapi,cache,etag,cache-control,redis,memcached,in-memory
|
|
6
6
|
Author: allen0099
|
|
@@ -186,7 +186,7 @@ from fastapi_cachex.backends import MemoryBackend
|
|
|
186
186
|
from fastapi_cachex import BackendProxy
|
|
187
187
|
|
|
188
188
|
backend = MemoryBackend()
|
|
189
|
-
BackendProxy.
|
|
189
|
+
BackendProxy.set(backend)
|
|
190
190
|
```
|
|
191
191
|
|
|
192
192
|
**Note**: In-memory cache is not suitable for production with multiple processes.
|
|
@@ -199,7 +199,7 @@ from fastapi_cachex.backends import MemcachedBackend
|
|
|
199
199
|
from fastapi_cachex import BackendProxy
|
|
200
200
|
|
|
201
201
|
backend = MemcachedBackend(servers=["localhost:11211"])
|
|
202
|
-
BackendProxy.
|
|
202
|
+
BackendProxy.set(backend)
|
|
203
203
|
```
|
|
204
204
|
|
|
205
205
|
**Limitations**:
|
|
@@ -214,7 +214,7 @@ from fastapi_cachex.backends import AsyncRedisCacheBackend
|
|
|
214
214
|
from fastapi_cachex import BackendProxy
|
|
215
215
|
|
|
216
216
|
backend = AsyncRedisCacheBackend(host="127.0.0.1", port=6379, db=0)
|
|
217
|
-
BackendProxy.
|
|
217
|
+
BackendProxy.set(backend)
|
|
218
218
|
```
|
|
219
219
|
|
|
220
220
|
**Features**:
|
|
@@ -232,7 +232,7 @@ backend = AsyncRedisCacheBackend(
|
|
|
232
232
|
port=6379,
|
|
233
233
|
key_prefix="myapp:cache:",
|
|
234
234
|
)
|
|
235
|
-
BackendProxy.
|
|
235
|
+
BackendProxy.set(backend)
|
|
236
236
|
```
|
|
237
237
|
|
|
238
238
|
## Performance Considerations
|
|
@@ -150,7 +150,7 @@ from fastapi_cachex.backends import MemoryBackend
|
|
|
150
150
|
from fastapi_cachex import BackendProxy
|
|
151
151
|
|
|
152
152
|
backend = MemoryBackend()
|
|
153
|
-
BackendProxy.
|
|
153
|
+
BackendProxy.set(backend)
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
**Note**: In-memory cache is not suitable for production with multiple processes.
|
|
@@ -163,7 +163,7 @@ from fastapi_cachex.backends import MemcachedBackend
|
|
|
163
163
|
from fastapi_cachex import BackendProxy
|
|
164
164
|
|
|
165
165
|
backend = MemcachedBackend(servers=["localhost:11211"])
|
|
166
|
-
BackendProxy.
|
|
166
|
+
BackendProxy.set(backend)
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
**Limitations**:
|
|
@@ -178,7 +178,7 @@ from fastapi_cachex.backends import AsyncRedisCacheBackend
|
|
|
178
178
|
from fastapi_cachex import BackendProxy
|
|
179
179
|
|
|
180
180
|
backend = AsyncRedisCacheBackend(host="127.0.0.1", port=6379, db=0)
|
|
181
|
-
BackendProxy.
|
|
181
|
+
BackendProxy.set(backend)
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
**Features**:
|
|
@@ -196,7 +196,7 @@ backend = AsyncRedisCacheBackend(
|
|
|
196
196
|
port=6379,
|
|
197
197
|
key_prefix="myapp:cache:",
|
|
198
198
|
)
|
|
199
|
-
BackendProxy.
|
|
199
|
+
BackendProxy.set(backend)
|
|
200
200
|
```
|
|
201
201
|
|
|
202
202
|
## Performance Considerations
|
|
@@ -151,11 +151,11 @@ def cache(
|
|
|
151
151
|
|
|
152
152
|
def decorator(func: HandlerCallable) -> AsyncResponseCallable:
|
|
153
153
|
try:
|
|
154
|
-
cache_backend = BackendProxy.
|
|
154
|
+
cache_backend = BackendProxy.get()
|
|
155
155
|
except BackendNotFoundError:
|
|
156
156
|
# Fallback to memory backend if no backend is set
|
|
157
157
|
cache_backend = MemoryBackend()
|
|
158
|
-
BackendProxy.
|
|
158
|
+
BackendProxy.set(cache_backend)
|
|
159
159
|
logger.debug("No backend configured; using MemoryBackend fallback")
|
|
160
160
|
|
|
161
161
|
# Analyze the original function's signature
|
|
@@ -10,7 +10,7 @@ from .proxy import BackendProxy
|
|
|
10
10
|
|
|
11
11
|
def get_cache_backend() -> BaseCacheBackend:
|
|
12
12
|
"""Dependency to get the current cache backend instance."""
|
|
13
|
-
return BackendProxy.
|
|
13
|
+
return BackendProxy.get()
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
CacheBackend = Annotated[BaseCacheBackend, Depends(get_cache_backend)]
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Backend proxy for managing cache backend instances."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import warnings
|
|
6
|
+
from logging import getLogger
|
|
7
|
+
from typing import Generic
|
|
8
|
+
from typing import TypeVar
|
|
9
|
+
|
|
10
|
+
from .backends import BaseCacheBackend
|
|
11
|
+
from .exceptions import BackendNotFoundError
|
|
12
|
+
|
|
13
|
+
ProxyInstance = TypeVar("ProxyInstance")
|
|
14
|
+
|
|
15
|
+
logger = getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ProxyMeta(type):
|
|
19
|
+
"""Metaclass for BackendProxy to prevent instantiation."""
|
|
20
|
+
|
|
21
|
+
def __call__(cls) -> None:
|
|
22
|
+
"""Prevent instantiation of BackendProxy."""
|
|
23
|
+
msg = "Proxy class cannot be instantiated. Use static methods instead."
|
|
24
|
+
raise TypeError(msg)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ProxyBase(Generic[ProxyInstance], metaclass=ProxyMeta):
|
|
28
|
+
"""Abstract base class for proxy classes."""
|
|
29
|
+
|
|
30
|
+
_instance: ProxyInstance | None = None
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def get(cls) -> ProxyInstance:
|
|
34
|
+
"""Get the current instance of the proxy.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
The current instance
|
|
38
|
+
"""
|
|
39
|
+
if cls._instance is None:
|
|
40
|
+
msg = f"No instance set for proxy {cls.__name__}"
|
|
41
|
+
raise BackendNotFoundError(msg)
|
|
42
|
+
return cls._instance
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def set(cls, instance: ProxyInstance | None) -> None:
|
|
46
|
+
"""Set the instance for the proxy.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
instance: The instance to set, or None to clear
|
|
50
|
+
"""
|
|
51
|
+
logger.info(
|
|
52
|
+
"Setting instance to: <%s>",
|
|
53
|
+
instance.__class__.__name__ if instance else "None",
|
|
54
|
+
)
|
|
55
|
+
cls._instance = instance
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class BackendProxy(ProxyBase[BaseCacheBackend]):
|
|
59
|
+
"""FastAPI CacheX Proxy for backend management."""
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def get_backend() -> BaseCacheBackend: # pragma: no cover
|
|
63
|
+
"""Get the current backend instance.
|
|
64
|
+
|
|
65
|
+
.. deprecated:: 0.3.0
|
|
66
|
+
Use :meth:`get` instead. Will be removed in version 0.4.0.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
The current backend instance
|
|
70
|
+
"""
|
|
71
|
+
warnings.warn(
|
|
72
|
+
"get_backend() is deprecated, use get() instead. "
|
|
73
|
+
"Will be removed in version 0.4.0.",
|
|
74
|
+
DeprecationWarning,
|
|
75
|
+
stacklevel=2,
|
|
76
|
+
)
|
|
77
|
+
return BackendProxy.get()
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def set_backend(backend: BaseCacheBackend | None) -> None: # pragma: no cover
|
|
81
|
+
"""Set the backend instance.
|
|
82
|
+
|
|
83
|
+
.. deprecated:: 0.3.0
|
|
84
|
+
Use :meth:`set` instead. Will be removed in version 0.4.0.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
backend: The backend instance to set, or None to clear
|
|
88
|
+
"""
|
|
89
|
+
warnings.warn(
|
|
90
|
+
"set_backend() is deprecated, use set() instead. "
|
|
91
|
+
"Will be removed in version 0.4.0.",
|
|
92
|
+
DeprecationWarning,
|
|
93
|
+
stacklevel=2,
|
|
94
|
+
)
|
|
95
|
+
BackendProxy.set(backend)
|
|
@@ -266,7 +266,7 @@ def add_routes(
|
|
|
266
266
|
CacheHitsResponse containing cache hit records and statistics
|
|
267
267
|
"""
|
|
268
268
|
try:
|
|
269
|
-
backend: BaseCacheBackend = BackendProxy.
|
|
269
|
+
backend: BaseCacheBackend = BackendProxy.get()
|
|
270
270
|
except BackendNotFoundError:
|
|
271
271
|
return CacheHitsResponse(
|
|
272
272
|
cached_hits=[],
|
|
@@ -294,7 +294,7 @@ def add_routes(
|
|
|
294
294
|
CachedRecordsResponse containing cached records and statistics
|
|
295
295
|
"""
|
|
296
296
|
try:
|
|
297
|
-
backend: BaseCacheBackend = BackendProxy.
|
|
297
|
+
backend: BaseCacheBackend = BackendProxy.get()
|
|
298
298
|
except BackendNotFoundError:
|
|
299
299
|
return CachedRecordsResponse(
|
|
300
300
|
cached_records=[],
|
|
@@ -9,11 +9,13 @@ from .manager import SessionManager
|
|
|
9
9
|
from .middleware import SessionMiddleware
|
|
10
10
|
from .models import Session
|
|
11
11
|
from .models import SessionUser
|
|
12
|
+
from .proxy import SessionManagerProxy
|
|
12
13
|
|
|
13
14
|
__all__ = [
|
|
14
15
|
"Session",
|
|
15
16
|
"SessionConfig",
|
|
16
17
|
"SessionManager",
|
|
18
|
+
"SessionManagerProxy",
|
|
17
19
|
"SessionMiddleware",
|
|
18
20
|
"SessionUser",
|
|
19
21
|
"get_optional_session",
|
|
@@ -12,6 +12,7 @@ from starlette.types import ASGIApp
|
|
|
12
12
|
from .config import SessionConfig
|
|
13
13
|
from .exceptions import SessionError
|
|
14
14
|
from .manager import SessionManager
|
|
15
|
+
from .proxy import SessionManagerProxy
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
17
18
|
from .models import Session
|
|
@@ -25,7 +26,7 @@ class SessionMiddleware(BaseHTTPMiddleware):
|
|
|
25
26
|
def __init__(
|
|
26
27
|
self,
|
|
27
28
|
app: ASGIApp,
|
|
28
|
-
session_manager: SessionManager,
|
|
29
|
+
session_manager: SessionManager | None = None,
|
|
29
30
|
config: SessionConfig | None = None,
|
|
30
31
|
) -> None:
|
|
31
32
|
"""Initialize session middleware.
|
|
@@ -36,7 +37,7 @@ class SessionMiddleware(BaseHTTPMiddleware):
|
|
|
36
37
|
config: Session configuration
|
|
37
38
|
"""
|
|
38
39
|
super().__init__(app)
|
|
39
|
-
self.session_manager = session_manager
|
|
40
|
+
self.session_manager = session_manager or SessionManagerProxy.get()
|
|
40
41
|
|
|
41
42
|
if config is None:
|
|
42
43
|
config = self.session_manager.config
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""FastAPI CacheX Proxy for session manager management."""
|
|
2
|
+
|
|
3
|
+
from fastapi_cachex.proxy import ProxyBase
|
|
4
|
+
|
|
5
|
+
from .manager import SessionManager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SessionManagerProxy(ProxyBase[SessionManager]):
|
|
9
|
+
"""FastAPI CacheX Proxy for session manager management."""
|
|
@@ -35,7 +35,7 @@ class StateManager:
|
|
|
35
35
|
key_prefix: Prefix for state keys in cache backend
|
|
36
36
|
default_ttl: Default time-to-live in seconds for state
|
|
37
37
|
"""
|
|
38
|
-
self.backend = BackendProxy.
|
|
38
|
+
self.backend = BackendProxy.get()
|
|
39
39
|
self.key_prefix = key_prefix
|
|
40
40
|
self.default_ttl = default_ttl
|
|
41
41
|
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"""Backend proxy for managing cache backend instances."""
|
|
2
|
-
|
|
3
|
-
from logging import getLogger
|
|
4
|
-
|
|
5
|
-
from .backends import BaseCacheBackend
|
|
6
|
-
from .exceptions import BackendNotFoundError
|
|
7
|
-
|
|
8
|
-
_default_backend: BaseCacheBackend | None = None
|
|
9
|
-
logger = getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class BackendProxy:
|
|
13
|
-
"""FastAPI CacheX Proxy for backend management."""
|
|
14
|
-
|
|
15
|
-
@staticmethod
|
|
16
|
-
def get_backend() -> BaseCacheBackend:
|
|
17
|
-
"""Get the current cache backend instance.
|
|
18
|
-
|
|
19
|
-
Returns:
|
|
20
|
-
The current cache backend
|
|
21
|
-
|
|
22
|
-
Raises:
|
|
23
|
-
BackendNotFoundError: If no backend has been set
|
|
24
|
-
"""
|
|
25
|
-
if _default_backend is None:
|
|
26
|
-
msg = "Backend is not set. Please set the backend first."
|
|
27
|
-
raise BackendNotFoundError(msg)
|
|
28
|
-
|
|
29
|
-
return _default_backend
|
|
30
|
-
|
|
31
|
-
@staticmethod
|
|
32
|
-
def set_backend(backend: BaseCacheBackend | None) -> None:
|
|
33
|
-
"""Set the backend for caching.
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
backend: The backend to use for caching, or None to clear the current backend
|
|
37
|
-
"""
|
|
38
|
-
global _default_backend
|
|
39
|
-
logger.info(
|
|
40
|
-
"Setting backend to: <%s>",
|
|
41
|
-
backend.__class__.__name__ if backend else "None",
|
|
42
|
-
)
|
|
43
|
-
_default_backend = backend
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|