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.
Files changed (30) hide show
  1. {hishel-0.0.23 → hishel-0.0.25}/CHANGELOG.md +11 -1
  2. {hishel-0.0.23 → hishel-0.0.25}/PKG-INFO +13 -3
  3. {hishel-0.0.23 → hishel-0.0.25}/hishel/__init__.py +1 -1
  4. {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_mock.py +1 -2
  5. {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_storages.py +7 -1
  6. {hishel-0.0.23 → hishel-0.0.25}/hishel/_controller.py +6 -2
  7. hishel-0.0.25/hishel/_exceptions.py +10 -0
  8. {hishel-0.0.23 → hishel-0.0.25}/hishel/_headers.py +0 -6
  9. {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_mock.py +1 -2
  10. {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_storages.py +7 -1
  11. {hishel-0.0.23 → hishel-0.0.25}/pyproject.toml +4 -2
  12. hishel-0.0.23/hishel/_exceptions.py +0 -13
  13. {hishel-0.0.23 → hishel-0.0.25}/.gitignore +0 -0
  14. {hishel-0.0.23 → hishel-0.0.25}/LICENSE +0 -0
  15. {hishel-0.0.23 → hishel-0.0.25}/README.md +0 -0
  16. {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/__init__.py +0 -0
  17. {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_client.py +0 -0
  18. {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_pool.py +0 -0
  19. {hishel-0.0.23 → hishel-0.0.25}/hishel/_async/_transports.py +0 -0
  20. {hishel-0.0.23 → hishel-0.0.25}/hishel/_files.py +0 -0
  21. {hishel-0.0.23 → hishel-0.0.25}/hishel/_lfu_cache.py +0 -0
  22. {hishel-0.0.23 → hishel-0.0.25}/hishel/_s3.py +0 -0
  23. {hishel-0.0.23 → hishel-0.0.25}/hishel/_serializers.py +0 -0
  24. {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/__init__.py +0 -0
  25. {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_client.py +0 -0
  26. {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_pool.py +0 -0
  27. {hishel-0.0.23 → hishel-0.0.25}/hishel/_sync/_transports.py +0 -0
  28. {hishel-0.0.23 → hishel-0.0.25}/hishel/_synchronization.py +0 -0
  29. {hishel-0.0.23 → hishel-0.0.25}/hishel/_utils.py +0 -0
  30. {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.23 (12th February, 2024)
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
1
+ Metadata-Version: 2.3
2
2
  Name: hishel
3
- Version: 0.0.23
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.23 (12th February, 2024)
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)
@@ -14,4 +14,4 @@ def install_cache() -> None: # pragma: no cover
14
14
  httpx.Client = CacheClient # type: ignore
15
15
 
16
16
 
17
- __version__ = "0.0.23"
17
+ __version__ = "0.0.25"
@@ -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 request.extensions.get("force_cache", False):
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
- if request.extensions.get("force_cache", False):
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
@@ -0,0 +1,10 @@
1
+ __all__ = ("CacheControlError", "ParseError", "ValidationError")
2
+
3
+
4
+ class CacheControlError(Exception): ...
5
+
6
+
7
+ class ParseError(CacheControlError): ...
8
+
9
+
10
+ class ValidationError(CacheControlError): ...
@@ -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
@@ -1,13 +0,0 @@
1
- __all__ = ("CacheControlError", "ParseError", "ValidationError")
2
-
3
-
4
- class CacheControlError(Exception):
5
- ...
6
-
7
-
8
- class ParseError(CacheControlError):
9
- ...
10
-
11
-
12
- class ValidationError(CacheControlError):
13
- ...
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