{"id":2060,"library":"hishel","title":"Hishel","description":"Hishel is an elegant HTTP caching library for Python, implementing RFC 9111 specifications to provide seamless caching integration for popular HTTP clients like HTTPX and Requests. It offers flexible storage backends, including SQLite, and supports both synchronous and asynchronous workflows with a focus on high performance and type safety. The library is actively maintained with frequent minor releases, ensuring ongoing compatibility and feature enhancements.","status":"active","version":"1.1.9","language":"en","source_language":"en","source_url":"https://github.com/karpetrosyan/hishel","tags":["http","cache","httpx","requests","asgi","rfc9111"],"install":[{"cmd":"pip install hishel","lang":"bash","label":"Base installation"},{"cmd":"pip install hishel[httpx]","lang":"bash","label":"For HTTPX integration"},{"cmd":"pip install hishel[requests]","lang":"bash","label":"For Requests integration"},{"cmd":"pip install hishel[fastapi]","lang":"bash","label":"For FastAPI/ASGI integration"}],"dependencies":[{"reason":"Requires Python 3.10 or newer.","package":"python","optional":false},{"reason":"Required for asynchronous operations and internals.","package":"anyio","optional":false},{"reason":"Required for SQLite storage backend.","package":"anysqlite","optional":false},{"reason":"Underlying HTTP library dependency.","package":"httpcore","optional":false},{"reason":"Required for serialization.","package":"msgpack","optional":false},{"reason":"Provides backported type hints.","package":"typing_extensions","optional":false},{"reason":"Optional dependency for HTTPX client integration.","package":"httpx","optional":true},{"reason":"Optional dependency for Requests client integration.","package":"requests","optional":true},{"reason":"Optional dependency for FastAPI and ASGI middleware integration.","package":"fastapi","optional":true},{"reason":"Optional dependency for AWS S3 storage backend.","package":"boto3","optional":true},{"reason":"Optional dependency for YAML serialization.","package":"PyYAML","optional":true},{"reason":"Optional dependency for Redis storage backend.","package":"redis","optional":true}],"imports":[{"note":"Generic synchronous cache client. For HTTPX, prefer hishel.httpx.SyncCacheClient.","symbol":"CacheClient","correct":"from hishel import CacheClient"},{"note":"Generic asynchronous cache client. For HTTPX, prefer hishel.httpx.AsyncCacheClient.","symbol":"AsyncCacheClient","correct":"from hishel import AsyncCacheClient"},{"note":"Recommended synchronous cache client for HTTPX.","symbol":"SyncCacheClient","correct":"from hishel.httpx import SyncCacheClient"},{"note":"Recommended asynchronous cache client for HTTPX.","symbol":"AsyncCacheClient","correct":"from hishel.httpx import AsyncCacheClient"},{"note":"For integrating caching with an existing HTTPX Transport.","symbol":"CacheTransport","correct":"from hishel import CacheTransport"},{"note":"Synchronous SQLite storage backend.","symbol":"SyncSqliteStorage","correct":"from hishel import SyncSqliteStorage"},{"note":"Asynchronous SQLite storage backend.","symbol":"AsyncSqliteStorage","correct":"from hishel import AsyncSqliteStorage"},{"note":"Base class for creating custom cache filters, exposed since 1.1.3.","symbol":"BaseFilter","correct":"from hishel import BaseFilter"}],"quickstart":{"code":"import hishel\nimport httpx\n\ndef main():\n    # Use SyncCacheClient for synchronous HTTPX requests\n    with hishel.httpx.SyncCacheClient() as client:\n        print(\"First request (from origin):\")\n        response1 = client.get(\"https://httpbin.org/get\")\n        print(f\"Status: {response1.status_code}, From cache: {response1.extensions.get('hishel_from_cache', False)}\")\n\n        print(\"\\nSecond request (from cache if cachable):\")\n        response2 = client.get(\"https://httpbin.org/get\")\n        print(f\"Status: {response2.status_code}, From cache: {response2.extensions.get('hishel_from_cache', False)}\")\n\n    # Example with explicit SQLite storage\n    # Ensure 'my_cache.db' is created in a writable directory\n    storage = hishel.SyncSqliteStorage(database_path=\"./my_cache.db\")\n    with hishel.httpx.SyncCacheClient(storage=storage) as client:\n        print(\"\\nFirst request with SQLite storage (from origin):\")\n        response3 = client.get(\"https://httpbin.org/get?item=1\")\n        print(f\"Status: {response3.status_code}, From cache: {response3.extensions.get('hishel_from_cache', False)}\")\n\n        print(\"\\nSecond request with SQLite storage (from cache):\")\n        response4 = client.get(\"https://httpbin.org/get?item=1\")\n        print(f\"Status: {response4.status_code}, From cache: {response4.extensions.get('hishel_from_cache', False)}\")\n\nif __name__ == \"__main__\":\n    main()","lang":"python","description":"This quickstart demonstrates using Hishel's `SyncCacheClient` with HTTPX for both in-memory (default) and file-based (SQLite) caching. The first request fetches data from the origin, while subsequent requests for the same URL will be served from the cache, if applicable according to HTTP caching rules."},"warnings":[{"fix":"Upgrade to Python 3.10 or newer, or pin Hishel to `<1.1.9`.","message":"Hishel 1.1.9 officially dropped support for Python 3.9. Users on Python 3.9 or older must use an earlier version of Hishel.","severity":"breaking","affected_versions":">=1.1.9"},{"fix":"For reliable caching, use `hishel.CacheClient`, `hishel.AsyncCacheClient`, or `hishel.CacheTransport` directly with your HTTP client.","message":"The `hishel.install_cache` function is intended for experimental use only and is not recommended for production environments.","severity":"gotcha","affected_versions":"All"},{"fix":"Always iterate over the response stream (e.g., `for chunk in response.iter_bytes(): pass`) to ensure its content is saved to the cache.","message":"For stream-based responses to be properly stored in Hishel storages, you must consume (iterate through) the response stream. Simply creating an entry with a stream does not store its data.","severity":"gotcha","affected_versions":"All"},{"fix":"Refer to the `httpx` documentation for available client arguments, as they are compatible with Hishel's cache clients.","message":"Hishel's `CacheClient` and `AsyncCacheClient` classes hide the constructor signature of the underlying `httpx` client. This means IDEs might not suggest arguments that are still valid for configuration.","severity":"gotcha","affected_versions":"All"},{"fix":"Upgrade to Hishel 1.1.8 or newer to benefit from race condition fixes.","message":"Earlier versions (before 1.1.8) had potential race conditions in storage operations.","severity":"gotcha","affected_versions":"<1.1.8"},{"fix":"Always use `None` as a default for mutable arguments and initialize them inside the function if `None` is passed (e.g., `if filters is None: filters = []`).","message":"Python's mutable default arguments (e.g., lists, dicts) are evaluated only once when the function is defined. Using them as defaults for `FilterPolicy` or other configurable components can lead to unintended shared state across calls.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}