hishel 1.0.0.dev0__py3-none-any.whl → 1.0.0.dev2__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/_core/models.py CHANGED
@@ -109,18 +109,21 @@ class Request:
109
109
 
110
110
  class ResponseMetadata(TypedDict, total=False):
111
111
  # All the names here should be prefixed with "hishel_" to avoid collisions with user data
112
- hishel_from_cache: bool | None
112
+ hishel_from_cache: bool
113
113
  """Indicates whether the response was served from cache."""
114
114
 
115
- hishel_revalidated: bool | None
115
+ hishel_revalidated: bool
116
116
  """Indicates whether the response was revalidated with the origin server."""
117
117
 
118
- hishel_spec_ignored: bool | None
118
+ hishel_spec_ignored: bool
119
119
  """Indicates whether the caching specification was ignored for this response."""
120
120
 
121
- hishel_stored: bool | None
121
+ hishel_stored: bool
122
122
  """Indicates whether the response was stored in cache."""
123
123
 
124
+ hishel_created_at: float
125
+ """Timestamp when the response was cached."""
126
+
124
127
 
125
128
  @dataclass
126
129
  class Response:
hishel/_sync_cache.py CHANGED
@@ -25,7 +25,7 @@ from hishel import (
25
25
  create_idle_state,
26
26
  )
27
27
  from hishel._core._spec import InvalidatePairs, vary_headers_match
28
- from hishel._core.models import CompletePair
28
+ from hishel._core.models import CompletePair, ResponseMetadata
29
29
 
30
30
  logger = logging.getLogger("hishel.integrations.clients")
31
31
 
@@ -90,7 +90,14 @@ class SyncCacheProxy:
90
90
  logger.debug(
91
91
  "Found matching cached response for the request",
92
92
  )
93
- pair.response.metadata["hishel_from_cache"] = True # type: ignore
93
+ response_meta = ResponseMetadata(
94
+ hishel_spec_ignored=True,
95
+ hishel_from_cache=True,
96
+ hishel_created_at=pair.meta.created_at,
97
+ hishel_revalidated=False,
98
+ hishel_stored=False,
99
+ )
100
+ pair.response.metadata.update(response_meta) # type: ignore
94
101
  self._maybe_refresh_pair_ttl(pair)
95
102
  return pair.response
96
103
 
hishel/_utils.py CHANGED
@@ -1,113 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import calendar
4
- import hashlib
5
- import json
6
- import sqlite3
7
4
  import time
8
5
  import typing as tp
9
- from datetime import date
10
6
  from email.utils import parsedate_tz
11
- from typing import Any, AsyncIterator, Generator, Iterable, Iterator, TypeVar
12
-
13
- import anyio
14
- import anysqlite
15
- import httpcore
16
- import httpx
17
- from anyio import from_thread, to_thread
7
+ from typing import AsyncIterator, Iterable, Iterator
18
8
 
19
9
  HEADERS_ENCODING = "iso-8859-1"
20
10
 
21
11
  T = tp.TypeVar("T")
22
12
 
23
13
 
24
- class BaseClock:
25
- def now(self) -> int:
26
- raise NotImplementedError()
27
-
28
-
29
- class Clock(BaseClock):
30
- def now(self) -> int:
31
- return int(time.time())
32
-
33
-
34
- def normalized_url(url: tp.Union[httpcore.URL, str, bytes]) -> str:
35
- if isinstance(url, str): # pragma: no cover
36
- return url
37
-
38
- if isinstance(url, bytes): # pragma: no cover
39
- return url.decode("ascii")
40
-
41
- if isinstance(url, httpcore.URL):
42
- port = f":{url.port}" if url.port is not None else ""
43
- return f"{url.scheme.decode('ascii')}://{url.host.decode('ascii')}{port}{url.target.decode('ascii')}"
44
- assert False, "Invalid type for `normalized_url`" # pragma: no cover
45
-
46
-
47
- def get_safe_url(url: httpcore.URL) -> str:
48
- httpx_url = httpx.URL(bytes(url).decode("ascii"))
49
-
50
- schema = httpx_url.scheme
51
- host = httpx_url.host
52
- path = httpx_url.path
53
-
54
- return f"{schema}://{host}{path}"
55
-
56
-
57
- def generate_key(request: httpcore.Request, body: bytes = b"") -> str:
58
- encoded_url = normalized_url(request.url).encode("ascii")
59
-
60
- key_parts = [request.method, encoded_url, body]
61
-
62
- # FIPs mode disables blake2 algorithm, use sha256 instead when not found.
63
- blake2b_hasher = None
64
- sha256_hasher = hashlib.sha256(usedforsecurity=False)
65
- try:
66
- blake2b_hasher = hashlib.blake2b(digest_size=16, usedforsecurity=False)
67
- except (ValueError, TypeError, AttributeError):
68
- pass
69
-
70
- hexdigest: str
71
- if blake2b_hasher:
72
- for part in key_parts:
73
- blake2b_hasher.update(part)
74
-
75
- hexdigest = blake2b_hasher.hexdigest()
76
- else:
77
- for part in key_parts:
78
- sha256_hasher.update(part)
79
-
80
- hexdigest = sha256_hasher.hexdigest()
81
- return hexdigest
82
-
83
-
84
- def extract_header_values(
85
- headers: tp.List[tp.Tuple[bytes, bytes]],
86
- header_key: tp.Union[bytes, str],
87
- single: bool = False,
88
- ) -> tp.List[bytes]:
89
- if isinstance(header_key, str):
90
- header_key = header_key.encode(HEADERS_ENCODING)
91
- extracted_headers = []
92
- for key, value in headers:
93
- if key.lower() == header_key.lower():
94
- extracted_headers.append(value)
95
- if single:
96
- break
97
- return extracted_headers
98
-
99
-
100
- def extract_header_values_decoded(
101
- headers: tp.List[tp.Tuple[bytes, bytes]], header_key: bytes, single: bool = False
102
- ) -> tp.List[str]:
103
- values = extract_header_values(headers=headers, header_key=header_key, single=single)
104
- return [value.decode(HEADERS_ENCODING) for value in values]
105
-
106
-
107
- def header_presents(headers: tp.List[tp.Tuple[bytes, bytes]], header_key: bytes) -> bool:
108
- return bool(extract_header_values(headers, header_key, single=True))
109
-
110
-
111
14
  def parse_date(date: str) -> tp.Optional[int]:
112
15
  expires = parsedate_tz(date)
113
16
  if expires is None:
@@ -116,18 +19,10 @@ def parse_date(date: str) -> tp.Optional[int]:
116
19
  return timestamp
117
20
 
118
21
 
119
- async def asleep(seconds: tp.Union[int, float]) -> None:
120
- await anyio.sleep(seconds)
121
-
122
-
123
22
  def sleep(seconds: tp.Union[int, float]) -> None:
124
23
  time.sleep(seconds)
125
24
 
126
25
 
127
- def float_seconds_to_int_milliseconds(seconds: float) -> int:
128
- return int(seconds * 1000)
129
-
130
-
131
26
  def partition(iterable: tp.Iterable[T], predicate: tp.Callable[[T], bool]) -> tp.Tuple[tp.List[T], tp.List[T]]:
132
27
  """
133
28
  Partition an iterable into two lists: one for matching items and one for non-matching items.
@@ -155,66 +50,6 @@ def partition(iterable: tp.Iterable[T], predicate: tp.Callable[[T], bool]) -> tp
155
50
  return matching, non_matching
156
51
 
157
52
 
158
- def async_iterator_to_sync(iterator: AsyncIterator[bytes]) -> Iterator[bytes]:
159
- """
160
- Convert an asynchronous byte iterator to a synchronous one.
161
- This function takes an asynchronous iterator that yields bytes and converts it into
162
- a synchronous iterator.
163
-
164
- Args:
165
- iterator (AsyncIterator[bytes]): The asynchronous byte iterator to be converted.
166
- Returns:
167
- Iterator[bytes]: A synchronous iterator that yields the same byte chunks as the input iterator.
168
- Example:
169
- ```python
170
- async_iter = some_async_byte_stream()
171
- sync_iter = async_iterator_to_sync(async_iter)
172
- for chunk in sync_iter:
173
- process_bytes(chunk)
174
- ```
175
- """
176
-
177
- while True:
178
- try:
179
- chunk = from_thread.run(iterator.__anext__)
180
- except StopAsyncIteration:
181
- break
182
- yield chunk
183
-
184
-
185
- def _call_next(iterator: Iterator[bytes]) -> bytes:
186
- try:
187
- return iterator.__next__()
188
- except StopIteration:
189
- raise StopAsyncIteration
190
-
191
-
192
- async def sync_iterator_to_async(iterator: Iterator[bytes]) -> AsyncIterator[bytes]:
193
- """
194
- Converts a synchronous bytes iterator to an asynchronous one.
195
- This function takes a synchronous iterator that yields bytes and converts it into an
196
- asynchronous iterator, allowing it to be used in async contexts without blocking.
197
- Args:
198
- iterator (Iterator[bytes]): A synchronous iterator yielding bytes objects.
199
- Returns:
200
- AsyncIterator[bytes]: An asynchronous iterator yielding the same bytes objects.
201
- Example:
202
- ```
203
- sync_iter = iter([b'data1', b'data2'])
204
- async for chunk in sync_iterator_to_async(sync_iter):
205
- await process_chunk(chunk)
206
- ```
207
- """
208
-
209
- while True:
210
- try:
211
- chunk = await to_thread.run_sync(_call_next, iterator)
212
- except StopAsyncIteration:
213
- break
214
-
215
- yield chunk
216
-
217
-
218
53
  async def make_async_iterator(iterable: Iterable[bytes]) -> AsyncIterator[bytes]:
219
54
  for item in iterable:
220
55
  yield item
@@ -245,214 +80,3 @@ def snake_to_header(text: str) -> str:
245
80
  """
246
81
  # Split by underscore, capitalize each word, join with dash, add X- prefix
247
82
  return "X-" + "-".join(word.capitalize() for word in text.split("_"))
248
-
249
-
250
- _T = TypeVar("_T")
251
-
252
-
253
- class GeneratorWithReturnValue:
254
- def __init__(
255
- self, gen: Generator[None, bytes | None, bytes], stream: AsyncIterator[bytes] | Iterator[bytes]
256
- ) -> None:
257
- self.gen = gen
258
- self.stream = stream
259
- self.value: bytes | None = None
260
-
261
- def __iter__(self) -> Iterator[bytes]:
262
- return self
263
-
264
- def __next__(self) -> bytes:
265
- assert isinstance(self.stream, Iterator)
266
-
267
- try:
268
- chunk = next(self.stream)
269
- self.gen.send(chunk)
270
- except StopIteration as exc:
271
- self.gen.send(None)
272
- self.value = exc.value
273
- raise
274
- return chunk
275
-
276
- def __aiter__(self) -> AsyncIterator[bytes]:
277
- return self
278
-
279
- async def __anext__(self) -> bytes:
280
- assert isinstance(self.stream, AsyncIterator)
281
- try:
282
- chunk = await self.stream.__anext__()
283
- self.gen.send(chunk)
284
- except StopIteration as exc:
285
- self.gen.send(None)
286
- self.value = exc.value
287
- raise
288
- return chunk
289
-
290
-
291
- def print_sqlite_state(conn: sqlite3.Connection) -> str:
292
- """
293
- Print all tables and their rows in a pretty format suitable for inline snapshots.
294
-
295
- Args:
296
- conn: SQLite database connection
297
-
298
- Returns:
299
- Formatted string representation of the database state
300
- """
301
- cursor = conn.cursor()
302
-
303
- # Get all table names
304
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
305
- tables = [row[0] for row in cursor.fetchall()]
306
-
307
- output_lines = []
308
- output_lines.append("=" * 80)
309
- output_lines.append("DATABASE SNAPSHOT")
310
- output_lines.append("=" * 80)
311
-
312
- for table_name in tables:
313
- # Get column information
314
- cursor.execute(f"PRAGMA table_info({table_name})")
315
- columns = cursor.fetchall()
316
- column_names = [col[1] for col in columns]
317
- column_types = {col[1]: col[2] for col in columns}
318
-
319
- # Get all rows
320
- cursor.execute(f"SELECT * FROM {table_name}")
321
- rows = cursor.fetchall()
322
-
323
- output_lines.append("")
324
- output_lines.append(f"TABLE: {table_name}")
325
- output_lines.append("-" * 80)
326
- output_lines.append(f"Rows: {len(rows)}")
327
- output_lines.append("")
328
-
329
- if not rows:
330
- output_lines.append(" (empty)")
331
- continue
332
-
333
- # Format each row
334
- for idx, row in enumerate(rows, 1):
335
- output_lines.append(f" Row {idx}:")
336
-
337
- for col_name, value in zip(column_names, row):
338
- col_type = column_types[col_name]
339
- formatted_value = format_value(value, col_name, col_type)
340
- output_lines.append(f" {col_name:15} = {formatted_value}")
341
-
342
- if idx < len(rows):
343
- output_lines.append("")
344
-
345
- output_lines.append("")
346
- output_lines.append("=" * 80)
347
-
348
- result = "\n".join(output_lines)
349
- return result
350
-
351
-
352
- async def aprint_sqlite_state(conn: anysqlite.Connection) -> str:
353
- """
354
- Print all tables and their rows in a pretty format suitable for inline snapshots.
355
-
356
- Args:
357
- conn: SQLite database connection
358
-
359
- Returns:
360
- Formatted string representation of the database state
361
- """
362
- cursor = await conn.cursor()
363
-
364
- # Get all table names
365
- await cursor.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
366
- tables = [row[0] for row in await cursor.fetchall()]
367
-
368
- output_lines = []
369
- output_lines.append("=" * 80)
370
- output_lines.append("DATABASE SNAPSHOT")
371
- output_lines.append("=" * 80)
372
-
373
- for table_name in tables:
374
- # Get column information
375
- await cursor.execute(f"PRAGMA table_info({table_name})")
376
- columns = await cursor.fetchall()
377
- column_names = [col[1] for col in columns]
378
- column_types = {col[1]: col[2] for col in columns}
379
-
380
- # Get all rows
381
- await cursor.execute(f"SELECT * FROM {table_name}")
382
- rows = await cursor.fetchall()
383
-
384
- output_lines.append("")
385
- output_lines.append(f"TABLE: {table_name}")
386
- output_lines.append("-" * 80)
387
- output_lines.append(f"Rows: {len(rows)}")
388
- output_lines.append("")
389
-
390
- if not rows:
391
- output_lines.append(" (empty)")
392
- continue
393
-
394
- # Format each row
395
- for idx, row in enumerate(rows, 1):
396
- output_lines.append(f" Row {idx}:")
397
-
398
- for col_name, value in zip(column_names, row):
399
- col_type = column_types[col_name]
400
- formatted_value = format_value(value, col_name, col_type)
401
- output_lines.append(f" {col_name:15} = {formatted_value}")
402
-
403
- if idx < len(rows):
404
- output_lines.append("")
405
-
406
- output_lines.append("")
407
- output_lines.append("=" * 80)
408
-
409
- result = "\n".join(output_lines)
410
- return result
411
-
412
-
413
- def format_value(value: Any, col_name: str, col_type: str) -> str:
414
- """Format a value for display based on its type and column name."""
415
-
416
- if value is None:
417
- return "NULL"
418
-
419
- # Handle BLOB columns
420
- if col_type.upper() == "BLOB":
421
- if isinstance(value, bytes):
422
- # Try to decode as UTF-8 string first
423
- try:
424
- decoded = value.decode("utf-8")
425
- # Check if it looks like JSON
426
- if decoded.strip().startswith("{") or decoded.strip().startswith("["):
427
- try:
428
- parsed = json.loads(decoded)
429
- return f"(JSON) {json.dumps(parsed, indent=2)}"
430
- except json.JSONDecodeError:
431
- pass
432
- # Show string if it's printable
433
- if all(32 <= ord(c) <= 126 or c in "\n\r\t" for c in decoded):
434
- return f"(str) '{decoded}'"
435
- except UnicodeDecodeError:
436
- pass
437
-
438
- # Show hex representation for binary data
439
- hex_str = value.hex()
440
- if len(hex_str) > 64:
441
- return f"(bytes) 0x{hex_str[:60]}... ({len(value)} bytes)"
442
- return f"(bytes) 0x{hex_str} ({len(value)} bytes)"
443
- return repr(value)
444
-
445
- # Handle timestamps - ONLY show date, not the raw timestamp
446
- if col_name.endswith("_at") and isinstance(value, (int, float)):
447
- try:
448
- dt = date.fromtimestamp(value)
449
- return dt.isoformat() # Changed: removed the timestamp prefix
450
- except (ValueError, OSError):
451
- return str(value)
452
-
453
- # Handle TEXT columns
454
- if col_type.upper() == "TEXT":
455
- return f"'{value}'"
456
-
457
- # Handle other types
458
- return str(value)
hishel/httpx.py CHANGED
@@ -4,8 +4,6 @@ import ssl
4
4
  import typing as t
5
5
  from typing import AsyncIterator, Iterable, Iterator, Union, overload
6
6
 
7
- import httpx
8
-
9
7
  from hishel import Headers, Request, Response
10
8
  from hishel._async_cache import AsyncCacheProxy
11
9
  from hishel._core._base._storages._base import AsyncBaseStorage, SyncBaseStorage
@@ -15,6 +13,15 @@ from hishel._core._spec import (
15
13
  from hishel._core.models import AnyIterable
16
14
  from hishel._sync_cache import SyncCacheProxy
17
15
 
16
+ try:
17
+ import httpx
18
+ except ImportError as e:
19
+ raise ImportError(
20
+ "httpx is required to use hishel.httpx module. "
21
+ "Please install hishel with the 'httpx' extra, "
22
+ "e.g., 'pip install hishel[httpx]'."
23
+ ) from e
24
+
18
25
  SOCKET_OPTION = t.Union[
19
26
  t.Tuple[int, int, int],
20
27
  t.Tuple[int, int, t.Union[bytes, bytearray]],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hishel
3
- Version: 1.0.0.dev0
3
+ Version: 1.0.0.dev2
4
4
  Summary: Elegant HTTP Caching for Python
5
5
  Project-URL: Homepage, https://hishel.com
6
6
  Project-URL: Source, https://github.com/karpetrosyan/hishel
@@ -24,12 +24,14 @@ Classifier: Programming Language :: Python :: 3.13
24
24
  Classifier: Programming Language :: Python :: 3.14
25
25
  Classifier: Topic :: Internet :: WWW/HTTP
26
26
  Requires-Python: >=3.9
27
- Requires-Dist: anyio>=4.9.0
28
- Requires-Dist: anysqlite>=0.0.5
29
- Requires-Dist: httpx>=0.28.0
30
27
  Requires-Dist: msgpack>=1.1.2
31
28
  Requires-Dist: typing-extensions>=4.14.1
29
+ Provides-Extra: async
30
+ Requires-Dist: anyio>=4.9.0; extra == 'async'
31
+ Requires-Dist: anysqlite>=0.0.5; extra == 'async'
32
32
  Provides-Extra: httpx
33
+ Requires-Dist: anyio>=4.9.0; extra == 'httpx'
34
+ Requires-Dist: anysqlite>=0.0.5; extra == 'httpx'
33
35
  Requires-Dist: httpx>=0.28.1; extra == 'httpx'
34
36
  Provides-Extra: requests
35
37
  Requires-Dist: requests>=2.32.5; extra == 'requests'
@@ -249,73 +251,66 @@ Hishel is inspired by and builds upon the excellent work in the Python HTTP ecos
249
251
  <strong>Made with ❤️ by <a href="https://github.com/karpetrosyan">Kar Petrosyan</a></strong>
250
252
  </p>
251
253
 
252
- ## [1.0.0dev0] - 2025-10-19
254
+ # Changelog
253
255
 
256
+ All notable changes to this project will be documented in this file.
257
+
258
+ ## 1.0.0.dev2 - 2025-10-21
254
259
  ### ⚙️ Miscellaneous Tasks
260
+ - Remove redundant utils and tests
261
+ - Add import without extras check in ci
255
262
 
256
- - *(docs)* Use mike powered versioning
257
- - *(docs)* Improve docs versioning, deploy dev doc on ci
258
- ## [0.1.5] - 2025-10-18
263
+ ### 🐛 Bug Fixes
264
+ - Fix check for storing auth requests
265
+ - Don't raise an error on 3xx during revalidation
259
266
 
260
267
  ### 🚀 Features
268
+ - Add hishel_created_at response metadata
261
269
 
262
- - *(perf)* Set chunk size to 128KB for httpx to reduce SQLite read/writes
263
- - Better cache-control parsing
264
- - Add close method to storages API (#384)
265
- - *(perf)* Increase requests buffer size to 128KB, disable charset detection
266
-
267
- ### 🐛 Bug Fixes
270
+ ## 1.0.0.dev1 - 2025-10-21
271
+ ### ⚙️ Miscellaneous Tasks
272
+ - Remove some redundant utils methods
268
273
 
269
- - *(docs)* Fix some line breaks
274
+ ### 📦 Dependencies
275
+ - Make httpx and async libs optional dependencies
276
+ - Make `anysqlite` optional dependency
277
+ - Install async extra with httpx
278
+ - Improve git-cliff
270
279
 
280
+ ## 1.0.0.dev0 - 2025-10-19
271
281
  ### ⚙️ Miscellaneous Tasks
282
+ - Use mike powered versioning
283
+ - Improve docs versioning, deploy dev doc on ci
272
284
 
285
+ ## 0.1.5 - 2025-10-18
286
+ ### ⚙️ Miscellaneous Tasks
273
287
  - Remove some redundant files from repo
274
- ## [0.1.4] - 2025-10-14
275
-
276
- ### 🚀 Features
277
-
278
- - Add support for a sans-IO API (#366)
279
- - Allow already consumed streams with `CacheTransport` (#377)
280
- - Add sqlite storage for beta storages
281
- - Get rid of some locks from sqlite storage
282
- - Better async implemetation for sqlite storage
283
288
 
284
289
  ### 🐛 Bug Fixes
290
+ - Fix some line breaks
285
291
 
286
- - Create an sqlite file in a cache folder
287
- - Fix beta imports
292
+ ### 🚀 Features
293
+ - Set chunk size to 128KB for httpx to reduce SQLite read/writes
294
+ - Better cache-control parsing
295
+ - Add close method to storages API (#384)
296
+ - Increase requests buffer size to 128KB, disable charset detection
288
297
 
298
+ ## 0.1.4 - 2025-10-14
289
299
  ### ⚙️ Miscellaneous Tasks
290
-
291
300
  - Improve CI (#369)
292
- - *(internal)* Remove src folder (#373)
293
- - *(internal)* Temporary remove python3.14 from CI
294
- - *(tests)* Add sqlite tests for new storage
295
- - *(tests)* Move some tests to beta
296
- ## [0.1.3] - 2025-07-06
297
-
298
- ### 🚀 Features
299
-
300
- - Support providing a path prefix to S3 storage (#342)
301
-
302
- ### 📚 Documentation
303
-
304
- - Update link to httpx transports page (#337)
305
- ## [0.1.2] - 2025-04-04
306
-
307
- ### 🐛 Bug Fixes
308
-
309
- - Requirements.txt to reduce vulnerabilities (#263)
310
- ## [0.0.30] - 2024-07-12
301
+ - Remove src folder (#373)
302
+ - Temporary remove python3.14 from CI
303
+ - Add sqlite tests for new storage
304
+ - Move some tests to beta
311
305
 
312
306
  ### 🐛 Bug Fixes
307
+ - Create an sqlite file in a cache folder
308
+ - Fix beta imports
313
309
 
314
- - Requirements.txt to reduce vulnerabilities (#245)
315
- - Requirements.txt to reduce vulnerabilities (#255)
316
- ## [0.0.27] - 2024-05-31
317
-
318
- ### 🐛 Bug Fixes
310
+ ### 🚀 Features
311
+ - Add support for a sans-IO API (#366)
312
+ - Allow already consumed streams with `CacheTransport` (#377)
313
+ - Add sqlite storage for beta storages
314
+ - Get rid of some locks from sqlite storage
315
+ - Better async implemetation for sqlite storage
319
316
 
320
- - *(redis)* Do not update metadata with negative ttl (#231)
321
- ## [0.0.1] - 2023-07-22
@@ -0,0 +1,19 @@
1
+ hishel/__init__.py,sha256=byj_IhCjFMaBcp6R8iyRlQV-3R4uTfH44PQzB4lVe1g,1447
2
+ hishel/_async_cache.py,sha256=1K5y369F2EqTnZEf9Wspq_rxKAlNPsKNa6WhDOreNeM,7109
3
+ hishel/_sync_cache.py,sha256=0pxnpb_27KRly5V-A8mSehUChavYFH5U8Az_sUiyo_M,6855
4
+ hishel/_utils.py,sha256=AAUMfTmXVZqvyc7_DvOI4OloamJlSQIR8qilf_ySFi8,2291
5
+ hishel/httpx.py,sha256=vscNB426VIhh0f5qQVkGA_WpwVvaKxbI6gnsHrBA_D0,11226
6
+ hishel/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ hishel/requests.py,sha256=eiWcwCId04DucnquCsU12tj9cDZcn-cjZ9MYniVuNeo,6429
8
+ hishel/_core/__init__.py,sha256=byj_IhCjFMaBcp6R8iyRlQV-3R4uTfH44PQzB4lVe1g,1447
9
+ hishel/_core/_headers.py,sha256=ii4x2L6GoQFpqpgg28OtFh7p2DoM9mhE4q6CjW6xUWc,17473
10
+ hishel/_core/_spec.py,sha256=yQmuJ-HOXTPNIooXr8PPlQUhIv_SEDkZocro_u89o_A,104179
11
+ hishel/_core/models.py,sha256=-09QfsdKHWyKwFqSZZf7qoUdTvtL1KL53c-KsBAtGuU,5571
12
+ hishel/_core/_async/_storages/_sqlite.py,sha256=QPbNtNMA7vYjpt8bSPFIZ4u4c3UCH6eDfUWnH6WprTU,17787
13
+ hishel/_core/_base/_storages/_base.py,sha256=xLJGTBlFK8DVrQMgRMtGXJnYRUmNB-iYkk7S-BtMx8s,8516
14
+ hishel/_core/_base/_storages/_packing.py,sha256=NFMpSvYYTDBNkzwpjj5l4w-JOPLc19oAEDqDEQJ7VZI,4873
15
+ hishel/_core/_sync/_storages/_sqlite.py,sha256=kvAcV2FttZstWEfCczBxj30-PYdj1y9lzh0x3hNusKY,17210
16
+ hishel-1.0.0.dev2.dist-info/METADATA,sha256=N0WGvzpWKP06XP5hWRHv_B6hgGm1sCsx8GSaGxjn_gs,10116
17
+ hishel-1.0.0.dev2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
18
+ hishel-1.0.0.dev2.dist-info/licenses/LICENSE,sha256=1qQj7pE0V2O9OIedvyOgLGLvZLaPd3nFEup3IBEOZjQ,1493
19
+ hishel-1.0.0.dev2.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- hishel/__init__.py,sha256=byj_IhCjFMaBcp6R8iyRlQV-3R4uTfH44PQzB4lVe1g,1447
2
- hishel/_async_cache.py,sha256=gE5CygC7FG9htBMfxul7carRRNph8zcMlSoOcB_LNTY,6792
3
- hishel/_sync_cache.py,sha256=lfkWHJFK527peESMaufjKSbXBriidc09tOwBwub2t34,6538
4
- hishel/_utils.py,sha256=uO8PcY_E1sHSgBGzZ2GNB4kpKqAlzmnzPCc3s-yDd44,13826
5
- hishel/httpx.py,sha256=HcJ5iO9PgkEOp92ti8013N6m1IotLajwd9M_DLsmrX0,10997
6
- hishel/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- hishel/requests.py,sha256=eiWcwCId04DucnquCsU12tj9cDZcn-cjZ9MYniVuNeo,6429
8
- hishel/_core/__init__.py,sha256=byj_IhCjFMaBcp6R8iyRlQV-3R4uTfH44PQzB4lVe1g,1447
9
- hishel/_core/_headers.py,sha256=ii4x2L6GoQFpqpgg28OtFh7p2DoM9mhE4q6CjW6xUWc,17473
10
- hishel/_core/_spec.py,sha256=d2ZnTXttyT4zuVq9xHAO86VGJxAEBxD2a8WMyEgOuAo,102702
11
- hishel/_core/models.py,sha256=5qwo1WifrDeZdXag7M5rh0hJuVsm1N-sF3UagQ5LcLc,5519
12
- hishel/_core/_async/_storages/_sqlite.py,sha256=wIO0UaFzal9qoVqDVczzcsW0kGUjBQD-ikauc_MN414,14704
13
- hishel/_core/_base/_storages/_base.py,sha256=xLJGTBlFK8DVrQMgRMtGXJnYRUmNB-iYkk7S-BtMx8s,8516
14
- hishel/_core/_base/_storages/_packing.py,sha256=NFMpSvYYTDBNkzwpjj5l4w-JOPLc19oAEDqDEQJ7VZI,4873
15
- hishel/_core/_sync/_storages/_sqlite.py,sha256=TDm9jXIWtd54m4_8AiVApxZVmbBoeFVi3E6s-vGzDjs,14138
16
- hishel-1.0.0.dev0.dist-info/METADATA,sha256=EpqEHRIGfzVXqMiRefCa_NZ9AlbjzVToXfnK-GBrs9o,9993
17
- hishel-1.0.0.dev0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
18
- hishel-1.0.0.dev0.dist-info/licenses/LICENSE,sha256=1qQj7pE0V2O9OIedvyOgLGLvZLaPd3nFEup3IBEOZjQ,1493
19
- hishel-1.0.0.dev0.dist-info/RECORD,,