Persistent cache implementation for httpx and httpcore
Project Links
Meta
Author: Kar Petrosyan
Requires Python: >=3.9
Classifiers
Development Status
- 3 - Alpha
Environment
- Web Environment
Framework
- AsyncIO
- Trio
Intended Audience
- Developers
License
- OSI Approved :: BSD License
Operating System
- OS Independent
Programming Language
- Python :: 3
- Python :: 3 :: Only
- Python :: 3.9
- Python :: 3.10
- Python :: 3.11
- Python :: 3.12
- Python :: 3.13
- Python :: 3.14
Topic
- Internet :: WWW/HTTP
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.5] - 2025-10-18
🚀 Features
- (perf) Set chunk size to 128KB for httpx to reduce SQLite read/writes
- Better cache-control parsing
- Add close method to storages API (#384)
- (perf) Increase requests buffer size to 128KB, disable charset detection
🐛 Bug Fixes
- (docs) Fix some line breaks
⚙️ Miscellaneous Tasks
- Remove some redundant files from repo
[0.1.4] - 2025-10-14
🚀 Features
- 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
🐛 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] - 2025-07-06
🚀 Features
- Support providing a path prefix to S3 storage (#342)
📚 Documentation
- Update link to httpx transports page (#337)
[0.1.2] - 2025-04-04
🐛 Bug Fixes
- Requirements.txt to reduce vulnerabilities (#263)
[0.0.30] - 2024-07-12
🐛 Bug Fixes
- Requirements.txt to reduce vulnerabilities (#245)
- Requirements.txt to reduce vulnerabilities (#255)
[0.0.27] - 2024-05-31
🐛 Bug Fixes
- (redis) Do not update metadata with negative ttl (#231)
[0.0.1] - 2023-07-22
1.0.0.dev2
Oct 21, 2025
1.0.0.dev1
Oct 21, 2025
1.0.0.dev0
Oct 19, 2025
0.1.5
Oct 18, 2025
0.1.4
Oct 14, 2025
0.1.3
Jul 06, 2025
0.1.2
Apr 04, 2025
0.1.1
Nov 02, 2024
0.1.0
Nov 02, 2024
0.0.33
Oct 04, 2024
0.0.32
Sep 27, 2024
0.0.31
Sep 22, 2024
0.0.30
Jul 12, 2024
0.0.29
Jun 23, 2024
0.0.28
Jun 23, 2024
0.0.27
May 31, 2024
0.0.26
Apr 12, 2024
0.0.25
Mar 26, 2024
0.0.24
Feb 14, 2024
0.0.23
Feb 14, 2024
0.0.22
Jan 31, 2024
0.0.21
Dec 29, 2023
0.0.20
Dec 12, 2023
0.0.19
Nov 30, 2023
0.0.18
Nov 23, 2023
0.0.17
Nov 06, 2023
0.0.16
Oct 25, 2023
0.0.15
Oct 25, 2023
0.0.14
Oct 23, 2023
0.0.13
Oct 05, 2023
0.0.12
Sep 08, 2023
0.0.11
Aug 15, 2023
0.0.10
Aug 07, 2023
0.0.9
Aug 01, 2023
0.0.8
Jul 31, 2023
0.0.7
Jul 30, 2023
0.0.6
Jul 29, 2023
0.0.5
Jul 29, 2023
0.0.4
Jul 29, 2023
0.0.3
Jul 28, 2023
0.0.2
Jul 25, 2023
0.0.1
Jul 22, 2023
Wheel compatibility matrix
Files in release
Extras:
Dependencies:
anyio
(>=4.9.0)
anysqlite
(>=0.0.5)
httpx
(>=0.28.0)
msgpack
(>=1.1.2)
typing-extensions
(>=4.14.1)
