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
, 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.
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 ❤️
Changelog
0.0.29 (23th June, 2024)
- Documentation hotfix. (#244)
0.0.28 (23th June, 2024)
- Add
revalidated
response extension. (#242)
0.0.27 (31th May, 2024)
- Fix
RedisStorage
when using without ttl. (#231)
0.0.26 (12th April, 2024)
- Expose
AsyncBaseStorage
andBaseStorage
. (#220) - Prevent cache hits from resetting the ttl. (#215)
0.0.25 (26th March, 2024)
- Add
force_cache
property to the controller, allowing RFC9111 rules to be completely disabled. (#204) - Add
.gitignore
to cache directory created byFIleStorage
. (#197) - Remove
stale_*
headers from theCacheControl
class. (#199)
0.0.24 (14th February, 2024)
- Fix
botocore is not installed
exception when using any kind of storage. (#186)
0.0.23 (14th February, 2024)
- Make
S3Storage
to check staleness of all cache files with set interval. (#182) - Fix an issue where an empty file in
FileCache
could cause a parsing error. (#181) - Support caching for
POST
and other HTTP methods. (#183)
0.0.22 (31th January, 2024)
- Make
FileStorage
to check staleness of all cache files with set interval. (#169) - Support AWS S3 storages. (#164)
- Move
typing_extensions
from 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_cache
extension 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_disabled
extension 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-Modified
validation.
0.0.16 (25th October, 2023)
- Add
install_cache
function. (#95) - Add sqlite support. (#92)
- Move
ttl
argument toBaseStorage
class. (#94)
0.0.14 (23rd October, 2023)
- Replace
AsyncResponseStream
withAsyncCacheStream
. (#86) - Add
must-understand
response 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-control
directives. (#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_heuristically
toController.allow_heuristics
. (#12) - Handle import errors. (#13)
0.0.6 (29th July, 2023)
- Fix
Vary
header 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
YamlSerializer
name toYAMLSerializer
.
0.0.3 (28th July, 2023)
- Add
from_cache
response extension. - Add
typing_extensions
into 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.