fastapi-cachex 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
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.
Potentially problematic release.
This version of fastapi-cachex might be problematic. Click here for more details.
- fastapi_cachex/backends/__init__.py +1 -0
- fastapi_cachex/backends/memcached.py +74 -0
- fastapi_cachex/proxy.py +9 -3
- fastapi_cachex-0.1.2.dist-info/METADATA +172 -0
- {fastapi_cachex-0.1.0.dist-info → fastapi_cachex-0.1.2.dist-info}/RECORD +8 -7
- fastapi_cachex-0.1.0.dist-info/METADATA +0 -111
- {fastapi_cachex-0.1.0.dist-info → fastapi_cachex-0.1.2.dist-info}/WHEEL +0 -0
- {fastapi_cachex-0.1.0.dist-info → fastapi_cachex-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {fastapi_cachex-0.1.0.dist-info → fastapi_cachex-0.1.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from fastapi_cachex.backends.base import BaseCacheBackend
|
|
5
|
+
from fastapi_cachex.exceptions import CacheXError
|
|
6
|
+
from fastapi_cachex.types import ETagContent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MemcachedBackend(BaseCacheBackend):
|
|
10
|
+
"""Memcached backend implementation."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, servers: list[str]) -> None:
|
|
13
|
+
"""Initialize the Memcached backend.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
servers: List of Memcached servers in format ["host:port", ...]
|
|
17
|
+
|
|
18
|
+
Raises:
|
|
19
|
+
CacheXError: If pymemcache is not installed
|
|
20
|
+
"""
|
|
21
|
+
try:
|
|
22
|
+
from pymemcache import HashClient
|
|
23
|
+
except ImportError:
|
|
24
|
+
raise CacheXError(
|
|
25
|
+
"pymemcache is not installed. Please install it with 'pip install pymemcache'"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
self.client = HashClient(servers)
|
|
29
|
+
|
|
30
|
+
async def get(self, key: str) -> Optional[ETagContent]:
|
|
31
|
+
"""Get value from cache.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
key: Cache key to retrieve
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Optional[ETagContent]: Cached value with ETag if exists, None otherwise
|
|
38
|
+
"""
|
|
39
|
+
value = self.client.get(key)
|
|
40
|
+
if value is None:
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
# Memcached stores data as bytes
|
|
44
|
+
# Convert string back to dictionary
|
|
45
|
+
value_dict = ast.literal_eval(value.decode("utf-8"))
|
|
46
|
+
return ETagContent(etag=value_dict["etag"], content=value_dict["content"])
|
|
47
|
+
|
|
48
|
+
async def set(
|
|
49
|
+
self, key: str, value: ETagContent, ttl: Optional[int] = None
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Set value in cache.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
key: Cache key
|
|
55
|
+
value: ETagContent to store
|
|
56
|
+
ttl: Time to live in seconds
|
|
57
|
+
"""
|
|
58
|
+
# Store as dictionary in string format
|
|
59
|
+
data = {"etag": value.etag, "content": value.content}
|
|
60
|
+
self.client.set(
|
|
61
|
+
key, str(data).encode("utf-8"), expire=ttl if ttl is not None else 0
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
async def delete(self, key: str) -> None:
|
|
65
|
+
"""Delete value from cache.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
key: Cache key to delete
|
|
69
|
+
"""
|
|
70
|
+
self.client.delete(key)
|
|
71
|
+
|
|
72
|
+
async def clear(self) -> None:
|
|
73
|
+
"""Clear all values from cache."""
|
|
74
|
+
self.client.flush_all()
|
fastapi_cachex/proxy.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
1
3
|
from fastapi_cachex.backends import BaseCacheBackend
|
|
2
4
|
from fastapi_cachex.exceptions import BackendNotFoundError
|
|
3
5
|
|
|
4
|
-
_default_backend: BaseCacheBackend
|
|
6
|
+
_default_backend: Optional[BaseCacheBackend] = None
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class BackendProxy:
|
|
@@ -17,7 +19,11 @@ class BackendProxy:
|
|
|
17
19
|
return _default_backend
|
|
18
20
|
|
|
19
21
|
@staticmethod
|
|
20
|
-
def set_backend(backend: BaseCacheBackend) -> None:
|
|
21
|
-
"""Set the backend for caching.
|
|
22
|
+
def set_backend(backend: Optional[BaseCacheBackend]) -> None:
|
|
23
|
+
"""Set the backend for caching.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
backend: The backend to use for caching, or None to clear the current backend
|
|
27
|
+
"""
|
|
22
28
|
global _default_backend
|
|
23
29
|
_default_backend = backend
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fastapi-cachex
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: A caching library for FastAPI with support for Cache-Control, ETag, and multiple backends.
|
|
5
|
+
Author-email: Allen <s96016641@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/allen0099/FastAPI-CacheX
|
|
8
|
+
Project-URL: Repository, https://github.com/allen0099/FastAPI-CacheX.git
|
|
9
|
+
Project-URL: Issues, https://github.com/allen0099/FastAPI-CacheX/issues
|
|
10
|
+
Keywords: fastapi,cache,etag,cache-control,redis,memcached,in-memory
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Framework :: FastAPI
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: fastapi
|
|
27
|
+
Requires-Dist: httpx
|
|
28
|
+
Provides-Extra: memcache
|
|
29
|
+
Requires-Dist: pymemcache; extra == "memcache"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# FastAPI-Cache X
|
|
33
|
+
|
|
34
|
+
[](https://github.com/astral-sh/uv)
|
|
35
|
+
[](https://github.com/astral-sh/ruff)
|
|
36
|
+
[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
|
|
37
|
+
[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
|
|
38
|
+
|
|
39
|
+
[](https://pepy.tech/project/fastapi-cachex)
|
|
40
|
+
[](https://pepy.tech/project/fastapi-cachex)
|
|
41
|
+
[](https://pepy.tech/project/fastapi-cachex)
|
|
42
|
+
|
|
43
|
+
[](https://pypi.org/project/fastapi-cachex)
|
|
44
|
+
[](https://pypi.org/project/fastapi-cachex/)
|
|
45
|
+
|
|
46
|
+
[English](README.md) | [繁體中文](docs/README.zh-TW.md)
|
|
47
|
+
|
|
48
|
+
A high-performance caching extension for FastAPI, providing comprehensive HTTP caching support.
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- Support for HTTP caching headers
|
|
53
|
+
- `Cache-Control`
|
|
54
|
+
- `ETag`
|
|
55
|
+
- `If-None-Match`
|
|
56
|
+
- Multiple backend cache support
|
|
57
|
+
- Redis
|
|
58
|
+
- Memcached
|
|
59
|
+
- In-memory cache
|
|
60
|
+
- Complete Cache-Control directive implementation
|
|
61
|
+
- Easy-to-use `@cache` decorator
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### Using pip
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install fastapi-cachex
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Using uv (recommended)
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
uv pip install fastapi-cachex
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Quick Start
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from fastapi import FastAPI
|
|
81
|
+
from fastapi_cachex import cache, BackendProxy
|
|
82
|
+
from fastapi_cachex.backends import MemoryBackend, MemcachedBackend
|
|
83
|
+
|
|
84
|
+
app = FastAPI()
|
|
85
|
+
|
|
86
|
+
# Configure your cache backend
|
|
87
|
+
memory_backend = MemoryBackend() # In-memory cache
|
|
88
|
+
# or
|
|
89
|
+
memcached_backend = MemcachedBackend(servers=["localhost:11211"]) # Memcached
|
|
90
|
+
|
|
91
|
+
# Set the backend you want to use
|
|
92
|
+
BackendProxy.set_backend(memory_backend) # or memcached_backend
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@app.get("/")
|
|
96
|
+
@cache(ttl=60) # Cache for 60 seconds
|
|
97
|
+
async def read_root():
|
|
98
|
+
return {"Hello": "World"}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Backend Configuration
|
|
102
|
+
|
|
103
|
+
FastAPI-CacheX supports multiple caching backends. You can easily switch between them using the `BackendProxy`.
|
|
104
|
+
|
|
105
|
+
### In-Memory Cache
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from fastapi_cachex.backends import MemoryBackend
|
|
109
|
+
from fastapi_cachex import BackendProxy
|
|
110
|
+
|
|
111
|
+
backend = MemoryBackend()
|
|
112
|
+
BackendProxy.set_backend(backend)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Memcached
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from fastapi_cachex.backends import MemcachedBackend
|
|
119
|
+
from fastapi_cachex import BackendProxy
|
|
120
|
+
|
|
121
|
+
backend = MemcachedBackend(servers=["localhost:11211"])
|
|
122
|
+
BackendProxy.set_backend(backend)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Redis (Coming Soon)
|
|
126
|
+
|
|
127
|
+
Redis support is under development and will be available in future releases.
|
|
128
|
+
|
|
129
|
+
## Development Guide
|
|
130
|
+
|
|
131
|
+
### Running Tests
|
|
132
|
+
|
|
133
|
+
1. Run unit tests:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pytest
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
2. Run tests with coverage report:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pytest --cov=fastapi_cachex
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Using tox
|
|
146
|
+
|
|
147
|
+
tox ensures the code works across different Python versions (3.10-3.13).
|
|
148
|
+
|
|
149
|
+
1. Install all Python versions
|
|
150
|
+
2. Run tox:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
tox
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
To run for a specific Python version:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
tox -e py310 # only run for Python 3.10
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Contributing
|
|
163
|
+
|
|
164
|
+
1. Fork the project
|
|
165
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
166
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
167
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
168
|
+
5. Open a Pull Request
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
@@ -2,13 +2,14 @@ fastapi_cachex/__init__.py,sha256=K8zRD7pEOo77Ged7SJQ-BFNMe6Pnz8yM5ePFq97nI_s,82
|
|
|
2
2
|
fastapi_cachex/cache.py,sha256=oMMPPcGISUWUuzVFhnd3KlgnL4ooMZErJVMQxieYy3A,6631
|
|
3
3
|
fastapi_cachex/directives.py,sha256=kJCmsbyQ89m6tsWo_c1vVJn3rk0pD5JZaY8xtNLcRh0,530
|
|
4
4
|
fastapi_cachex/exceptions.py,sha256=coYct4u6uK_pdjetUWDwM5OUCfhql0OkTECynMRUq4M,379
|
|
5
|
-
fastapi_cachex/proxy.py,sha256=
|
|
5
|
+
fastapi_cachex/proxy.py,sha256=vFShY7_xp4Sh1XU9dJzsBv2ICN8Rtwx6g1qCcCvmdf8,810
|
|
6
6
|
fastapi_cachex/types.py,sha256=YkXlBARIr5lHQE4PYQrwXjEoLHdz9CIjfX7V-S9N8p0,328
|
|
7
|
-
fastapi_cachex/backends/__init__.py,sha256=
|
|
7
|
+
fastapi_cachex/backends/__init__.py,sha256=U65JrCeh1eusklqUfV5yvZGK7Kfy5RctzfVrRfFPuaI,166
|
|
8
8
|
fastapi_cachex/backends/base.py,sha256=eGfn0oZNQ8_drNHz4ZtqBVFSxKxEwW8y4ojw5iShgLQ,707
|
|
9
|
+
fastapi_cachex/backends/memcached.py,sha256=g3184fHpFK7LH1UY9xfzRszBBzqmzeaLG806B5MsZDM,2190
|
|
9
10
|
fastapi_cachex/backends/memory.py,sha256=-69k5-HwNzAPumemy-17LBZuBzUcA-qYhz2qCzVTOCc,2419
|
|
10
|
-
fastapi_cachex-0.1.
|
|
11
|
-
fastapi_cachex-0.1.
|
|
12
|
-
fastapi_cachex-0.1.
|
|
13
|
-
fastapi_cachex-0.1.
|
|
14
|
-
fastapi_cachex-0.1.
|
|
11
|
+
fastapi_cachex-0.1.2.dist-info/licenses/LICENSE,sha256=asJkHbd10YDSnjeAOIlKafh7E_exwtKXY5rA-qc_Mno,11339
|
|
12
|
+
fastapi_cachex-0.1.2.dist-info/METADATA,sha256=VIrxJdGN6n_YjWcFCPrCcYS_rsGIOEYtA5QLjRfQ9d0,5224
|
|
13
|
+
fastapi_cachex-0.1.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
14
|
+
fastapi_cachex-0.1.2.dist-info/top_level.txt,sha256=97FfG5FDycd3hks-_JznEr-5lUOgg8AZd8pqK5imWj0,15
|
|
15
|
+
fastapi_cachex-0.1.2.dist-info/RECORD,,
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: fastapi-cachex
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Add your description here
|
|
5
|
-
Requires-Python: >=3.10
|
|
6
|
-
Description-Content-Type: text/markdown
|
|
7
|
-
License-File: LICENSE
|
|
8
|
-
Requires-Dist: fastapi>=0.115.12
|
|
9
|
-
Requires-Dist: httpx>=0.28.1
|
|
10
|
-
Dynamic: license-file
|
|
11
|
-
|
|
12
|
-
# FastAPI-Cache X
|
|
13
|
-
|
|
14
|
-
[](https://github.com/astral-sh/uv)
|
|
15
|
-
[](https://github.com/astral-sh/ruff)
|
|
16
|
-
[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
|
|
17
|
-
[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
|
|
18
|
-
|
|
19
|
-
[](https://badge.fury.io/py/fastapi-cachex)
|
|
20
|
-
[](https://pypi.org/project/fastapi-cachex/)
|
|
21
|
-
|
|
22
|
-
[English](README.md) | [繁體中文](docs/README.zh-TW.md)
|
|
23
|
-
|
|
24
|
-
A high-performance caching extension for FastAPI, providing comprehensive HTTP caching support.
|
|
25
|
-
|
|
26
|
-
## Features
|
|
27
|
-
|
|
28
|
-
- Support for HTTP caching headers
|
|
29
|
-
- `Cache-Control`
|
|
30
|
-
- `ETag`
|
|
31
|
-
- `If-None-Match`
|
|
32
|
-
- Multiple backend cache support
|
|
33
|
-
- Redis
|
|
34
|
-
- Memcached
|
|
35
|
-
- In-memory cache
|
|
36
|
-
- Complete Cache-Control directive implementation
|
|
37
|
-
- Easy-to-use `@cache` decorator
|
|
38
|
-
|
|
39
|
-
## Installation
|
|
40
|
-
|
|
41
|
-
### Using pip
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
pip install fastapi-cachex
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Using uv (recommended)
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
uv pip install fastapi-cachex
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Quick Start
|
|
54
|
-
|
|
55
|
-
```python
|
|
56
|
-
from fastapi import FastAPI
|
|
57
|
-
from fastapi_cachex import cache
|
|
58
|
-
|
|
59
|
-
app = FastAPI()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@app.get("/")
|
|
63
|
-
@cache()
|
|
64
|
-
async def read_root():
|
|
65
|
-
return {"Hello": "World"}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Development Guide
|
|
69
|
-
|
|
70
|
-
### Running Tests
|
|
71
|
-
|
|
72
|
-
1. Run unit tests:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
pytest
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
2. Run tests with coverage report:
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
pytest --cov=fastapi_cachex
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Using tox
|
|
85
|
-
|
|
86
|
-
tox ensures the code works across different Python versions (3.10-3.13).
|
|
87
|
-
|
|
88
|
-
1. Install all Python versions
|
|
89
|
-
2. Run tox:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
tox
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
To run for a specific Python version:
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
tox -e py310 # only run for Python 3.10
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Contributing
|
|
102
|
-
|
|
103
|
-
1. Fork the project
|
|
104
|
-
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
105
|
-
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
106
|
-
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
107
|
-
5. Open a Pull Request
|
|
108
|
-
|
|
109
|
-
## License
|
|
110
|
-
|
|
111
|
-
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|