fastapi-cacher


Namefastapi-cacher JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://github.com/Fahadukr/fastapi-cacher
SummaryA caching library for FastAPI
upload_time2024-07-11 18:12:07
maintainerNone
docs_urlNone
authorFahad Mawlood
requires_python>=3.10
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FastAPI-Cacher

An intuitive caching library for FastAPI inspired by Flask-Caching.
It uses decorators for easy endpoint caching, supports both **absolute** and **sliding window expiration** mechanisms.

## Installation

Install and update using pip

```bash
pip install -U fastapi-cacher
```

## Cache Types

Configured in the CacheConfig class:

```python
# Options: "SimpleCache", "RedisCache", "MongoCache", "MemCache"
cache_type = "SimpleCache"  # Default: "SimpleCache", 
```

#### `SimpleCache`

- Suitable for development and single-thread applications.
- Default cache type if cache_type is not specified or CacheConfig is not provided.

#### `RedisCache`

- Robust option for production environments.
- Supports distributed caching.
- Configuration requires specifying either `redis_url` or both `redis_host` and `redis_password`.

#### `MongoCache`

- Uses MongoDB's `expireAfterSeconds` index to automatically manage the expiration of cached entries.
- Requires a MongoDB connection URL.

#### `MemCache`

- Uses a Memcached server to store cached data.
- Specify `memcache_host` and `memcache_port`.

### Each cache type has specific attributes in the `CacheConfig` that need to be configured:

```python
from fastapi_cacher import CacheConfig

# For SimpleCache
cache_config = CacheConfig(
  cache_type="SimpleCache",
  simple_cache_threshold=100,  # Default: 100 (number of items to store in cache, before deleting the oldest)
)

# For RedisCache
cache_config = CacheConfig(
  cache_type="RedisCache",
  redis_url="redis://localhost:6379",  # either redis_url or redis_host, redis_port, redis_password
  redis_host="your_redis_host",
  redis_port=6379,  # Default: 6379
  redis_password="your_redis_password",
  redis_db=0,  # Default: 0
)

# For MongoCache
cache_config = CacheConfig(
  cache_type="MongoCache",
  mongo_url="mongodb://user:password@localhost:27017",
  mongo_database="fastapi_cache",
  mongo_collection="your_cache_collection",  # Default: "cache"
  mongo_direct_connection=False  # Default: False
)

# For MemCache
cache_config = CacheConfig(
  cache_type="MemCache",
  memcache_host="your_memcache_host",  # Default: ""
  memcache_port=11211,  # Default: 11211
  memcache_threshold=100  # Default: 100 (number of items to store in cache, before deleting the oldest)
)
```

## Generic CacheConfig Attributes with Defaults:

- `cache_type` (str) = `SimpleCache`: Sets the caching strategy (e.g., SimpleCache, RedisCache).
- `default_timeout` (int) = `300`: Default timeout in seconds if not specified in decorator.
- `app_space` (str) = `fastapi-cacher`: Namespace prefix for cache keys to avoid conflicts.
- `coder` (Coder) = `JsonCoder`: Serialization coder for caching.
- `sliding_expiration` (bool) = `False`: Sets the caching mechanism globally, if True, the expiration time will be reset
  on every access **(overwritten by the decorator if specified there)**.
- Time Constants (`ONE_HOUR`, `ONE_DAY`, etc.): Predefined time intervals in seconds for easy setup of expiration times.

### Example:

```python
cache_config = CacheConfig(
  cache_type="SimpleCache",
  default_timeout=600,
  app_space="my_app",
  sliding_expiration=True
)
```

## Usage

To use the caching functionality, decorate your FastAPI endpoints with the @cache.cached decorator.
Here are some examples for each type of cache:

```python
from asyncio import sleep

from fastapi import FastAPI, Request, Response
from fastapi_cacher import Cache, CacheConfig

app = FastAPI()
# Configuring with RedisCache; for settings of other cache types, see the CacheConfig section above.
cache_config = CacheConfig(
    cache_type="RedisCache",
    redis_host="your_redis_host",
    redis_password="your_redis_password",
    default_timeout=600,  # default if not specified in the decorator
    app_space="fastapi-cacher",
    sliding_expiration=False
)
cache = Cache(config=cache_config)


@app.get("/item/{item_id}")
@cache.cached(timeout=300,
              sliding_expiration=False,
              namespace="item_detail",
              query_params=True,
              json_body=False,
              require_auth_header=False)
async def get_item(request: Request, response: Response, item_id: int):
    """
    request parameter is required in the function signature for the cache to work.
    request and response parameters can be named differently:
    async def get_item(req: Request, resp: Response, item_id: int):
    """
    await sleep(3)
    return {"id": item_id, "name": "Item Name"}


@app.get("/items/")
@cache.cached(timeout=cache_config.ONE_HOUR,
              namespace="item_detail")
async def get_items(request: Request, response: Response):
    """
    request parameter is required in the function signature for the cache to work.
    request and response parameters can be named differently:
    async def get_item(req: Request, resp: Response, item_id: int):
    """
    await sleep(3)
    return {"id": 1, "name": "Item Name"}
```

### `cache.cached` decorator arguments with defaults:

- `timeout` (int) = `None`: Timeout in seconds. Set to `0` to never expire. If not specified, the default timeout
  from the cache config is used. A pre-calculated values in the cache_config can be used, e.g.,
  `cache_config.ONE_HOUR`, `cache_config.ONE_DAY`, etc.
- `sliding_expiration` (bool) = `None`: If True, the expiration time will be reset on every access. If set, it
  overwrites the cache_config setting.
- `namespace` (str) = `""`: Allows scoping of cache keys.
- `query_params` (book) = `True`: Consider URL query parameters for caching.
- `json_body` = `False`: Include requests JSON body in the cache string key.
- `require_auth_header` = `False`: Include the Authorization header in the cache string key.
  If set to True, the Authorization header is required in the request and if not present - Raises `HTTPException(401)`.

## More about the sliding expiration mechanism:

The sliding expiration mechanism resets the expiration time of a cached item each time it is accessed. This means the
item will only be deleted if it is not accessed for the specified timeout period.

- Global Setting: Set in `CacheConfig` to apply by default to all endpoints.
- Individual Setting: Can be overridden in the `cache.cached` decorator for specific endpoints.

### Clearing the Cache

#### Endpoints can be configured to clear the cache selectively or entirely.

```python
@app.post('/clear-cache/')
async def clear_cache(namespace: str = None, key: str = None):
    """
    Clears the cache.
  
    - `namespace`: Optional. The namespace of the cache to clear.
    - `key`: Optional. The specific key within the namespace to clear.
  
    If no parameters are provided, the entire cache will be cleared.
    example:
    http://domain/clear-cache/?namespace=test&key=specific-key
    """
    await cache.clear(namespace=namespace, key=key)
    return "Cache cleared!"
```

### Other `cache` methods:

```python
# set 
await cache.set(key="key", value="value", timeout=300)

# get
value = await cache.get(key="key")

# get with ttl
ttl, cached_result = await cache.get_with_ttl(key="key")
```

## Contributions

Contributions to the fastapi-cacher project are welcome. Please ensure to follow best practices for code quality and add
tests for new features.

## License

This project is licensed under the MIT License.



# Changelog

## [0.3.0] - 2024-07-10:

### Added

- Support for sliding window expiration mechanism.

## [0.2.0] - 2024-07-08:

### Added

- Support for MongoDB cache: `MongoCache`.
- Support for Authorization header in `cache.cached` decorator.
- Support for JSON body in `cache.cached` decorator.
- Support for dynamic `Request` and `Response` parameters names in the function signature.

### Fixed

- Issue with json parsing of MemCache results.

### Changed

- `default_timeout` in RedisCache from 150 to 300.
- Updated README file with more examples.

## [0.1.0] - 2024-06-24 initial release

### Added

- Initial release of the package.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Fahadukr/fastapi-cacher",
    "name": "fastapi-cacher",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": null,
    "author": "Fahad Mawlood",
    "author_email": "fahadukr@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/6c/d5/e7bc348bbc85bdffda3d0022c838e910c6eef000696cad99320be920b658/fastapi-cacher-0.3.1.tar.gz",
    "platform": null,
    "description": "# FastAPI-Cacher\r\n\r\nAn intuitive caching library for FastAPI inspired by Flask-Caching.\r\nIt uses decorators for easy endpoint caching, supports both **absolute** and **sliding window expiration** mechanisms.\r\n\r\n## Installation\r\n\r\nInstall and update using pip\r\n\r\n```bash\r\npip install -U fastapi-cacher\r\n```\r\n\r\n## Cache Types\r\n\r\nConfigured in the CacheConfig class:\r\n\r\n```python\r\n# Options: \"SimpleCache\", \"RedisCache\", \"MongoCache\", \"MemCache\"\r\ncache_type = \"SimpleCache\"  # Default: \"SimpleCache\", \r\n```\r\n\r\n#### `SimpleCache`\r\n\r\n- Suitable for development and single-thread applications.\r\n- Default cache type if cache_type is not specified or CacheConfig is not provided.\r\n\r\n#### `RedisCache`\r\n\r\n- Robust option for production environments.\r\n- Supports distributed caching.\r\n- Configuration requires specifying either `redis_url` or both `redis_host` and `redis_password`.\r\n\r\n#### `MongoCache`\r\n\r\n- Uses MongoDB's `expireAfterSeconds` index to automatically manage the expiration of cached entries.\r\n- Requires a MongoDB connection URL.\r\n\r\n#### `MemCache`\r\n\r\n- Uses a Memcached server to store cached data.\r\n- Specify `memcache_host` and `memcache_port`.\r\n\r\n### Each cache type has specific attributes in the `CacheConfig` that need to be configured:\r\n\r\n```python\r\nfrom fastapi_cacher import CacheConfig\r\n\r\n# For SimpleCache\r\ncache_config = CacheConfig(\r\n  cache_type=\"SimpleCache\",\r\n  simple_cache_threshold=100,  # Default: 100 (number of items to store in cache, before deleting the oldest)\r\n)\r\n\r\n# For RedisCache\r\ncache_config = CacheConfig(\r\n  cache_type=\"RedisCache\",\r\n  redis_url=\"redis://localhost:6379\",  # either redis_url or redis_host, redis_port, redis_password\r\n  redis_host=\"your_redis_host\",\r\n  redis_port=6379,  # Default: 6379\r\n  redis_password=\"your_redis_password\",\r\n  redis_db=0,  # Default: 0\r\n)\r\n\r\n# For MongoCache\r\ncache_config = CacheConfig(\r\n  cache_type=\"MongoCache\",\r\n  mongo_url=\"mongodb://user:password@localhost:27017\",\r\n  mongo_database=\"fastapi_cache\",\r\n  mongo_collection=\"your_cache_collection\",  # Default: \"cache\"\r\n  mongo_direct_connection=False  # Default: False\r\n)\r\n\r\n# For MemCache\r\ncache_config = CacheConfig(\r\n  cache_type=\"MemCache\",\r\n  memcache_host=\"your_memcache_host\",  # Default: \"\"\r\n  memcache_port=11211,  # Default: 11211\r\n  memcache_threshold=100  # Default: 100 (number of items to store in cache, before deleting the oldest)\r\n)\r\n```\r\n\r\n## Generic CacheConfig Attributes with Defaults:\r\n\r\n- `cache_type` (str) = `SimpleCache`: Sets the caching strategy (e.g., SimpleCache, RedisCache).\r\n- `default_timeout` (int) = `300`: Default timeout in seconds if not specified in decorator.\r\n- `app_space` (str) = `fastapi-cacher`: Namespace prefix for cache keys to avoid conflicts.\r\n- `coder` (Coder) = `JsonCoder`: Serialization coder for caching.\r\n- `sliding_expiration` (bool) = `False`: Sets the caching mechanism globally, if True, the expiration time will be reset\r\n  on every access **(overwritten by the decorator if specified there)**.\r\n- Time Constants (`ONE_HOUR`, `ONE_DAY`, etc.): Predefined time intervals in seconds for easy setup of expiration times.\r\n\r\n### Example:\r\n\r\n```python\r\ncache_config = CacheConfig(\r\n  cache_type=\"SimpleCache\",\r\n  default_timeout=600,\r\n  app_space=\"my_app\",\r\n  sliding_expiration=True\r\n)\r\n```\r\n\r\n## Usage\r\n\r\nTo use the caching functionality, decorate your FastAPI endpoints with the @cache.cached decorator.\r\nHere are some examples for each type of cache:\r\n\r\n```python\r\nfrom asyncio import sleep\r\n\r\nfrom fastapi import FastAPI, Request, Response\r\nfrom fastapi_cacher import Cache, CacheConfig\r\n\r\napp = FastAPI()\r\n# Configuring with RedisCache; for settings of other cache types, see the CacheConfig section above.\r\ncache_config = CacheConfig(\r\n    cache_type=\"RedisCache\",\r\n    redis_host=\"your_redis_host\",\r\n    redis_password=\"your_redis_password\",\r\n    default_timeout=600,  # default if not specified in the decorator\r\n    app_space=\"fastapi-cacher\",\r\n    sliding_expiration=False\r\n)\r\ncache = Cache(config=cache_config)\r\n\r\n\r\n@app.get(\"/item/{item_id}\")\r\n@cache.cached(timeout=300,\r\n              sliding_expiration=False,\r\n              namespace=\"item_detail\",\r\n              query_params=True,\r\n              json_body=False,\r\n              require_auth_header=False)\r\nasync def get_item(request: Request, response: Response, item_id: int):\r\n    \"\"\"\r\n    request parameter is required in the function signature for the cache to work.\r\n    request and response parameters can be named differently:\r\n    async def get_item(req: Request, resp: Response, item_id: int):\r\n    \"\"\"\r\n    await sleep(3)\r\n    return {\"id\": item_id, \"name\": \"Item Name\"}\r\n\r\n\r\n@app.get(\"/items/\")\r\n@cache.cached(timeout=cache_config.ONE_HOUR,\r\n              namespace=\"item_detail\")\r\nasync def get_items(request: Request, response: Response):\r\n    \"\"\"\r\n    request parameter is required in the function signature for the cache to work.\r\n    request and response parameters can be named differently:\r\n    async def get_item(req: Request, resp: Response, item_id: int):\r\n    \"\"\"\r\n    await sleep(3)\r\n    return {\"id\": 1, \"name\": \"Item Name\"}\r\n```\r\n\r\n### `cache.cached` decorator arguments with defaults:\r\n\r\n- `timeout` (int) = `None`: Timeout in seconds. Set to `0` to never expire. If not specified, the default timeout\r\n  from the cache config is used. A pre-calculated values in the cache_config can be used, e.g.,\r\n  `cache_config.ONE_HOUR`, `cache_config.ONE_DAY`, etc.\r\n- `sliding_expiration` (bool) = `None`: If True, the expiration time will be reset on every access. If set, it\r\n  overwrites the cache_config setting.\r\n- `namespace` (str) = `\"\"`: Allows scoping of cache keys.\r\n- `query_params` (book) = `True`: Consider URL query parameters for caching.\r\n- `json_body` = `False`: Include requests JSON body in the cache string key.\r\n- `require_auth_header` = `False`: Include the Authorization header in the cache string key.\r\n  If set to True, the Authorization header is required in the request and if not present - Raises `HTTPException(401)`.\r\n\r\n## More about the sliding expiration mechanism:\r\n\r\nThe sliding expiration mechanism resets the expiration time of a cached item each time it is accessed. This means the\r\nitem will only be deleted if it is not accessed for the specified timeout period.\r\n\r\n- Global Setting: Set in `CacheConfig` to apply by default to all endpoints.\r\n- Individual Setting: Can be overridden in the `cache.cached` decorator for specific endpoints.\r\n\r\n### Clearing the Cache\r\n\r\n#### Endpoints can be configured to clear the cache selectively or entirely.\r\n\r\n```python\r\n@app.post('/clear-cache/')\r\nasync def clear_cache(namespace: str = None, key: str = None):\r\n    \"\"\"\r\n    Clears the cache.\r\n  \r\n    - `namespace`: Optional. The namespace of the cache to clear.\r\n    - `key`: Optional. The specific key within the namespace to clear.\r\n  \r\n    If no parameters are provided, the entire cache will be cleared.\r\n    example:\r\n    http://domain/clear-cache/?namespace=test&key=specific-key\r\n    \"\"\"\r\n    await cache.clear(namespace=namespace, key=key)\r\n    return \"Cache cleared!\"\r\n```\r\n\r\n### Other `cache` methods:\r\n\r\n```python\r\n# set \r\nawait cache.set(key=\"key\", value=\"value\", timeout=300)\r\n\r\n# get\r\nvalue = await cache.get(key=\"key\")\r\n\r\n# get with ttl\r\nttl, cached_result = await cache.get_with_ttl(key=\"key\")\r\n```\r\n\r\n## Contributions\r\n\r\nContributions to the fastapi-cacher project are welcome. Please ensure to follow best practices for code quality and add\r\ntests for new features.\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License.\r\n\r\n\r\n\r\n# Changelog\r\n\r\n## [0.3.0] - 2024-07-10:\r\n\r\n### Added\r\n\r\n- Support for sliding window expiration mechanism.\r\n\r\n## [0.2.0] - 2024-07-08:\r\n\r\n### Added\r\n\r\n- Support for MongoDB cache: `MongoCache`.\r\n- Support for Authorization header in `cache.cached` decorator.\r\n- Support for JSON body in `cache.cached` decorator.\r\n- Support for dynamic `Request` and `Response` parameters names in the function signature.\r\n\r\n### Fixed\r\n\r\n- Issue with json parsing of MemCache results.\r\n\r\n### Changed\r\n\r\n- `default_timeout` in RedisCache from 150 to 300.\r\n- Updated README file with more examples.\r\n\r\n## [0.1.0] - 2024-06-24 initial release\r\n\r\n### Added\r\n\r\n- Initial release of the package.\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A caching library for FastAPI",
    "version": "0.3.1",
    "project_urls": {
        "Homepage": "https://github.com/Fahadukr/fastapi-cacher"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e71af82c1c401563bacf297ab94b185d26688717177656e206d1abdc63642162",
                "md5": "6121c19381c93c89ab1ac6a03db3e4c2",
                "sha256": "506dbf88a89fad2007d40cbdb199c143fcecaa6821b1391a2bf56a0fdeb65ed2"
            },
            "downloads": -1,
            "filename": "fastapi_cacher-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6121c19381c93c89ab1ac6a03db3e4c2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 26734,
            "upload_time": "2024-07-11T18:12:03",
            "upload_time_iso_8601": "2024-07-11T18:12:03.330271Z",
            "url": "https://files.pythonhosted.org/packages/e7/1a/f82c1c401563bacf297ab94b185d26688717177656e206d1abdc63642162/fastapi_cacher-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6cd5e7bc348bbc85bdffda3d0022c838e910c6eef000696cad99320be920b658",
                "md5": "f78e40ac1516ce454e4f5b68df406258",
                "sha256": "a55744329c4589d247e1e850c448efdd07a6eaf5d455b0c49af9d56424e00e6c"
            },
            "downloads": -1,
            "filename": "fastapi-cacher-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f78e40ac1516ce454e4f5b68df406258",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 15488,
            "upload_time": "2024-07-11T18:12:07",
            "upload_time_iso_8601": "2024-07-11T18:12:07.105237Z",
            "url": "https://files.pythonhosted.org/packages/6c/d5/e7bc348bbc85bdffda3d0022c838e910c6eef000696cad99320be920b658/fastapi-cacher-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-11 18:12:07",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Fahadukr",
    "github_project": "fastapi-cacher",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "fastapi-cacher"
}
        
Elapsed time: 0.36942s