hishel 0.0.23__py3-none-any.whl → 0.0.25__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.
hishel/__init__.py CHANGED
@@ -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"
hishel/_async/_mock.py CHANGED
@@ -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
hishel/_controller.py CHANGED
@@ -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
hishel/_exceptions.py CHANGED
@@ -1,13 +1,10 @@
1
1
  __all__ = ("CacheControlError", "ParseError", "ValidationError")
2
2
 
3
3
 
4
- class CacheControlError(Exception):
5
- ...
4
+ class CacheControlError(Exception): ...
6
5
 
7
6
 
8
- class ParseError(CacheControlError):
9
- ...
7
+ class ParseError(CacheControlError): ...
10
8
 
11
9
 
12
- class ValidationError(CacheControlError):
13
- ...
10
+ class ValidationError(CacheControlError): ...
hishel/_headers.py CHANGED
@@ -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]:
hishel/_sync/_mock.py CHANGED
@@ -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):
hishel/_sync/_storages.py CHANGED
@@ -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
@@ -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)
@@ -1,8 +1,8 @@
1
- hishel/__init__.py,sha256=nC3vY9bcbL4hoNFGweMIdW2_1XeW9Uqrkeh2oY14LsE,369
2
- hishel/_controller.py,sha256=Xw8JoqGZ5QTtR0u2pZTYMyi5ZASlGlBaKSVaoVEZTOI,15241
3
- hishel/_exceptions.py,sha256=QjHcJeNLXtSVhvVuqxSi9eRz0QpfQNrcCLnPGex7chw,210
1
+ hishel/__init__.py,sha256=2FeYWinWo-PLSBIu_uD-zHIKwiv2vTnc8FdWLq6hfAY,369
2
+ hishel/_controller.py,sha256=WHpztkcL-eL04lQK4ZTLEOfg-FzmS3nHx82K5bhtT9M,15482
3
+ hishel/_exceptions.py,sha256=qbg55RNlzwhv5JreWY9Zog_zmmiKdn5degtqJKijuRs,198
4
4
  hishel/_files.py,sha256=7J5uX7Nnzd7QQWfYuDGh8v6XGLG3eUDBjoJZ4aTaY1c,2228
5
- hishel/_headers.py,sha256=8M4fAkAEmUab-wFCrLyFavHP8nu1VdKksjXyOLEZKAc,7619
5
+ hishel/_headers.py,sha256=TWuHi7sRoeS2xxdNGujKmqWtgncUqfhNGCgHKYpRU-I,7329
6
6
  hishel/_lfu_cache.py,sha256=0KJCCnwigPsZ_xKmE7AjdjPRuMFmNcjGWS-mDnbtZVQ,2730
7
7
  hishel/_s3.py,sha256=GAqEADmvalUqRoVygAK6ju3OiL23XXrxiA3cg3AWbSs,2913
8
8
  hishel/_serializers.py,sha256=-KySCCgBqRCeN3SrfJJoiHvef6irnqwYkGj4jGMOjgI,11736
@@ -11,17 +11,17 @@ hishel/_utils.py,sha256=cgLGjBI7H-T_DkYBXiHiEEf8SGjGeZ6Cc2IHbLAZybU,2501
11
11
  hishel/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  hishel/_async/__init__.py,sha256=_oAltH4emAtUF7_9SSxz_KKGYzSXL34o_EGgGvoPG7E,187
13
13
  hishel/_async/_client.py,sha256=AkVSSbNTTHmK0gX6PRYVQ-3aDbuCX2Im4VKbLkwLiBU,1101
14
- hishel/_async/_mock.py,sha256=zmPUq-15Y0GrFBejdiO-SahNnPEbym38cpR_Dz5Qp4A,1523
14
+ hishel/_async/_mock.py,sha256=995v9p5xiw3svGSOJATkLMqwodlhZhcwmGygLHM2VFw,1515
15
15
  hishel/_async/_pool.py,sha256=3hXRG3ljG8jChHoJeI7oVHqQsFPzKNDxaq24rknKPwc,6553
16
- hishel/_async/_storages.py,sha256=lCbNwy1aeHskbOEIuCFIZkaNdrKgI9QuszYshlWSG1A,19176
16
+ hishel/_async/_storages.py,sha256=I64JwCX0w6YnQH-49R5ha7UcEe3y9HCfF-uydNrGb_Q,19428
17
17
  hishel/_async/_transports.py,sha256=_UYBbLstk2I3AruGceLiazN5trnY4rDyB8kdEWeurvc,10125
18
18
  hishel/_sync/__init__.py,sha256=_oAltH4emAtUF7_9SSxz_KKGYzSXL34o_EGgGvoPG7E,187
19
19
  hishel/_sync/_client.py,sha256=O-gwm9DsveKtSFUfqdbBB-3I1FmXr5rE-uQ7X5frwDA,1060
20
- hishel/_sync/_mock.py,sha256=jqy89epiAIE6mk3dVzIlom-ZJVFKXWwM6k5aThSUglE,1438
20
+ hishel/_sync/_mock.py,sha256=im88tZr-XhP9BpzvIt3uOjndAlNcJvFP7Puv3H-6lKU,1430
21
21
  hishel/_sync/_pool.py,sha256=wQFEir0gTdwLYhFcpRqo0YjF8riypgB4TFfWNHCkfRE,6348
22
- hishel/_sync/_storages.py,sha256=sIqfkAjZTZoE7tmlB9yJTg0bXz-q4Ck5V3IOc7FT9FA,18619
22
+ hishel/_sync/_storages.py,sha256=IYxvTVDPP5aPw-evD0AeDYbw1oiVtIuDaAAu8iQ_N7U,18871
23
23
  hishel/_sync/_transports.py,sha256=WNgWVNjMi0WyZ8e-5pJMGOVarQEksc4_4dQjU-G9pFY,9797
24
- hishel-0.0.23.dist-info/METADATA,sha256=LdprkzhyFR-Z3Oj8VgUWT6v06E5fVJtwjEv1vQ3o_Wo,9999
25
- hishel-0.0.23.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
26
- hishel-0.0.23.dist-info/licenses/LICENSE,sha256=1qQj7pE0V2O9OIedvyOgLGLvZLaPd3nFEup3IBEOZjQ,1493
27
- hishel-0.0.23.dist-info/RECORD,,
24
+ hishel-0.0.25.dist-info/METADATA,sha256=tlRwjxem922nV72utLunYMZ_p5FVEARS6NgNuOGCoak,10388
25
+ hishel-0.0.25.dist-info/WHEEL,sha256=uNdcs2TADwSd5pVaP0Z_kcjcvvTUklh2S7bxZMF8Uj0,87
26
+ hishel-0.0.25.dist-info/licenses/LICENSE,sha256=1qQj7pE0V2O9OIedvyOgLGLvZLaPd3nFEup3IBEOZjQ,1493
27
+ hishel-0.0.25.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.21.1
2
+ Generator: hatchling 1.22.4
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any