fastapi-cachex 0.1.1__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.

@@ -1,2 +1,3 @@
1
1
  from .base import BaseCacheBackend as BaseCacheBackend
2
+ from .memcached import MemcachedBackend as MemcachedBackend
2
3
  from .memory import MemoryBackend as MemoryBackend
@@ -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 | None = None
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-cachex
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: A caching library for FastAPI with support for Cache-Control, ETag, and multiple backends.
5
5
  Author-email: Allen <s96016641@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -25,6 +25,8 @@ Description-Content-Type: text/markdown
25
25
  License-File: LICENSE
26
26
  Requires-Dist: fastapi
27
27
  Requires-Dist: httpx
28
+ Provides-Extra: memcache
29
+ Requires-Dist: pymemcache; extra == "memcache"
28
30
  Dynamic: license-file
29
31
 
30
32
  # FastAPI-Cache X
@@ -34,8 +36,12 @@ Dynamic: license-file
34
36
  [![Tests](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml/badge.svg)](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
35
37
  [![Coverage Status](https://raw.githubusercontent.com/allen0099/FastAPI-CacheX/coverage-badge/coverage.svg)](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
36
38
 
37
- [![PyPI version](https://badge.fury.io/py/fastapi-cachex.svg)](https://badge.fury.io/py/fastapi-cachex)
38
- [![Python Versions](https://img.shields.io/pypi/pyversions/fastapi-cachex.svg)](https://pypi.org/project/fastapi-cachex/)
39
+ [![Downloads](https://static.pepy.tech/badge/fastapi-cachex)](https://pepy.tech/project/fastapi-cachex)
40
+ [![Weekly downloads](https://static.pepy.tech/badge/fastapi-cachex/week)](https://pepy.tech/project/fastapi-cachex)
41
+ [![Monthly downloads](https://static.pepy.tech/badge/fastapi-cachex/month)](https://pepy.tech/project/fastapi-cachex)
42
+
43
+ [![PyPI version](https://img.shields.io/pypi/v/fastapi-cachex.svg?logo=pypi&logoColor=gold&label=PyPI)](https://pypi.org/project/fastapi-cachex)
44
+ [![Python Versions](https://img.shields.io/pypi/pyversions/fastapi-cachex.svg?logo=python&label=Python&logoColor=gold)](https://pypi.org/project/fastapi-cachex/)
39
45
 
40
46
  [English](README.md) | [繁體中文](docs/README.zh-TW.md)
41
47
 
@@ -72,17 +78,54 @@ uv pip install fastapi-cachex
72
78
 
73
79
  ```python
74
80
  from fastapi import FastAPI
75
- from fastapi_cachex import cache
81
+ from fastapi_cachex import cache, BackendProxy
82
+ from fastapi_cachex.backends import MemoryBackend, MemcachedBackend
76
83
 
77
84
  app = FastAPI()
78
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
+
79
94
 
80
95
  @app.get("/")
81
- @cache()
96
+ @cache(ttl=60) # Cache for 60 seconds
82
97
  async def read_root():
83
98
  return {"Hello": "World"}
84
99
  ```
85
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
+
86
129
  ## Development Guide
87
130
 
88
131
  ### Running Tests
@@ -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=4o38sdf1mT3dgFaY06dk9ADojfBUiFhZkxdaEg5dVo4,654
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=khEnP_GmZHJXAjfqZ35uQRYMtJQTmcQxNC2y2r8Pz5w,106
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.1.dist-info/licenses/LICENSE,sha256=asJkHbd10YDSnjeAOIlKafh7E_exwtKXY5rA-qc_Mno,11339
11
- fastapi_cachex-0.1.1.dist-info/METADATA,sha256=8d1xhC1CdfqRsDzep4UBK6mfPzzkPGGR14tabTxHm7U,3709
12
- fastapi_cachex-0.1.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
13
- fastapi_cachex-0.1.1.dist-info/top_level.txt,sha256=97FfG5FDycd3hks-_JznEr-5lUOgg8AZd8pqK5imWj0,15
14
- fastapi_cachex-0.1.1.dist-info/RECORD,,
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,,