hishel 0.1.2__tar.gz → 0.1.3__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.
- {hishel-0.1.2 → hishel-0.1.3}/CHANGELOG.md +7 -0
- {hishel-0.1.2 → hishel-0.1.3}/PKG-INFO +10 -3
- {hishel-0.1.2 → hishel-0.1.3}/hishel/__init__.py +1 -1
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_async/_storages.py +7 -3
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_s3.py +19 -8
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_sync/_storages.py +6 -2
- {hishel-0.1.2 → hishel-0.1.3}/pyproject.toml +3 -4
- {hishel-0.1.2 → hishel-0.1.3}/.gitignore +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/LICENSE +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/README.md +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_async/__init__.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_async/_client.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_async/_mock.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_async/_pool.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_async/_transports.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_controller.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_exceptions.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_files.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_headers.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_lfu_cache.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_serializers.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_sync/__init__.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_sync/_client.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_sync/_mock.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_sync/_pool.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_sync/_transports.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_synchronization.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/_utils.py +0 -0
- {hishel-0.1.2 → hishel-0.1.3}/hishel/py.typed +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.3 (1st July, 2025)
|
|
4
|
+
|
|
5
|
+
- Remove `types-redis` from dev dependencies (#336)
|
|
6
|
+
- Bump redis to 6.0.0 and address async `.close()` deprecation warning (#336)
|
|
7
|
+
- Avoid race condition when unlinking files in `FileStorage`. (#334)
|
|
8
|
+
- Allow prodiving a `path_prefix` in `S3Storage` and `AsyncS3Storage`. (#342)
|
|
9
|
+
|
|
3
10
|
## 0.1.2 (5th April, 2025)
|
|
4
11
|
|
|
5
12
|
- Add check for fips compliant python. (#325)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hishel
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Persistent cache implementation for httpx and httpcore
|
|
5
5
|
Project-URL: Homepage, https://hishel.com
|
|
6
6
|
Project-URL: Source, https://github.com/karpetrosyan/hishel
|
|
@@ -25,14 +25,14 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
25
25
|
Requires-Python: >=3.9
|
|
26
26
|
Requires-Dist: httpx>=0.28.0
|
|
27
27
|
Provides-Extra: redis
|
|
28
|
-
Requires-Dist: redis==
|
|
28
|
+
Requires-Dist: redis==6.2.0; extra == 'redis'
|
|
29
29
|
Provides-Extra: s3
|
|
30
30
|
Requires-Dist: boto3<=1.15.3,>=1.15.0; (python_version < '3.12') and extra == 's3'
|
|
31
31
|
Requires-Dist: boto3>=1.15.3; (python_version >= '3.12') and extra == 's3'
|
|
32
32
|
Provides-Extra: sqlite
|
|
33
33
|
Requires-Dist: anysqlite>=0.0.5; extra == 'sqlite'
|
|
34
34
|
Provides-Extra: yaml
|
|
35
|
-
Requires-Dist: pyyaml==6.0.
|
|
35
|
+
Requires-Dist: pyyaml==6.0.2; extra == 'yaml'
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
38
|
<p align="center" class="logo">
|
|
@@ -181,6 +181,13 @@ Help us grow and continue developing good software for you ❤️
|
|
|
181
181
|
|
|
182
182
|
# Changelog
|
|
183
183
|
|
|
184
|
+
## 0.1.3 (1st July, 2025)
|
|
185
|
+
|
|
186
|
+
- Remove `types-redis` from dev dependencies (#336)
|
|
187
|
+
- Bump redis to 6.0.0 and address async `.close()` deprecation warning (#336)
|
|
188
|
+
- Avoid race condition when unlinking files in `FileStorage`. (#334)
|
|
189
|
+
- Allow prodiving a `path_prefix` in `S3Storage` and `AsyncS3Storage`. (#342)
|
|
190
|
+
|
|
184
191
|
## 0.1.2 (5th April, 2025)
|
|
185
192
|
|
|
186
193
|
- Add check for fips compliant python. (#325)
|
|
@@ -159,7 +159,7 @@ class AsyncFileStorage(AsyncBaseStorage):
|
|
|
159
159
|
|
|
160
160
|
async with self._lock:
|
|
161
161
|
if response_path.exists():
|
|
162
|
-
response_path.unlink()
|
|
162
|
+
response_path.unlink(missing_ok=True)
|
|
163
163
|
|
|
164
164
|
async def update_metadata(self, key: str, response: Response, request: Request, metadata: Metadata) -> None:
|
|
165
165
|
"""
|
|
@@ -222,7 +222,7 @@ class AsyncFileStorage(AsyncBaseStorage):
|
|
|
222
222
|
if response_path.is_file():
|
|
223
223
|
age = time.time() - response_path.stat().st_mtime
|
|
224
224
|
if age > self._ttl:
|
|
225
|
-
response_path.unlink()
|
|
225
|
+
response_path.unlink(missing_ok=True)
|
|
226
226
|
return
|
|
227
227
|
|
|
228
228
|
self._last_cleaned = time.monotonic()
|
|
@@ -507,7 +507,7 @@ class AsyncRedisStorage(AsyncBaseStorage):
|
|
|
507
507
|
return self._serializer.loads(cached_response)
|
|
508
508
|
|
|
509
509
|
async def aclose(self) -> None: # pragma: no cover
|
|
510
|
-
await self._client.
|
|
510
|
+
await self._client.aclose()
|
|
511
511
|
|
|
512
512
|
|
|
513
513
|
class AsyncInMemoryStorage(AsyncBaseStorage):
|
|
@@ -654,6 +654,8 @@ class AsyncS3Storage(AsyncBaseStorage): # pragma: no cover
|
|
|
654
654
|
:type check_ttl_every: tp.Union[int, float]
|
|
655
655
|
:param client: A client for S3, defaults to None
|
|
656
656
|
:type client: tp.Optional[tp.Any], optional
|
|
657
|
+
:param path_prefix: A path prefix to use for S3 object keys, defaults to "hishel-"
|
|
658
|
+
:type path_prefix: str, optional
|
|
657
659
|
"""
|
|
658
660
|
|
|
659
661
|
def __init__(
|
|
@@ -663,6 +665,7 @@ class AsyncS3Storage(AsyncBaseStorage): # pragma: no cover
|
|
|
663
665
|
ttl: tp.Optional[tp.Union[int, float]] = None,
|
|
664
666
|
check_ttl_every: tp.Union[int, float] = 60,
|
|
665
667
|
client: tp.Optional[tp.Any] = None,
|
|
668
|
+
path_prefix: str = "hishel-",
|
|
666
669
|
) -> None:
|
|
667
670
|
super().__init__(serializer, ttl)
|
|
668
671
|
|
|
@@ -680,6 +683,7 @@ class AsyncS3Storage(AsyncBaseStorage): # pragma: no cover
|
|
|
680
683
|
bucket_name=bucket_name,
|
|
681
684
|
is_binary=self._serializer.is_binary,
|
|
682
685
|
check_ttl_every=check_ttl_every,
|
|
686
|
+
path_prefix=path_prefix,
|
|
683
687
|
)
|
|
684
688
|
self._lock = AsyncLock()
|
|
685
689
|
|
|
@@ -11,16 +11,22 @@ def get_timestamp_in_ms() -> float:
|
|
|
11
11
|
|
|
12
12
|
class S3Manager:
|
|
13
13
|
def __init__(
|
|
14
|
-
self,
|
|
14
|
+
self,
|
|
15
|
+
client: tp.Any,
|
|
16
|
+
bucket_name: str,
|
|
17
|
+
check_ttl_every: tp.Union[int, float],
|
|
18
|
+
is_binary: bool = False,
|
|
19
|
+
path_prefix: str = "hishel-",
|
|
15
20
|
):
|
|
16
21
|
self._client = client
|
|
17
22
|
self._bucket_name = bucket_name
|
|
18
23
|
self._is_binary = is_binary
|
|
19
24
|
self._last_cleaned = time.monotonic()
|
|
20
25
|
self._check_ttl_every = check_ttl_every
|
|
26
|
+
self._path_prefix = path_prefix
|
|
21
27
|
|
|
22
28
|
def write_to(self, path: str, data: tp.Union[bytes, str], only_metadata: bool = False) -> None:
|
|
23
|
-
path =
|
|
29
|
+
path = self._path_prefix + path
|
|
24
30
|
if isinstance(data, str):
|
|
25
31
|
data = data.encode("utf-8")
|
|
26
32
|
|
|
@@ -43,7 +49,7 @@ class S3Manager:
|
|
|
43
49
|
)
|
|
44
50
|
|
|
45
51
|
def read_from(self, path: str) -> tp.Union[bytes, str]:
|
|
46
|
-
path =
|
|
52
|
+
path = self._path_prefix + path
|
|
47
53
|
response = self._client.get_object(
|
|
48
54
|
Bucket=self._bucket_name,
|
|
49
55
|
Key=path,
|
|
@@ -57,7 +63,7 @@ class S3Manager:
|
|
|
57
63
|
return tp.cast(str, content.decode("utf-8"))
|
|
58
64
|
|
|
59
65
|
def remove_expired(self, ttl: int, key: str) -> None:
|
|
60
|
-
path =
|
|
66
|
+
path = self._path_prefix + key
|
|
61
67
|
|
|
62
68
|
if time.monotonic() - self._last_cleaned < self._check_ttl_every:
|
|
63
69
|
try:
|
|
@@ -72,7 +78,7 @@ class S3Manager:
|
|
|
72
78
|
|
|
73
79
|
self._last_cleaned = time.monotonic()
|
|
74
80
|
for obj in self._client.list_objects(Bucket=self._bucket_name).get("Contents", []):
|
|
75
|
-
if not obj["Key"].startswith(
|
|
81
|
+
if not obj["Key"].startswith(self._path_prefix): # pragma: no cover
|
|
76
82
|
continue
|
|
77
83
|
|
|
78
84
|
try:
|
|
@@ -88,15 +94,20 @@ class S3Manager:
|
|
|
88
94
|
self._client.delete_object(Bucket=self._bucket_name, Key=obj["Key"])
|
|
89
95
|
|
|
90
96
|
def remove_entry(self, key: str) -> None:
|
|
91
|
-
path =
|
|
97
|
+
path = self._path_prefix + key
|
|
92
98
|
self._client.delete_object(Bucket=self._bucket_name, Key=path)
|
|
93
99
|
|
|
94
100
|
|
|
95
101
|
class AsyncS3Manager: # pragma: no cover
|
|
96
102
|
def __init__(
|
|
97
|
-
self,
|
|
103
|
+
self,
|
|
104
|
+
client: tp.Any,
|
|
105
|
+
bucket_name: str,
|
|
106
|
+
check_ttl_every: tp.Union[int, float],
|
|
107
|
+
is_binary: bool = False,
|
|
108
|
+
path_prefix: str = "hishel-",
|
|
98
109
|
):
|
|
99
|
-
self._sync_manager = S3Manager(client, bucket_name, check_ttl_every, is_binary)
|
|
110
|
+
self._sync_manager = S3Manager(client, bucket_name, check_ttl_every, is_binary, path_prefix)
|
|
100
111
|
|
|
101
112
|
async def write_to(self, path: str, data: tp.Union[bytes, str], only_metadata: bool = False) -> None:
|
|
102
113
|
return await to_thread.run_sync(self._sync_manager.write_to, path, data, only_metadata)
|
|
@@ -159,7 +159,7 @@ class FileStorage(BaseStorage):
|
|
|
159
159
|
|
|
160
160
|
with self._lock:
|
|
161
161
|
if response_path.exists():
|
|
162
|
-
response_path.unlink()
|
|
162
|
+
response_path.unlink(missing_ok=True)
|
|
163
163
|
|
|
164
164
|
def update_metadata(self, key: str, response: Response, request: Request, metadata: Metadata) -> None:
|
|
165
165
|
"""
|
|
@@ -222,7 +222,7 @@ class FileStorage(BaseStorage):
|
|
|
222
222
|
if response_path.is_file():
|
|
223
223
|
age = time.time() - response_path.stat().st_mtime
|
|
224
224
|
if age > self._ttl:
|
|
225
|
-
response_path.unlink()
|
|
225
|
+
response_path.unlink(missing_ok=True)
|
|
226
226
|
return
|
|
227
227
|
|
|
228
228
|
self._last_cleaned = time.monotonic()
|
|
@@ -654,6 +654,8 @@ class S3Storage(BaseStorage): # pragma: no cover
|
|
|
654
654
|
:type check_ttl_every: tp.Union[int, float]
|
|
655
655
|
:param client: A client for S3, defaults to None
|
|
656
656
|
:type client: tp.Optional[tp.Any], optional
|
|
657
|
+
:param path_prefix: A path prefix to use for S3 object keys, defaults to "hishel-"
|
|
658
|
+
:type path_prefix: str, optional
|
|
657
659
|
"""
|
|
658
660
|
|
|
659
661
|
def __init__(
|
|
@@ -663,6 +665,7 @@ class S3Storage(BaseStorage): # pragma: no cover
|
|
|
663
665
|
ttl: tp.Optional[tp.Union[int, float]] = None,
|
|
664
666
|
check_ttl_every: tp.Union[int, float] = 60,
|
|
665
667
|
client: tp.Optional[tp.Any] = None,
|
|
668
|
+
path_prefix: str = "hishel-",
|
|
666
669
|
) -> None:
|
|
667
670
|
super().__init__(serializer, ttl)
|
|
668
671
|
|
|
@@ -680,6 +683,7 @@ class S3Storage(BaseStorage): # pragma: no cover
|
|
|
680
683
|
bucket_name=bucket_name,
|
|
681
684
|
is_binary=self._serializer.is_binary,
|
|
682
685
|
check_ttl_every=check_ttl_every,
|
|
686
|
+
path_prefix=path_prefix,
|
|
683
687
|
)
|
|
684
688
|
self._lock = Lock()
|
|
685
689
|
|
|
@@ -35,11 +35,11 @@ dependencies = [
|
|
|
35
35
|
[project.optional-dependencies]
|
|
36
36
|
|
|
37
37
|
yaml = [
|
|
38
|
-
"pyyaml==6.0.
|
|
38
|
+
"pyyaml==6.0.2",
|
|
39
39
|
]
|
|
40
40
|
|
|
41
41
|
redis = [
|
|
42
|
-
"redis==
|
|
42
|
+
"redis==6.2.0"
|
|
43
43
|
]
|
|
44
44
|
|
|
45
45
|
sqlite = [
|
|
@@ -92,7 +92,7 @@ filterwarnings = []
|
|
|
92
92
|
|
|
93
93
|
[tool.coverage.run]
|
|
94
94
|
omit = [
|
|
95
|
-
"venv/*",
|
|
95
|
+
"venv/*",
|
|
96
96
|
"hishel/_sync/*",
|
|
97
97
|
"hishel/_s3.py"
|
|
98
98
|
]
|
|
@@ -136,6 +136,5 @@ dev = [
|
|
|
136
136
|
"trio==0.28.0",
|
|
137
137
|
"types-boto3==1.0.2",
|
|
138
138
|
"types-pyyaml==6.0.12.20240311",
|
|
139
|
-
"types-redis==4.6.0.20240425",
|
|
140
139
|
"zipp>=3.19.1",
|
|
141
140
|
]
|
|
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
|
|
File without changes
|