hishel 0.0.24__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.24 → hishel-0.0.25}/CHANGELOG.md +6 -0
  2. {hishel-0.0.24 → hishel-0.0.25}/PKG-INFO +8 -2
  3. {hishel-0.0.24 → hishel-0.0.25}/hishel/__init__.py +1 -1
  4. {hishel-0.0.24 → hishel-0.0.25}/hishel/_async/_mock.py +1 -2
  5. {hishel-0.0.24 → hishel-0.0.25}/hishel/_async/_storages.py +5 -0
  6. {hishel-0.0.24 → hishel-0.0.25}/hishel/_controller.py +6 -2
  7. hishel-0.0.25/hishel/_exceptions.py +10 -0
  8. {hishel-0.0.24 → hishel-0.0.25}/hishel/_headers.py +0 -6
  9. {hishel-0.0.24 → hishel-0.0.25}/hishel/_sync/_mock.py +1 -2
  10. {hishel-0.0.24 → hishel-0.0.25}/hishel/_sync/_storages.py +5 -0
  11. {hishel-0.0.24 → hishel-0.0.25}/pyproject.toml +4 -2
  12. hishel-0.0.24/hishel/_exceptions.py +0 -13
  13. {hishel-0.0.24 → hishel-0.0.25}/.gitignore +0 -0
  14. {hishel-0.0.24 → hishel-0.0.25}/LICENSE +0 -0
  15. {hishel-0.0.24 → hishel-0.0.25}/README.md +0 -0
  16. {hishel-0.0.24 → hishel-0.0.25}/hishel/_async/__init__.py +0 -0
  17. {hishel-0.0.24 → hishel-0.0.25}/hishel/_async/_client.py +0 -0
  18. {hishel-0.0.24 → hishel-0.0.25}/hishel/_async/_pool.py +0 -0
  19. {hishel-0.0.24 → hishel-0.0.25}/hishel/_async/_transports.py +0 -0
  20. {hishel-0.0.24 → hishel-0.0.25}/hishel/_files.py +0 -0
  21. {hishel-0.0.24 → hishel-0.0.25}/hishel/_lfu_cache.py +0 -0
  22. {hishel-0.0.24 → hishel-0.0.25}/hishel/_s3.py +0 -0
  23. {hishel-0.0.24 → hishel-0.0.25}/hishel/_serializers.py +0 -0
  24. {hishel-0.0.24 → hishel-0.0.25}/hishel/_sync/__init__.py +0 -0
  25. {hishel-0.0.24 → hishel-0.0.25}/hishel/_sync/_client.py +0 -0
  26. {hishel-0.0.24 → hishel-0.0.25}/hishel/_sync/_pool.py +0 -0
  27. {hishel-0.0.24 → hishel-0.0.25}/hishel/_sync/_transports.py +0 -0
  28. {hishel-0.0.24 → hishel-0.0.25}/hishel/_synchronization.py +0 -0
  29. {hishel-0.0.24 → hishel-0.0.25}/hishel/_utils.py +0 -0
  30. {hishel-0.0.24 → hishel-0.0.25}/hishel/py.typed +0 -0
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
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
+
3
9
  ## 0.0.24 (14th February, 2024)
4
10
 
5
11
  - Fix `botocore is not installed` exception when using any kind of storage. (#186)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: hishel
3
- Version: 0.0.24
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,6 +175,12 @@ Help us grow and continue developing good software for you ❤️
175
175
 
176
176
  # Changelog
177
177
 
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
+
178
184
  ## 0.0.24 (14th February, 2024)
179
185
 
180
186
  - Fix `botocore is not installed` exception when using any kind of storage. (#186)
@@ -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.24"
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):
@@ -83,10 +83,15 @@ class AsyncFileStorage(AsyncBaseStorage):
83
83
  super().__init__(serializer, ttl)
84
84
 
85
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"
86
87
 
87
88
  if not self._base_path.is_dir():
88
89
  self._base_path.mkdir(parents=True)
89
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
+
90
95
  self._file_manager = AsyncFileManager(is_binary=self._serializer.is_binary)
91
96
  self._lock = AsyncLock()
92
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):
@@ -83,10 +83,15 @@ class FileStorage(BaseStorage):
83
83
  super().__init__(serializer, ttl)
84
84
 
85
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"
86
87
 
87
88
  if not self._base_path.is_dir():
88
89
  self._base_path.mkdir(parents=True)
89
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
+
90
95
  self._file_manager = FileManager(is_binary=self._serializer.is_binary)
91
96
  self._lock = Lock()
92
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