hishel 0.0.23__tar.gz → 0.0.25__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.0.23 → hishel-0.0.25}/CHANGELOG.md +11 -1
- {hishel-0.0.23 → hishel-0.0.25}/PKG-INFO +13 -3
- {hishel-0.0.23 → hishel-0.0.25}/hishel/__init__.py +1 -1
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_mock.py +1 -2
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_storages.py +7 -1
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_controller.py +6 -2
- hishel-0.0.25/hishel/_exceptions.py +10 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_headers.py +0 -6
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_mock.py +1 -2
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_storages.py +7 -1
- {hishel-0.0.23 → hishel-0.0.25}/pyproject.toml +4 -2
- hishel-0.0.23/hishel/_exceptions.py +0 -13
- {hishel-0.0.23 → hishel-0.0.25}/.gitignore +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/LICENSE +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/README.md +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/__init__.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_client.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_pool.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_transports.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_files.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_lfu_cache.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_s3.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_serializers.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/__init__.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_client.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_pool.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_transports.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_synchronization.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/_utils.py +0 -0
- {hishel-0.0.23 → hishel-0.0.25}/hishel/py.typed +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.0.
|
|
3
|
+
## 0.0.25 (26th March, 2024)
|
|
4
|
+
|
|
5
|
+
- Add `force_cache` property to the controller, allowing RFC9111 rules to be completely disabled. (#204)
|
|
6
|
+
- Add `.gitignore` to cache directory created by `FIleStorage`. (#197)
|
|
7
|
+
- Remove `stale_*` headers from the `CacheControl` class. (#199)
|
|
8
|
+
|
|
9
|
+
## 0.0.24 (14th February, 2024)
|
|
10
|
+
|
|
11
|
+
- Fix `botocore is not installed` exception when using any kind of storage. (#186)
|
|
12
|
+
|
|
13
|
+
## 0.0.23 (14th February, 2024)
|
|
4
14
|
|
|
5
15
|
- Make `S3Storage` to check staleness of all cache files with set interval. (#182)
|
|
6
16
|
- Fix an issue where an empty file in `FileCache` could cause a parsing error. (#181)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: hishel
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.25
|
|
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
|
|
@@ -175,7 +175,17 @@ Help us grow and continue developing good software for you ❤️
|
|
|
175
175
|
|
|
176
176
|
# Changelog
|
|
177
177
|
|
|
178
|
-
## 0.0.
|
|
178
|
+
## 0.0.25 (26th March, 2024)
|
|
179
|
+
|
|
180
|
+
- Add `force_cache` property to the controller, allowing RFC9111 rules to be completely disabled. (#204)
|
|
181
|
+
- Add `.gitignore` to cache directory created by `FIleStorage`. (#197)
|
|
182
|
+
- Remove `stale_*` headers from the `CacheControl` class. (#199)
|
|
183
|
+
|
|
184
|
+
## 0.0.24 (14th February, 2024)
|
|
185
|
+
|
|
186
|
+
- Fix `botocore is not installed` exception when using any kind of storage. (#186)
|
|
187
|
+
|
|
188
|
+
## 0.0.23 (14th February, 2024)
|
|
179
189
|
|
|
180
190
|
- Make `S3Storage` to check staleness of all cache files with set interval. (#182)
|
|
181
191
|
- Fix an issue where an empty file in `FileCache` could cause a parsing error. (#181)
|
|
@@ -30,8 +30,7 @@ class MockAsyncConnectionPool(AsyncRequestInterface):
|
|
|
30
30
|
exc_type: tp.Optional[tp.Type[BaseException]] = None,
|
|
31
31
|
exc_value: tp.Optional[BaseException] = None,
|
|
32
32
|
traceback: tp.Optional[TracebackType] = None,
|
|
33
|
-
) -> None:
|
|
34
|
-
...
|
|
33
|
+
) -> None: ...
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
class MockAsyncTransport(httpx.AsyncBaseTransport):
|
|
@@ -7,6 +7,8 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
try:
|
|
9
9
|
import boto3
|
|
10
|
+
|
|
11
|
+
from .._s3 import AsyncS3Manager
|
|
10
12
|
except ImportError: # pragma: no cover
|
|
11
13
|
boto3 = None # type: ignore
|
|
12
14
|
|
|
@@ -21,7 +23,6 @@ from typing_extensions import TypeAlias
|
|
|
21
23
|
from hishel._serializers import BaseSerializer, clone_model
|
|
22
24
|
|
|
23
25
|
from .._files import AsyncFileManager
|
|
24
|
-
from .._s3 import AsyncS3Manager
|
|
25
26
|
from .._serializers import JSONSerializer, Metadata
|
|
26
27
|
from .._synchronization import AsyncLock
|
|
27
28
|
from .._utils import float_seconds_to_int_milliseconds
|
|
@@ -82,10 +83,15 @@ class AsyncFileStorage(AsyncBaseStorage):
|
|
|
82
83
|
super().__init__(serializer, ttl)
|
|
83
84
|
|
|
84
85
|
self._base_path = Path(base_path) if base_path is not None else Path(".cache/hishel")
|
|
86
|
+
self._gitignore_file = self._base_path / ".gitignore"
|
|
85
87
|
|
|
86
88
|
if not self._base_path.is_dir():
|
|
87
89
|
self._base_path.mkdir(parents=True)
|
|
88
90
|
|
|
91
|
+
if not self._gitignore_file.is_file():
|
|
92
|
+
with open(self._gitignore_file, "w", encoding="utf-8") as f:
|
|
93
|
+
f.write("# Automatically created by Hishel\n*")
|
|
94
|
+
|
|
89
95
|
self._file_manager = AsyncFileManager(is_binary=self._serializer.is_binary)
|
|
90
96
|
self._lock = AsyncLock()
|
|
91
97
|
self._check_ttl_every = check_ttl_every
|
|
@@ -111,6 +111,7 @@ class Controller:
|
|
|
111
111
|
clock: tp.Optional[BaseClock] = None,
|
|
112
112
|
allow_stale: bool = False,
|
|
113
113
|
always_revalidate: bool = False,
|
|
114
|
+
force_cache: bool = False,
|
|
114
115
|
key_generator: tp.Optional[tp.Callable[[Request, tp.Optional[bytes]], str]] = None,
|
|
115
116
|
):
|
|
116
117
|
self._cacheable_methods = []
|
|
@@ -131,6 +132,7 @@ class Controller:
|
|
|
131
132
|
self._allow_heuristics = allow_heuristics
|
|
132
133
|
self._allow_stale = allow_stale
|
|
133
134
|
self._always_revalidate = always_revalidate
|
|
135
|
+
self._force_cache = force_cache
|
|
134
136
|
self._key_generator = key_generator or generate_key
|
|
135
137
|
|
|
136
138
|
def is_cachable(self, request: Request, response: Response) -> bool:
|
|
@@ -143,8 +145,9 @@ class Controller:
|
|
|
143
145
|
lists the steps that this method simply follows.
|
|
144
146
|
"""
|
|
145
147
|
method = request.method.decode("ascii")
|
|
148
|
+
force_cache = request.extensions.get("force_cache", None)
|
|
146
149
|
|
|
147
|
-
if
|
|
150
|
+
if force_cache if force_cache is not None else self._force_cache:
|
|
148
151
|
return True
|
|
149
152
|
|
|
150
153
|
if response.status not in self._cacheable_status_codes:
|
|
@@ -279,7 +282,8 @@ class Controller:
|
|
|
279
282
|
return None # pragma: no cover
|
|
280
283
|
|
|
281
284
|
# !!! this should be after the "vary" header validation.
|
|
282
|
-
|
|
285
|
+
force_cache = request.extensions.get("force_cache", None)
|
|
286
|
+
if force_cache if force_cache is not None else self._force_cache:
|
|
283
287
|
return response
|
|
284
288
|
|
|
285
289
|
# the stored response does not contain the
|
|
@@ -38,8 +38,6 @@ BOOLEAN_FIELDS = [
|
|
|
38
38
|
"only_if_cached",
|
|
39
39
|
"public",
|
|
40
40
|
"proxy_revalidate",
|
|
41
|
-
"stale_if_error",
|
|
42
|
-
"stale_while_revalidate",
|
|
43
41
|
]
|
|
44
42
|
|
|
45
43
|
LIST_FIELDS = ["no_cache", "private"]
|
|
@@ -146,8 +144,6 @@ class CacheControl:
|
|
|
146
144
|
proxy_revalidate: bool = False, # [RFC9111, Section 5.2.2.8]
|
|
147
145
|
public: bool = False, # [RFC9111, Section 5.2.2.9]
|
|
148
146
|
s_maxage: Optional[int] = None, # [RFC9111, Section 5.2.2.10]
|
|
149
|
-
stale_if_error: bool = False, # [RFC5861, Section 4]
|
|
150
|
-
stale_while_revalidate: bool = False, # [RFC5861, Section 3]
|
|
151
147
|
) -> None:
|
|
152
148
|
self.immutable = immutable
|
|
153
149
|
self.max_age = max_age
|
|
@@ -163,8 +159,6 @@ class CacheControl:
|
|
|
163
159
|
self.proxy_revalidate = proxy_revalidate
|
|
164
160
|
self.public = public
|
|
165
161
|
self.s_maxage = s_maxage
|
|
166
|
-
self.stale_if_error = stale_if_error
|
|
167
|
-
self.stale_while_revalidate = stale_while_revalidate
|
|
168
162
|
|
|
169
163
|
@classmethod
|
|
170
164
|
def validate(cls, directives: Dict[str, Any]) -> Dict[str, Any]:
|
|
@@ -30,8 +30,7 @@ class MockConnectionPool(RequestInterface):
|
|
|
30
30
|
exc_type: tp.Optional[tp.Type[BaseException]] = None,
|
|
31
31
|
exc_value: tp.Optional[BaseException] = None,
|
|
32
32
|
traceback: tp.Optional[TracebackType] = None,
|
|
33
|
-
) -> None:
|
|
34
|
-
...
|
|
33
|
+
) -> None: ...
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
class MockTransport(httpx.BaseTransport):
|
|
@@ -7,6 +7,8 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
try:
|
|
9
9
|
import boto3
|
|
10
|
+
|
|
11
|
+
from .._s3 import S3Manager
|
|
10
12
|
except ImportError: # pragma: no cover
|
|
11
13
|
boto3 = None # type: ignore
|
|
12
14
|
|
|
@@ -21,7 +23,6 @@ from typing_extensions import TypeAlias
|
|
|
21
23
|
from hishel._serializers import BaseSerializer, clone_model
|
|
22
24
|
|
|
23
25
|
from .._files import FileManager
|
|
24
|
-
from .._s3 import S3Manager
|
|
25
26
|
from .._serializers import JSONSerializer, Metadata
|
|
26
27
|
from .._synchronization import Lock
|
|
27
28
|
from .._utils import float_seconds_to_int_milliseconds
|
|
@@ -82,10 +83,15 @@ class FileStorage(BaseStorage):
|
|
|
82
83
|
super().__init__(serializer, ttl)
|
|
83
84
|
|
|
84
85
|
self._base_path = Path(base_path) if base_path is not None else Path(".cache/hishel")
|
|
86
|
+
self._gitignore_file = self._base_path / ".gitignore"
|
|
85
87
|
|
|
86
88
|
if not self._base_path.is_dir():
|
|
87
89
|
self._base_path.mkdir(parents=True)
|
|
88
90
|
|
|
91
|
+
if not self._gitignore_file.is_file():
|
|
92
|
+
with open(self._gitignore_file, "w", encoding="utf-8") as f:
|
|
93
|
+
f.write("# Automatically created by Hishel\n*")
|
|
94
|
+
|
|
89
95
|
self._file_manager = FileManager(is_binary=self._serializer.is_binary)
|
|
90
96
|
self._lock = Lock()
|
|
91
97
|
self._check_ttl_every = check_ttl_every
|
|
@@ -79,7 +79,7 @@ path = "CHANGELOG.md"
|
|
|
79
79
|
strict = true
|
|
80
80
|
show_error_codes = true
|
|
81
81
|
warn_unused_ignores = false
|
|
82
|
-
|
|
82
|
+
exclude = ['venv', '.venv']
|
|
83
83
|
|
|
84
84
|
[[tool.mypy.overrides]]
|
|
85
85
|
module = "tests.*"
|
|
@@ -112,6 +112,8 @@ exclude = [
|
|
|
112
112
|
"tests/_sync",
|
|
113
113
|
]
|
|
114
114
|
line-length = 120
|
|
115
|
+
|
|
116
|
+
[tool.ruff.lint]
|
|
115
117
|
select = [
|
|
116
118
|
"E",
|
|
117
119
|
"F",
|
|
@@ -119,5 +121,5 @@ select = [
|
|
|
119
121
|
"I"
|
|
120
122
|
]
|
|
121
123
|
|
|
122
|
-
[tool.ruff.isort]
|
|
124
|
+
[tool.ruff.lint.isort]
|
|
123
125
|
combine-as-imports = true
|
|
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
|