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.
- 💾 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
, andExpires
headers, 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.
Go through the Hishel documentation.
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
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}
)
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.
You can support the project by simply leaving a GitHub star ⭐ or by contributing. Help us grow and continue developing good software for you ❤️