Persistent cache implementation for httpx and httpcore
Project description
Hishel - An elegant HTTP Cache implementation for httpx and httpcore.
Hishel (հիշել, remember) is a library that implements HTTP Caching for HTTPX and HTTP Core libraries in accordance with RFC 9111, the most recent caching specification.
Features
- 💾 Persistence: Responses are cached in the persistent memory for later use.
- 🤲 Compatibility: It is completely compatible with your existing transports or connection pools, whether they are default, custom, or provided by third-party libraries.
- 🤗 Easy to use: You continue to use httpx while also enabling web cache.
- 🧠 Smart: Attempts to clearly implement RFC 9111, understands
Vary,Etag,Last-Modified,Cache-Control, andExpiresheaders, and handles response re-validation automatically. - ⚙️ Configurable: You have complete control over how the responses are stored and serialized.
- 📦 From the package:
- 🚀 Very fast: Your requests will be even faster if there are no IO operations.
Documentation
Go through the Hishel documentation.
QuickStart
Install Hishel using pip:
$ pip install hishel
Let's begin with an example of a httpx client.
import hishel
with hishel.CacheClient() as client:
client.get("https://hishel.com") # 0.4749558370003797s
client.get("https://hishel.com") # 0.002873589000046195s (~250x faster!)
or in asynchronous context
import hishel
async with hishel.AsyncCacheClient() as client:
await client.get("https://hishel.com")
await client.get("https://hishel.com") # takes from the cache
Configurations
Configure when and how you want to store your responses.
import hishel
# All the specification configs
controller = hishel.Controller(
# Cache only GET and POST methods
cacheable_methods=["GET", "POST"],
# Cache only 200 status codes
cacheable_status_codes=[200],
# Use the stale response if there is a connection issue and the new response cannot be obtained.
allow_stale=True,
# First, revalidate the response and then utilize it.
# If the response has not changed, do not download the
# entire response data from the server; instead,
# use the one you have because you know it has not been modified.
always_revalidate=True,
)
# All the storage configs
storage = hishel.S3Storage(
bucket_name="my_bucket_name", # store my cache files in the `my_bucket_name` bucket
ttl=3600, # delete the response if it is in the cache for more than an hour
)
client = hishel.CacheClient(controller=controller, storage=storage)
# Ignore the fact that the server does not recommend you cache this request!
client.post(
"https://example.com",
extensions={"force_cache": True}
)
# Return a regular response if it is in the cache; else, return a 504 status code. DO NOT SEND A REQUEST!
client.post(
"https://example.com",
headers=[("Cache-Control", "only-if-cached")]
)
# Ignore cached responses and do not store incoming responses!
response = client.post(
"https://example.com",
extensions={"cache_disabled": True}
)
How and where are the responses saved?
The responses are stored by Hishel in storages.
You have complete control over them; you can change storage or even write your own if necessary.
Support the project
You can support the project by simply leaving a GitHub star ⭐ or by contributing. Help us grow and continue developing good software for you ❤️
[0.1.4] - 2025-10-14
🚀 Features
- Add support for requests library
- Add support for Python 3.14
- Add support for a sans-IO API (#366)
- Allow already consumed streams with
CacheTransport(#377) - Add sqlite storage for beta storages
- Get rid of some locks from sqlite storage
- Better async implemetation for sqlite storage
- Added
Metadatato public API. (#363) - Fix race condition in FileStorage initialization. (#353)
🐛 Bug Fixes
- Create an sqlite file in a cache folder
- Fix beta imports
⚙️ Miscellaneous Tasks
- Improve CI (#369)
- (internal) Remove src folder (#373)
- (internal) Temporary remove python3.14 from CI
- (tests) Add sqlite tests for new storage
- (tests) Move some tests to beta
0.1.3 (1st July, 2025)
- Remove
types-redisfrom dev dependencies (#336) - Bump redis to 6.0.0 and address async
.close()deprecation warning (#336) - Avoid race condition when unlinking files in
FileStorage. (#334) - Allow prodiving a
path_prefixinS3StorageandAsyncS3Storage. (#342)
0.1.2 (5th April, 2025)
- Add check for fips compliant python. (#325)
- Fix compatibility with httpx. (#291)
- Use
SyncByteStreaminstead ofByteStream. (#298) - Don't raise exceptions if date-containing headers are invalid. (#318)
- Fix for S3 Storage missing metadata in API request. (#320)
0.1.1 (2nd Nov, 2024)
- Fix typing extensions not found. (#290)
0.1.0 (2nd Nov, 2024)
- Add support for Python 3.12 / drop Python 3.8. (#286)
- Specify usedforsecurity=False in blake2b. (#285)
0.0.33 (4th Oct, 2024)
- Added a Logging section to the documentation.
0.0.32 (27th Sep, 2024)
- Don't raise an exception if the
Dateheader is not present. (#273)
0.0.31 (22nd Sep, 2024)
- Ignore file not found error when cleaning up a file storage. (#264)
- Fix
AssertionErroronclient.close()when use SQLiteStorage. (#269) - Fix ignored flags when use
force_cache. (#271)
0.0.30 (12th July, 2024)
- Fix cache update on revalidation response with content (rfc9111 section 4.3.3) (#239)
- Fix request extensions that were not passed into revalidation request for transport-based implementation (but were passed for the pool-based impl) (#247).
- Add
cache_privateproperty to the controller to support acting as shared cache. (#224) - Improve efficiency of scanning cached responses in
FileStorageby reducing number of syscalls. (#252) - Add
removesupport for storages (#241)
0.0.29 (23th June, 2024)
- Documentation hotfix. (#244)
0.0.28 (23th June, 2024)
- Add
revalidatedresponse extension. (#242)
0.0.27 (31th May, 2024)
- Fix
RedisStoragewhen using without ttl. (#231)
0.0.26 (12th April, 2024)
- Expose
AsyncBaseStorageandBaseStorage. (#220) - Prevent cache hits from resetting the ttl. (#215)
0.0.25 (26th March, 2024)
- Add
force_cacheproperty to the controller, allowing RFC9111 rules to be completely disabled. (#204) - Add
.gitignoreto cache directory created byFIleStorage. (#197) - Remove
stale_*headers from theCacheControlclass. (#199)
0.0.24 (14th February, 2024)
- Fix
botocore is not installedexception when using any kind of storage. (#186)
0.0.23 (14th February, 2024)
- Make
S3Storageto check staleness of all cache files with set interval. (#182) - Fix an issue where an empty file in
FileCachecould cause a parsing error. (#181) - Support caching for
POSTand other HTTP methods. (#183)
0.0.22 (31th January, 2024)
- Make
FileStorageto check staleness of all cache files with set interval. (#169) - Support AWS S3 storages. (#164)
- Move
typing_extensionsfrom requirements.txt to pyproject.toml. (#161)
0.0.21 (29th December, 2023)
- Fix inner transport and connection pool instances closing. (#147)
- Improved error message when the storage type is incorrect. (#138)
0.0.20 (12th December, 2023)
- Add in-memory storage. (#133)
- Allow customization of cache key generation. (#130)
0.0.19 (30th November, 2023)
- Add
force_cacheextension to enforce the request to be cached, ignoring the HTTP headers. (#117) - Fix issue where sqlite storage cache get deleted immediately. (#119)
- Support float numbers for storage ttl. (#107)
0.0.18 (23rd November, 2023)
- Fix issue where freshness cannot be calculated to re-send request. (#104)
- Add
cache_disabledextension to temporarily disable the cache (#109) - Update
datetime.datetime.utcnow()todatetime.datetime.now(datetime.timezone.utc)sincedatetime.datetime.utcnow()has been deprecated. (#111)
0.0.17 (6th November, 2023)
- Fix
Last-Modifiedvalidation.
0.0.16 (25th October, 2023)
- Add
install_cachefunction. (#95) - Add sqlite support. (#92)
- Move
ttlargument toBaseStorageclass. (#94)
0.0.14 (23rd October, 2023)
- Replace
AsyncResponseStreamwithAsyncCacheStream. (#86) - Add
must-understandresponse directive support. (#90)
0.0.13 (5th October, 2023)
- Add support for Python 3.12. (#71)
- Fix connections releasing from the connection pool. (#83)
0.0.12 (8th September, 2023)
- Add metadata into the response extensions. (#56)
0.0.11 (15th August, 2023)
- Add support for request
cache-controldirectives. (#42) - Drop httpcore dependency. (#40)
- Support HTTP methods only if they are defined as cacheable. (#37)
0.0.10 (7th August, 2023)
- Add Response metadata. (#33)
- Add API Reference documentation. (#30)
- Use stale responses only if the client is disconnected. (#28)
0.0.9 (1st August, 2023)
- Expose Controller API. (#23)
0.0.8 (31st July, 2023)
- Skip redis tests if the server was not found. (#16)
- Decrease sleep time for the storage ttl tests. (#18)
- Fail coverage under 100. (#19)
0.0.7 (30th July, 2023)
- Add support for
Heuristic Freshness. (#11) - Change
Controller.cache_heuristicallytoController.allow_heuristics. (#12) - Handle import errors. (#13)
0.0.6 (29th July, 2023)
- Fix
Varyheader validation. (#8) - Dump original requests with the responses. (#7)
0.0.5 (29th July, 2023)
- Fix httpx response streaming.
0.0.4 (29th July, 2023)
- Change
YamlSerializername toYAMLSerializer.
0.0.3 (28th July, 2023)
- Add
from_cacheresponse extension. - Add
typing_extensionsinto the requirements.
0.0.2 (25th July, 2023)
- Add redis support.
- Make backends thread and task safe.
- Add black as a new linter.
- Add an expire time for cached responses.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hishel-0.1.4.tar.gz.
File metadata
- Download URL: hishel-0.1.4.tar.gz
- Upload date:
- Size: 77.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e298ca4585dc2c01cc3a3dd59796651c3ca0d22d649eb38d64cee44555b1a1b1
|
|
| MD5 |
5d109990d585864edbb28297f9961cae
|
|
| BLAKE2b-256 |
6a4d2bcd25ee79701c268f7f53e3caf8a903ef0f3ba857f60c9b384c3e2a7b05
|
Provenance
The following attestation bundles were made for hishel-0.1.4.tar.gz:
Publisher:
publish.yml on karpetrosyan/hishel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hishel-0.1.4.tar.gz -
Subject digest:
e298ca4585dc2c01cc3a3dd59796651c3ca0d22d649eb38d64cee44555b1a1b1 - Sigstore transparency entry: 605165867
- Sigstore integration time:
-
Permalink:
karpetrosyan/hishel@d982b9e70200934ebf364df1b6e761a0ff6770f9 -
Branch / Tag:
refs/tags/0.1.4 - Owner: https://github.com/karpetrosyan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d982b9e70200934ebf364df1b6e761a0ff6770f9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hishel-0.1.4-py3-none-any.whl.
File metadata
- Download URL: hishel-0.1.4-py3-none-any.whl
- Upload date:
- Size: 92.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e90c9d747a8f785426d7e196655d1e6a4ca5f668b1322b4a0d39c9cca6b4588
|
|
| MD5 |
d178be24d96a29d083c86cdf7e93f1fc
|
|
| BLAKE2b-256 |
72c081b3bfa47c7253e24dc61ad8810a8235f87752483986fc5d6a2a6b43ae33
|
Provenance
The following attestation bundles were made for hishel-0.1.4-py3-none-any.whl:
Publisher:
publish.yml on karpetrosyan/hishel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hishel-0.1.4-py3-none-any.whl -
Subject digest:
2e90c9d747a8f785426d7e196655d1e6a4ca5f668b1322b4a0d39c9cca6b4588 - Sigstore transparency entry: 605165878
- Sigstore integration time:
-
Permalink:
karpetrosyan/hishel@d982b9e70200934ebf364df1b6e761a0ff6770f9 -
Branch / Tag:
refs/tags/0.1.4 - Owner: https://github.com/karpetrosyan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d982b9e70200934ebf364df1b6e761a0ff6770f9 -
Trigger Event:
push
-
Statement type: